Whamcloud - gitweb
9ae38c517e8d045f35958db94f8c884348731613
[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
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" ] || [ -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 ] || [ $num_uniq -ne $nrfiles ] ||
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_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_25a() {
1444         echo '== symlink sanity ============================================='
1445
1446         test_mkdir $DIR/d25
1447         ln -s d25 $DIR/s25
1448         touch $DIR/s25/foo ||
1449                 error "File creation in symlinked directory failed"
1450 }
1451 run_test 25a "create file in symlinked directory ==============="
1452
1453 test_25b() {
1454         [ ! -d $DIR/d25 ] && test_25a
1455         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1456 }
1457 run_test 25b "lookup file in symlinked directory ==============="
1458
1459 test_26a() {
1460         test_mkdir $DIR/d26
1461         test_mkdir $DIR/d26/d26-2
1462         ln -s d26/d26-2 $DIR/s26
1463         touch $DIR/s26/foo || error "File creation failed"
1464 }
1465 run_test 26a "multiple component symlink ======================="
1466
1467 test_26b() {
1468         test_mkdir -p $DIR/$tdir/d26-2
1469         ln -s $tdir/d26-2/foo $DIR/s26-2
1470         touch $DIR/s26-2 || error "File creation failed"
1471 }
1472 run_test 26b "multiple component symlink at end of lookup ======"
1473
1474 test_26c() {
1475         test_mkdir $DIR/d26.2
1476         touch $DIR/d26.2/foo
1477         ln -s d26.2 $DIR/s26.2-1
1478         ln -s s26.2-1 $DIR/s26.2-2
1479         ln -s s26.2-2 $DIR/s26.2-3
1480         chmod 0666 $DIR/s26.2-3/foo
1481 }
1482 run_test 26c "chain of symlinks"
1483
1484 # recursive symlinks (bug 439)
1485 test_26d() {
1486         ln -s d26-3/foo $DIR/d26-3
1487 }
1488 run_test 26d "create multiple component recursive symlink"
1489
1490 test_26e() {
1491         [ ! -h $DIR/d26-3 ] && test_26d
1492         rm $DIR/d26-3
1493 }
1494 run_test 26e "unlink multiple component recursive symlink"
1495
1496 # recursive symlinks (bug 7022)
1497 test_26f() {
1498         test_mkdir $DIR/$tdir
1499         test_mkdir $DIR/$tdir/$tfile
1500         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1501         test_mkdir -p lndir/bar1
1502         test_mkdir $DIR/$tdir/$tfile/$tfile
1503         cd $tfile                || error "cd $tfile failed"
1504         ln -s .. dotdot          || error "ln dotdot failed"
1505         ln -s dotdot/lndir lndir || error "ln lndir failed"
1506         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1507         output=`ls $tfile/$tfile/lndir/bar1`
1508         [ "$output" = bar1 ] && error "unexpected output"
1509         rm -r $tfile             || error "rm $tfile failed"
1510         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1511 }
1512 run_test 26f "rm -r of a directory which has recursive symlink"
1513
1514 test_27a() {
1515         test_mkdir $DIR/$tdir
1516         $LFS getstripe $DIR/$tdir
1517         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1518         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1519         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1520 }
1521 run_test 27a "one stripe file"
1522
1523 test_27b() {
1524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1525
1526         test_mkdir $DIR/$tdir
1527         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $LFS getstripe -c $DIR/$tdir/$tfile
1529         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1530                 error "two-stripe file doesn't have two stripes"
1531
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533 }
1534 run_test 27b "create and write to two stripe file"
1535
1536 test_27d() {
1537         test_mkdir $DIR/$tdir
1538         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1539                 error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1542 }
1543 run_test 27d "create file with default settings"
1544
1545 test_27e() {
1546         # LU-5839 adds check for existed layout before setting it
1547         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1548                 skip "Need MDS version at least 2.7.56"
1549
1550         test_mkdir $DIR/$tdir
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1552         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1553         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1554 }
1555 run_test 27e "setstripe existing file (should return error)"
1556
1557 test_27f() {
1558         test_mkdir $DIR/$tdir
1559         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1560                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1561         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1562                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1564         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1565 }
1566 run_test 27f "setstripe with bad stripe size (should return error)"
1567
1568 test_27g() {
1569         test_mkdir $DIR/$tdir
1570         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1571         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1572                 error "$DIR/$tdir/$tfile has object"
1573 }
1574 run_test 27g "$LFS getstripe with no objects"
1575
1576 test_27i() {
1577         test_mkdir $DIR/$tdir
1578         touch $DIR/$tdir/$tfile || error "touch failed"
1579         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1580                 error "missing objects"
1581 }
1582 run_test 27i "$LFS getstripe with some objects"
1583
1584 test_27j() {
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1587                 error "setstripe failed" || true
1588 }
1589 run_test 27j "setstripe with bad stripe offset (should return error)"
1590
1591 test_27k() { # bug 2844
1592         test_mkdir $DIR/$tdir
1593         local file=$DIR/$tdir/$tfile
1594         local ll_max_blksize=$((4 * 1024 * 1024))
1595         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1596         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1597         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1598         dd if=/dev/zero of=$file bs=4k count=1
1599         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1600         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1601 }
1602 run_test 27k "limit i_blksize for broken user apps"
1603
1604 test_27l() {
1605         mcreate $DIR/$tfile || error "creating file"
1606         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1607                 error "setstripe should have failed" || true
1608 }
1609 run_test 27l "check setstripe permissions (should return error)"
1610
1611 test_27m() {
1612         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1613
1614         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1615                    head -n1)
1616         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1617                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1618         fi
1619         trap simple_cleanup_common EXIT
1620         test_mkdir $DIR/$tdir
1621         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1623                 error "dd should fill OST0"
1624         i=2
1625         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1626                 i=$((i + 1))
1627                 [ $i -gt 256 ] && break
1628         done
1629         i=$((i + 1))
1630         touch $DIR/$tdir/$tfile.$i
1631         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1632             awk '{print $1}'| grep -w "0") ] &&
1633                 error "OST0 was full but new created file still use it"
1634         i=$((i + 1))
1635         touch $DIR/$tdir/$tfile.$i
1636         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1637             awk '{print $1}'| grep -w "0") ] &&
1638                 error "OST0 was full but new created file still use it"
1639         simple_cleanup_common
1640 }
1641 run_test 27m "create file while OST0 was full"
1642
1643 sleep_maxage() {
1644         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1645                       awk '{ print $1 * 2; exit; }')
1646         sleep $delay
1647 }
1648
1649 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1650 # if the OST isn't full anymore.
1651 reset_enospc() {
1652         local OSTIDX=${1:-""}
1653
1654         local list=$(comma_list $(osts_nodes))
1655         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1656
1657         do_nodes $list lctl set_param fail_loc=0
1658         sync    # initiate all OST_DESTROYs from MDS to OST
1659         sleep_maxage
1660 }
1661
1662 exhaust_precreations() {
1663         local OSTIDX=$1
1664         local FAILLOC=$2
1665         local FAILIDX=${3:-$OSTIDX}
1666         local ofacet=ost$((OSTIDX + 1))
1667
1668         test_mkdir -p -c1 $DIR/$tdir
1669         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1670         local mfacet=mds$((mdtidx + 1))
1671         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1672
1673         local OST=$(ostname_from_index $OSTIDX)
1674
1675         # on the mdt's osc
1676         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1677         local last_id=$(do_facet $mfacet lctl get_param -n \
1678                         osc.$mdtosc_proc1.prealloc_last_id)
1679         local next_id=$(do_facet $mfacet lctl get_param -n \
1680                         osc.$mdtosc_proc1.prealloc_next_id)
1681
1682         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1683         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1684
1685         test_mkdir -p $DIR/$tdir/${OST}
1686         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1687 #define OBD_FAIL_OST_ENOSPC              0x215
1688         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1689         echo "Creating to objid $last_id on ost $OST..."
1690         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1691         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1692         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1693         sleep_maxage
1694 }
1695
1696 exhaust_all_precreations() {
1697         local i
1698         for (( i=0; i < OSTCOUNT; i++ )) ; do
1699                 exhaust_precreations $i $1 -1
1700         done
1701 }
1702
1703 test_27n() {
1704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1706         remote_mds_nodsh && skip "remote MDS with nodsh"
1707         remote_ost_nodsh && skip "remote OST with nodsh"
1708
1709         reset_enospc
1710         rm -f $DIR/$tdir/$tfile
1711         exhaust_precreations 0 0x80000215
1712         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1713         touch $DIR/$tdir/$tfile || error "touch failed"
1714         $LFS getstripe $DIR/$tdir/$tfile
1715         reset_enospc
1716 }
1717 run_test 27n "create file with some full OSTs"
1718
1719 test_27o() {
1720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1722         remote_mds_nodsh && skip "remote MDS with nodsh"
1723         remote_ost_nodsh && skip "remote OST with nodsh"
1724
1725         reset_enospc
1726         rm -f $DIR/$tdir/$tfile
1727         exhaust_all_precreations 0x215
1728
1729         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1730
1731         reset_enospc
1732         rm -rf $DIR/$tdir/*
1733 }
1734 run_test 27o "create file with all full OSTs (should error)"
1735
1736 test_27p() {
1737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1739         remote_mds_nodsh && skip "remote MDS with nodsh"
1740         remote_ost_nodsh && skip "remote OST with nodsh"
1741
1742         reset_enospc
1743         rm -f $DIR/$tdir/$tfile
1744         test_mkdir $DIR/$tdir
1745
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1748         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1749
1750         exhaust_precreations 0 0x80000215
1751         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1752         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1753         $LFS getstripe $DIR/$tdir/$tfile
1754
1755         reset_enospc
1756 }
1757 run_test 27p "append to a truncated file with some full OSTs"
1758
1759 test_27q() {
1760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1762         remote_mds_nodsh && skip "remote MDS with nodsh"
1763         remote_ost_nodsh && skip "remote OST with nodsh"
1764
1765         reset_enospc
1766         rm -f $DIR/$tdir/$tfile
1767
1768         test_mkdir $DIR/$tdir
1769         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1770         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1771                 error "truncate $DIR/$tdir/$tfile failed"
1772         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1773
1774         exhaust_all_precreations 0x215
1775
1776         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1777         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1778
1779         reset_enospc
1780 }
1781 run_test 27q "append to truncated file with all OSTs full (should error)"
1782
1783 test_27r() {
1784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1786         remote_mds_nodsh && skip "remote MDS with nodsh"
1787         remote_ost_nodsh && skip "remote OST with nodsh"
1788
1789         reset_enospc
1790         rm -f $DIR/$tdir/$tfile
1791         exhaust_precreations 0 0x80000215
1792
1793         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1794
1795         reset_enospc
1796 }
1797 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1798
1799 test_27s() { # bug 10725
1800         test_mkdir $DIR/$tdir
1801         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1802         local stripe_count=0
1803         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1804         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1805                 error "stripe width >= 2^32 succeeded" || true
1806
1807 }
1808 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1809
1810 test_27t() { # bug 10864
1811         WDIR=$(pwd)
1812         WLFS=$(which lfs)
1813         cd $DIR
1814         touch $tfile
1815         $WLFS getstripe $tfile
1816         cd $WDIR
1817 }
1818 run_test 27t "check that utils parse path correctly"
1819
1820 test_27u() { # bug 4900
1821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1822         remote_mds_nodsh && skip "remote MDS with nodsh"
1823
1824         local index
1825         local list=$(comma_list $(mdts_nodes))
1826
1827 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1828         do_nodes $list $LCTL set_param fail_loc=0x139
1829         test_mkdir -p $DIR/$tdir
1830         trap simple_cleanup_common EXIT
1831         createmany -o $DIR/$tdir/t- 1000
1832         do_nodes $list $LCTL set_param fail_loc=0
1833
1834         TLOG=$TMP/$tfile.getstripe
1835         $LFS getstripe $DIR/$tdir > $TLOG
1836         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1837         unlinkmany $DIR/$tdir/t- 1000
1838         trap 0
1839         [[ $OBJS -gt 0 ]] &&
1840                 error "$OBJS objects created on OST-0. See $TLOG" ||
1841                 rm -f $TLOG
1842 }
1843 run_test 27u "skip object creation on OSC w/o objects"
1844
1845 test_27v() { # bug 4900
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         exhaust_all_precreations 0x215
1852         reset_enospc
1853
1854         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1855
1856         touch $DIR/$tdir/$tfile
1857         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1858         # all except ost1
1859         for (( i=1; i < OSTCOUNT; i++ )); do
1860                 do_facet ost$i lctl set_param fail_loc=0x705
1861         done
1862         local START=`date +%s`
1863         createmany -o $DIR/$tdir/$tfile 32
1864
1865         local FINISH=`date +%s`
1866         local TIMEOUT=`lctl get_param -n timeout`
1867         local PROCESS=$((FINISH - START))
1868         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1869                error "$FINISH - $START >= $TIMEOUT / 2"
1870         sleep $((TIMEOUT / 2 - PROCESS))
1871         reset_enospc
1872 }
1873 run_test 27v "skip object creation on slow OST"
1874
1875 test_27w() { # bug 10997
1876         test_mkdir $DIR/$tdir
1877         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1878         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1879                 error "stripe size $size != 65536" || true
1880         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1881                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1882 }
1883 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1884
1885 test_27wa() {
1886         [[ $OSTCOUNT -lt 2 ]] &&
1887                 skip_env "skipping multiple stripe count/offset test"
1888
1889         test_mkdir $DIR/$tdir
1890         for i in $(seq 1 $OSTCOUNT); do
1891                 offset=$((i - 1))
1892                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1893                         error "setstripe -c $i -i $offset failed"
1894                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1895                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1896                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1897                 [ $index -ne $offset ] &&
1898                         error "stripe offset $index != $offset" || true
1899         done
1900 }
1901 run_test 27wa "check $LFS setstripe -c -i options"
1902
1903 test_27x() {
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907
1908         OFFSET=$(($OSTCOUNT - 1))
1909         OSTIDX=0
1910         local OST=$(ostname_from_index $OSTIDX)
1911
1912         test_mkdir $DIR/$tdir
1913         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1914         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1915         sleep_maxage
1916         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1917         for i in $(seq 0 $OFFSET); do
1918                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1919                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1920                 error "OST0 was degraded but new created file still use it"
1921         done
1922         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1923 }
1924 run_test 27x "create files while OST0 is degraded"
1925
1926 test_27y() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931
1932         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1933         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1934                 osc.$mdtosc.prealloc_last_id)
1935         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1936                 osc.$mdtosc.prealloc_next_id)
1937         local fcount=$((last_id - next_id))
1938         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1939         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1940
1941         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1942                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1943         local OST_DEACTIVE_IDX=-1
1944         local OSC
1945         local OSTIDX
1946         local OST
1947
1948         for OSC in $MDS_OSCS; do
1949                 OST=$(osc_to_ost $OSC)
1950                 OSTIDX=$(index_from_ostuuid $OST)
1951                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1952                         OST_DEACTIVE_IDX=$OSTIDX
1953                 fi
1954                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1955                         echo $OSC "is Deactivated:"
1956                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1957                 fi
1958         done
1959
1960         OSTIDX=$(index_from_ostuuid $OST)
1961         test_mkdir $DIR/$tdir
1962         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1963
1964         for OSC in $MDS_OSCS; do
1965                 OST=$(osc_to_ost $OSC)
1966                 OSTIDX=$(index_from_ostuuid $OST)
1967                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1968                         echo $OST "is degraded:"
1969                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1970                                                 obdfilter.$OST.degraded=1
1971                 fi
1972         done
1973
1974         sleep_maxage
1975         createmany -o $DIR/$tdir/$tfile $fcount
1976
1977         for OSC in $MDS_OSCS; do
1978                 OST=$(osc_to_ost $OSC)
1979                 OSTIDX=$(index_from_ostuuid $OST)
1980                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1981                         echo $OST "is recovered from degraded:"
1982                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1983                                                 obdfilter.$OST.degraded=0
1984                 else
1985                         do_facet $SINGLEMDS lctl --device %$OSC activate
1986                 fi
1987         done
1988
1989         # all osp devices get activated, hence -1 stripe count restored
1990         local stripe_count=0
1991
1992         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1993         # devices get activated.
1994         sleep_maxage
1995         $LFS setstripe -c -1 $DIR/$tfile
1996         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1997         rm -f $DIR/$tfile
1998         [ $stripe_count -ne $OSTCOUNT ] &&
1999                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2000         return 0
2001 }
2002 run_test 27y "create files while OST0 is degraded and the rest inactive"
2003
2004 check_seq_oid()
2005 {
2006         log "check file $1"
2007
2008         lmm_count=$($LFS getstripe -c $1)
2009         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2010         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2011
2012         local old_ifs="$IFS"
2013         IFS=$'[:]'
2014         fid=($($LFS path2fid $1))
2015         IFS="$old_ifs"
2016
2017         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2018         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2019
2020         # compare lmm_seq and lu_fid->f_seq
2021         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2022         # compare lmm_object_id and lu_fid->oid
2023         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2024
2025         # check the trusted.fid attribute of the OST objects of the file
2026         local have_obdidx=false
2027         local stripe_nr=0
2028         $LFS getstripe $1 | while read obdidx oid hex seq; do
2029                 # skip lines up to and including "obdidx"
2030                 [ -z "$obdidx" ] && break
2031                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2032                 $have_obdidx || continue
2033
2034                 local ost=$((obdidx + 1))
2035                 local dev=$(ostdevname $ost)
2036                 local oid_hex
2037
2038                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2039
2040                 seq=$(echo $seq | sed -e "s/^0x//g")
2041                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2042                         oid_hex=$(echo $oid)
2043                 else
2044                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2045                 fi
2046                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2047
2048                 local ff=""
2049                 #
2050                 # Don't unmount/remount the OSTs if we don't need to do that.
2051                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2052                 # update too, until that use mount/ll_decode_filter_fid/mount.
2053                 # Re-enable when debugfs will understand new filter_fid.
2054                 #
2055                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2056                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2057                                 $dev 2>/dev/null" | grep "parent=")
2058                 fi
2059                 if [ -z "$ff" ]; then
2060                         stop ost$ost
2061                         mount_fstype ost$ost
2062                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2063                                 $(facet_mntpt ost$ost)/$obj_file)
2064                         unmount_fstype ost$ost
2065                         start ost$ost $dev $OST_MOUNT_OPTS
2066                         clients_up
2067                 fi
2068
2069                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2070
2071                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2072
2073                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2074                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2075                 #
2076                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2077                 #       stripe_size=1048576 component_id=1 component_start=0 \
2078                 #       component_end=33554432
2079                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2080                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2081                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2082                 local ff_pstripe
2083                 if grep -q 'stripe=' <<<$ff; then
2084                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2085                 else
2086                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2087                         # into f_ver in this case.  See comment on ff_parent.
2088                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2089                 fi
2090
2091                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2092                 [ $ff_pseq = $lmm_seq ] ||
2093                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2094                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2095                 [ $ff_poid = $lmm_oid ] ||
2096                         error "FF parent OID $ff_poid != $lmm_oid"
2097                 (($ff_pstripe == $stripe_nr)) ||
2098                         error "FF stripe $ff_pstripe != $stripe_nr"
2099
2100                 stripe_nr=$((stripe_nr + 1))
2101                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2102                         continue
2103                 if grep -q 'stripe_count=' <<<$ff; then
2104                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2105                                             -e 's/ .*//' <<<$ff)
2106                         [ $lmm_count = $ff_scnt ] ||
2107                                 error "FF stripe count $lmm_count != $ff_scnt"
2108                 fi
2109         done
2110 }
2111
2112 test_27z() {
2113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2114         remote_ost_nodsh && skip "remote OST with nodsh"
2115
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2118                 { error "setstripe -c -1 failed"; return 1; }
2119         # We need to send a write to every object to get parent FID info set.
2120         # This _should_ also work for setattr, but does not currently.
2121         # touch $DIR/$tdir/$tfile-1 ||
2122         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2123                 { error "dd $tfile-1 failed"; return 2; }
2124         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2125                 { error "setstripe -c -1 failed"; return 3; }
2126         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2127                 { error "dd $tfile-2 failed"; return 4; }
2128
2129         # make sure write RPCs have been sent to OSTs
2130         sync; sleep 5; sync
2131
2132         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2133         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2134 }
2135 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2136
2137 test_27A() { # b=19102
2138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2139
2140         save_layout_restore_at_exit $MOUNT
2141         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2142         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2143                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2144         local default_size=$($LFS getstripe -S $MOUNT)
2145         local default_offset=$($LFS getstripe -i $MOUNT)
2146         local dsize=$(do_facet $SINGLEMDS \
2147                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2148         [ $default_size -eq $dsize ] ||
2149                 error "stripe size $default_size != $dsize"
2150         [ $default_offset -eq -1 ] ||
2151                 error "stripe offset $default_offset != -1"
2152 }
2153 run_test 27A "check filesystem-wide default LOV EA values"
2154
2155 test_27B() { # LU-2523
2156         test_mkdir $DIR/$tdir
2157         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2158         touch $DIR/$tdir/f0
2159         # open f1 with O_LOV_DELAY_CREATE
2160         # rename f0 onto f1
2161         # call setstripe ioctl on open file descriptor for f1
2162         # close
2163         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2164                 $DIR/$tdir/f0
2165
2166         rm -f $DIR/$tdir/f1
2167         # open f1 with O_LOV_DELAY_CREATE
2168         # unlink f1
2169         # call setstripe ioctl on open file descriptor for f1
2170         # close
2171         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2172
2173         # Allow multiop to fail in imitation of NFS's busted semantics.
2174         true
2175 }
2176 run_test 27B "call setstripe on open unlinked file/rename victim"
2177
2178 test_27C() { #LU-2871
2179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2180
2181         declare -a ost_idx
2182         local index
2183         local found
2184         local i
2185         local j
2186
2187         test_mkdir $DIR/$tdir
2188         cd $DIR/$tdir
2189         for i in $(seq 0 $((OSTCOUNT - 1))); do
2190                 # set stripe across all OSTs starting from OST$i
2191                 $LFS setstripe -i $i -c -1 $tfile$i
2192                 # get striping information
2193                 ost_idx=($($LFS getstripe $tfile$i |
2194                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2195                 echo ${ost_idx[@]}
2196
2197                 # check the layout
2198                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2199                         error "${#ost_idx[@]} != $OSTCOUNT"
2200
2201                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2202                         found=0
2203                         for j in $(echo ${ost_idx[@]}); do
2204                                 if [ $index -eq $j ]; then
2205                                         found=1
2206                                         break
2207                                 fi
2208                         done
2209                         [ $found = 1 ] ||
2210                                 error "Can not find $index in ${ost_idx[@]}"
2211                 done
2212         done
2213 }
2214 run_test 27C "check full striping across all OSTs"
2215
2216 test_27D() {
2217         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2218         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2219         remote_mds_nodsh && skip "remote MDS with nodsh"
2220
2221         local POOL=${POOL:-testpool}
2222         local first_ost=0
2223         local last_ost=$(($OSTCOUNT - 1))
2224         local ost_step=1
2225         local ost_list=$(seq $first_ost $ost_step $last_ost)
2226         local ost_range="$first_ost $last_ost $ost_step"
2227
2228         if ! combined_mgs_mds ; then
2229                 mount_mgs_client
2230         fi
2231
2232         test_mkdir $DIR/$tdir
2233         pool_add $POOL || error "pool_add failed"
2234         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2235
2236         local skip27D
2237         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2238                 skip27D+="-s 29"
2239         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2240                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2241                         skip27D+=" -s 30,31"
2242         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2243                 error "llapi_layout_test failed"
2244
2245         destroy_test_pools || error "destroy test pools failed"
2246
2247         if ! combined_mgs_mds ; then
2248                 umount_mgs_client
2249         fi
2250 }
2251 run_test 27D "validate llapi_layout API"
2252
2253 # Verify that default_easize is increased from its initial value after
2254 # accessing a widely striped file.
2255 test_27E() {
2256         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2257         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2258                 skip "client does not have LU-3338 fix"
2259
2260         # 72 bytes is the minimum space required to store striping
2261         # information for a file striped across one OST:
2262         # (sizeof(struct lov_user_md_v3) +
2263         #  sizeof(struct lov_user_ost_data_v1))
2264         local min_easize=72
2265         $LCTL set_param -n llite.*.default_easize $min_easize ||
2266                 error "lctl set_param failed"
2267         local easize=$($LCTL get_param -n llite.*.default_easize)
2268
2269         [ $easize -eq $min_easize ] ||
2270                 error "failed to set default_easize"
2271
2272         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2273                 error "setstripe failed"
2274         cat $DIR/$tfile
2275         rm $DIR/$tfile
2276
2277         easize=$($LCTL get_param -n llite.*.default_easize)
2278
2279         [ $easize -gt $min_easize ] ||
2280                 error "default_easize not updated"
2281 }
2282 run_test 27E "check that default extended attribute size properly increases"
2283
2284 test_27F() { # LU-5346/LU-7975
2285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2286         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2287         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2288                 skip "Need MDS version at least 2.8.51"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         rm -f $DIR/$tdir/f0
2293         $LFS setstripe -c 2 $DIR/$tdir
2294
2295         # stop all OSTs to reproduce situation for LU-7975 ticket
2296         for num in $(seq $OSTCOUNT); do
2297                 stop ost$num
2298         done
2299
2300         # open/create f0 with O_LOV_DELAY_CREATE
2301         # truncate f0 to a non-0 size
2302         # close
2303         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2304
2305         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2306         # open/write it again to force delayed layout creation
2307         cat /etc/hosts > $DIR/$tdir/f0 &
2308         catpid=$!
2309
2310         # restart OSTs
2311         for num in $(seq $OSTCOUNT); do
2312                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2313                         error "ost$num failed to start"
2314         done
2315
2316         wait $catpid || error "cat failed"
2317
2318         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2319         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2320                 error "wrong stripecount"
2321
2322 }
2323 run_test 27F "Client resend delayed layout creation with non-zero size"
2324
2325 test_27G() { #LU-10629
2326         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2327                 skip "Need MDS version at least 2.11.51"
2328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2329         remote_mds_nodsh && skip "remote MDS with nodsh"
2330         local POOL=${POOL:-testpool}
2331         local ostrange="0 0 1"
2332
2333         test_mkdir $DIR/$tdir
2334         pool_add $POOL || error "pool_add failed"
2335         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2336         $LFS setstripe -p $POOL $DIR/$tdir
2337
2338         local pool=$($LFS getstripe -p $DIR/$tdir)
2339
2340         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2341
2342         $LFS setstripe -d $DIR/$tdir
2343
2344         pool=$($LFS getstripe -p $DIR/$tdir)
2345
2346         rmdir $DIR/$tdir
2347
2348         [ -z "$pool" ] || error "'$pool' is not empty"
2349 }
2350 run_test 27G "Clear OST pool from stripe"
2351
2352 test_27H() {
2353         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2354                 skip "Need MDS version newer than 2.11.54"
2355         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2358         touch $DIR/$tdir/$tfile
2359         $LFS getstripe -c $DIR/$tdir/$tfile
2360         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2361                 error "two-stripe file doesn't have two stripes"
2362
2363         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2364         $LFS getstripe -y $DIR/$tdir/$tfile
2365         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2366              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2367                 error "expected l_ost_idx: [02]$ not matched"
2368
2369         # make sure ost list has been cleared
2370         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2371         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2372                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2373         touch $DIR/$tdir/f3
2374         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2375 }
2376 run_test 27H "Set specific OSTs stripe"
2377
2378 test_27I() {
2379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2381         local pool=$TESTNAME
2382         local ostrange="1 1 1"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 2 -i 0 $MOUNT
2386         pool_add $pool || error "pool_add failed"
2387         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2388         test_mkdir $DIR/$tdir
2389         $LFS setstripe -p $pool $DIR/$tdir
2390         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2391         $LFS getstripe $DIR/$tdir/$tfile
2392 }
2393 run_test 27I "check that root dir striping does not break parent dir one"
2394
2395 # createtest also checks that device nodes are created and
2396 # then visible correctly (#2091)
2397 test_28() { # bug 2091
2398         test_mkdir $DIR/d28
2399         $CREATETEST $DIR/d28/ct || error "createtest failed"
2400 }
2401 run_test 28 "create/mknod/mkdir with bad file types ============"
2402
2403 test_29() {
2404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2405
2406         sync; sleep 1; sync # flush out any dirty pages from previous tests
2407         cancel_lru_locks
2408         test_mkdir $DIR/d29
2409         touch $DIR/d29/foo
2410         log 'first d29'
2411         ls -l $DIR/d29
2412
2413         declare -i LOCKCOUNTORIG=0
2414         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2415                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2416         done
2417         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2418
2419         declare -i LOCKUNUSEDCOUNTORIG=0
2420         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2421                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2422         done
2423
2424         log 'second d29'
2425         ls -l $DIR/d29
2426         log 'done'
2427
2428         declare -i LOCKCOUNTCURRENT=0
2429         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2430                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2431         done
2432
2433         declare -i LOCKUNUSEDCOUNTCURRENT=0
2434         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2435                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2436         done
2437
2438         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2439                 $LCTL set_param -n ldlm.dump_namespaces ""
2440                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2441                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2442                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2443                 return 2
2444         fi
2445         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2446                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2447                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2448                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2449                 return 3
2450         fi
2451 }
2452 run_test 29 "IT_GETATTR regression  ============================"
2453
2454 test_30a() { # was test_30
2455         cp $(which ls) $DIR || cp /bin/ls $DIR
2456         $DIR/ls / || error "Can't execute binary from lustre"
2457         rm $DIR/ls
2458 }
2459 run_test 30a "execute binary from Lustre (execve) =============="
2460
2461 test_30b() {
2462         cp `which ls` $DIR || cp /bin/ls $DIR
2463         chmod go+rx $DIR/ls
2464         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2465         rm $DIR/ls
2466 }
2467 run_test 30b "execute binary from Lustre as non-root ==========="
2468
2469 test_30c() { # b=22376
2470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2471
2472         cp `which ls` $DIR || cp /bin/ls $DIR
2473         chmod a-rw $DIR/ls
2474         cancel_lru_locks mdc
2475         cancel_lru_locks osc
2476         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2477         rm -f $DIR/ls
2478 }
2479 run_test 30c "execute binary from Lustre without read perms ===="
2480
2481 test_31a() {
2482         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2483         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2484 }
2485 run_test 31a "open-unlink file =================================="
2486
2487 test_31b() {
2488         touch $DIR/f31 || error "touch $DIR/f31 failed"
2489         ln $DIR/f31 $DIR/f31b || error "ln failed"
2490         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2491         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2492 }
2493 run_test 31b "unlink file with multiple links while open ======="
2494
2495 test_31c() {
2496         touch $DIR/f31 || error "touch $DIR/f31 failed"
2497         ln $DIR/f31 $DIR/f31c || error "ln failed"
2498         multiop_bg_pause $DIR/f31 O_uc ||
2499                 error "multiop_bg_pause for $DIR/f31 failed"
2500         MULTIPID=$!
2501         $MULTIOP $DIR/f31c Ouc
2502         kill -USR1 $MULTIPID
2503         wait $MULTIPID
2504 }
2505 run_test 31c "open-unlink file with multiple links ============="
2506
2507 test_31d() {
2508         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2509         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2510 }
2511 run_test 31d "remove of open directory ========================="
2512
2513 test_31e() { # bug 2904
2514         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2515 }
2516 run_test 31e "remove of open non-empty directory ==============="
2517
2518 test_31f() { # bug 4554
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520
2521         set -vx
2522         test_mkdir $DIR/d31f
2523         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2524         cp /etc/hosts $DIR/d31f
2525         ls -l $DIR/d31f
2526         $LFS getstripe $DIR/d31f/hosts
2527         multiop_bg_pause $DIR/d31f D_c || return 1
2528         MULTIPID=$!
2529
2530         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2531         test_mkdir $DIR/d31f
2532         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2533         cp /etc/hosts $DIR/d31f
2534         ls -l $DIR/d31f
2535         $LFS getstripe $DIR/d31f/hosts
2536         multiop_bg_pause $DIR/d31f D_c || return 1
2537         MULTIPID2=$!
2538
2539         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2540         wait $MULTIPID || error "first opendir $MULTIPID failed"
2541
2542         sleep 6
2543
2544         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2545         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2546         set +vx
2547 }
2548 run_test 31f "remove of open directory with open-unlink file ==="
2549
2550 test_31g() {
2551         echo "-- cross directory link --"
2552         test_mkdir -c1 $DIR/${tdir}ga
2553         test_mkdir -c1 $DIR/${tdir}gb
2554         touch $DIR/${tdir}ga/f
2555         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2556         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2557         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2558         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2559         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2560 }
2561 run_test 31g "cross directory link==============="
2562
2563 test_31h() {
2564         echo "-- cross directory link --"
2565         test_mkdir -c1 $DIR/${tdir}
2566         test_mkdir -c1 $DIR/${tdir}/dir
2567         touch $DIR/${tdir}/f
2568         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2569         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2570         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2571         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2572         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2573 }
2574 run_test 31h "cross directory link under child==============="
2575
2576 test_31i() {
2577         echo "-- cross directory link --"
2578         test_mkdir -c1 $DIR/$tdir
2579         test_mkdir -c1 $DIR/$tdir/dir
2580         touch $DIR/$tdir/dir/f
2581         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2582         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2583         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2584         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2585         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2586 }
2587 run_test 31i "cross directory link under parent==============="
2588
2589 test_31j() {
2590         test_mkdir -c1 -p $DIR/$tdir
2591         test_mkdir -c1 -p $DIR/$tdir/dir1
2592         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2593         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2594         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2595         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2596         return 0
2597 }
2598 run_test 31j "link for directory==============="
2599
2600 test_31k() {
2601         test_mkdir -c1 -p $DIR/$tdir
2602         touch $DIR/$tdir/s
2603         touch $DIR/$tdir/exist
2604         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2605         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2606         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2607         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2608         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2609         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2610         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2611         return 0
2612 }
2613 run_test 31k "link to file: the same, non-existing, dir==============="
2614
2615 test_31m() {
2616         mkdir $DIR/d31m
2617         touch $DIR/d31m/s
2618         mkdir $DIR/d31m2
2619         touch $DIR/d31m2/exist
2620         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2621         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2622         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2623         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2624         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2625         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2626         return 0
2627 }
2628 run_test 31m "link to file: the same, non-existing, dir==============="
2629
2630 test_31n() {
2631         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2632         nlink=$(stat --format=%h $DIR/$tfile)
2633         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2634         local fd=$(free_fd)
2635         local cmd="exec $fd<$DIR/$tfile"
2636         eval $cmd
2637         cmd="exec $fd<&-"
2638         trap "eval $cmd" EXIT
2639         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2640         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2641         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2643         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2644         eval $cmd
2645 }
2646 run_test 31n "check link count of unlinked file"
2647
2648 link_one() {
2649         local TEMPNAME=$(mktemp $1_XXXXXX)
2650         mlink $TEMPNAME $1 2> /dev/null &&
2651                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2652         munlink $TEMPNAME
2653 }
2654
2655 test_31o() { # LU-2901
2656         test_mkdir $DIR/$tdir
2657         for LOOP in $(seq 100); do
2658                 rm -f $DIR/$tdir/$tfile*
2659                 for THREAD in $(seq 8); do
2660                         link_one $DIR/$tdir/$tfile.$LOOP &
2661                 done
2662                 wait
2663                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2664                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2665                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2666                         break || true
2667         done
2668 }
2669 run_test 31o "duplicate hard links with same filename"
2670
2671 test_31p() {
2672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2673
2674         test_mkdir $DIR/$tdir
2675         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2676         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2677
2678         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2679                 error "open unlink test1 failed"
2680         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2681                 error "open unlink test2 failed"
2682
2683         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2684                 error "test1 still exists"
2685         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2686                 error "test2 still exists"
2687 }
2688 run_test 31p "remove of open striped directory"
2689
2690 cleanup_test32_mount() {
2691         local rc=0
2692         trap 0
2693         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2694         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2695         losetup -d $loopdev || true
2696         rm -rf $DIR/$tdir
2697         return $rc
2698 }
2699
2700 test_32a() {
2701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2702
2703         echo "== more mountpoints and symlinks ================="
2704         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2705         trap cleanup_test32_mount EXIT
2706         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2707         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2708                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2709         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2710                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2711         cleanup_test32_mount
2712 }
2713 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2714
2715 test_32b() {
2716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2717
2718         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2719         trap cleanup_test32_mount EXIT
2720         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2721         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2722                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2723         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2724                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2725         cleanup_test32_mount
2726 }
2727 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2728
2729 test_32c() {
2730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2731
2732         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2733         trap cleanup_test32_mount EXIT
2734         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2735         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2736                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2737         test_mkdir -p $DIR/$tdir/d2/test_dir
2738         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2739                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2740         cleanup_test32_mount
2741 }
2742 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2743
2744 test_32d() {
2745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2746
2747         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2748         trap cleanup_test32_mount EXIT
2749         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2750         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2751                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2752         test_mkdir -p $DIR/$tdir/d2/test_dir
2753         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2754                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2755         cleanup_test32_mount
2756 }
2757 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2758
2759 test_32e() {
2760         rm -fr $DIR/$tdir
2761         test_mkdir -p $DIR/$tdir/tmp
2762         local tmp_dir=$DIR/$tdir/tmp
2763         ln -s $DIR/$tdir $tmp_dir/symlink11
2764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2765         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2766         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2767 }
2768 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2769
2770 test_32f() {
2771         rm -fr $DIR/$tdir
2772         test_mkdir -p $DIR/$tdir/tmp
2773         local tmp_dir=$DIR/$tdir/tmp
2774         ln -s $DIR/$tdir $tmp_dir/symlink11
2775         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2776         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2777         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2778 }
2779 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2780
2781 test_32g() {
2782         local tmp_dir=$DIR/$tdir/tmp
2783         test_mkdir -p $tmp_dir
2784         test_mkdir $DIR/${tdir}2
2785         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2786         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2787         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2788         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2789         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2790         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2791 }
2792 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2793
2794 test_32h() {
2795         rm -fr $DIR/$tdir $DIR/${tdir}2
2796         tmp_dir=$DIR/$tdir/tmp
2797         test_mkdir -p $tmp_dir
2798         test_mkdir $DIR/${tdir}2
2799         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2800         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2801         ls $tmp_dir/symlink12 || error "listing symlink12"
2802         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2803 }
2804 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2805
2806 test_32i() {
2807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2808
2809         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2810         trap cleanup_test32_mount EXIT
2811         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2812         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2813                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2814         touch $DIR/$tdir/test_file
2815         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2816                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2817         cleanup_test32_mount
2818 }
2819 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2820
2821 test_32j() {
2822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2823
2824         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2825         trap cleanup_test32_mount EXIT
2826         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2827         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2828                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2829         touch $DIR/$tdir/test_file
2830         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2831                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2832         cleanup_test32_mount
2833 }
2834 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2835
2836 test_32k() {
2837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2838
2839         rm -fr $DIR/$tdir
2840         trap cleanup_test32_mount EXIT
2841         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2842         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2843                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2844         test_mkdir -p $DIR/$tdir/d2
2845         touch $DIR/$tdir/d2/test_file || error "touch failed"
2846         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2847                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2848         cleanup_test32_mount
2849 }
2850 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2851
2852 test_32l() {
2853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2854
2855         rm -fr $DIR/$tdir
2856         trap cleanup_test32_mount EXIT
2857         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2858         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2859                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2860         test_mkdir -p $DIR/$tdir/d2
2861         touch $DIR/$tdir/d2/test_file || error "touch failed"
2862         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2863                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2864         cleanup_test32_mount
2865 }
2866 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2867
2868 test_32m() {
2869         rm -fr $DIR/d32m
2870         test_mkdir -p $DIR/d32m/tmp
2871         TMP_DIR=$DIR/d32m/tmp
2872         ln -s $DIR $TMP_DIR/symlink11
2873         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2874         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2875                 error "symlink11 not a link"
2876         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2877                 error "symlink01 not a link"
2878 }
2879 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2880
2881 test_32n() {
2882         rm -fr $DIR/d32n
2883         test_mkdir -p $DIR/d32n/tmp
2884         TMP_DIR=$DIR/d32n/tmp
2885         ln -s $DIR $TMP_DIR/symlink11
2886         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2887         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2888         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2889 }
2890 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2891
2892 test_32o() {
2893         touch $DIR/$tfile
2894         test_mkdir -p $DIR/d32o/tmp
2895         TMP_DIR=$DIR/d32o/tmp
2896         ln -s $DIR/$tfile $TMP_DIR/symlink12
2897         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2898         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2899                 error "symlink12 not a link"
2900         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2901         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2902                 error "$DIR/d32o/tmp/symlink12 not file type"
2903         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2904                 error "$DIR/d32o/symlink02 not file type"
2905 }
2906 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2907
2908 test_32p() {
2909         log 32p_1
2910         rm -fr $DIR/d32p
2911         log 32p_2
2912         rm -f $DIR/$tfile
2913         log 32p_3
2914         touch $DIR/$tfile
2915         log 32p_4
2916         test_mkdir -p $DIR/d32p/tmp
2917         log 32p_5
2918         TMP_DIR=$DIR/d32p/tmp
2919         log 32p_6
2920         ln -s $DIR/$tfile $TMP_DIR/symlink12
2921         log 32p_7
2922         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2923         log 32p_8
2924         cat $DIR/d32p/tmp/symlink12 ||
2925                 error "Can't open $DIR/d32p/tmp/symlink12"
2926         log 32p_9
2927         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2928         log 32p_10
2929 }
2930 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2931
2932 test_32q() {
2933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2934
2935         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2936         trap cleanup_test32_mount EXIT
2937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2938         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2941         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2942         cleanup_test32_mount
2943 }
2944 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2945
2946 test_32r() {
2947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2948
2949         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2950         trap cleanup_test32_mount EXIT
2951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2952         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2953         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2954                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2955         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2956         cleanup_test32_mount
2957 }
2958 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2959
2960 test_33aa() {
2961         rm -f $DIR/$tfile
2962         touch $DIR/$tfile
2963         chmod 444 $DIR/$tfile
2964         chown $RUNAS_ID $DIR/$tfile
2965         log 33_1
2966         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2967         log 33_2
2968 }
2969 run_test 33aa "write file with mode 444 (should return error)"
2970
2971 test_33a() {
2972         rm -fr $DIR/$tdir
2973         test_mkdir $DIR/$tdir
2974         chown $RUNAS_ID $DIR/$tdir
2975         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2976                 error "$RUNAS create $tdir/$tfile failed"
2977         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2978                 error "open RDWR" || true
2979 }
2980 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2981
2982 test_33b() {
2983         rm -fr $DIR/$tdir
2984         test_mkdir $DIR/$tdir
2985         chown $RUNAS_ID $DIR/$tdir
2986         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2987 }
2988 run_test 33b "test open file with malformed flags (No panic)"
2989
2990 test_33c() {
2991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2992         remote_ost_nodsh && skip "remote OST with nodsh"
2993
2994         local ostnum
2995         local ostname
2996         local write_bytes
2997         local all_zeros
2998
2999         all_zeros=:
3000         rm -fr $DIR/$tdir
3001         test_mkdir $DIR/$tdir
3002         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3003
3004         sync
3005         for ostnum in $(seq $OSTCOUNT); do
3006                 # test-framework's OST numbering is one-based, while Lustre's
3007                 # is zero-based
3008                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3009                 # Parsing llobdstat's output sucks; we could grep the /proc
3010                 # path, but that's likely to not be as portable as using the
3011                 # llobdstat utility.  So we parse lctl output instead.
3012                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3013                         obdfilter/$ostname/stats |
3014                         awk '/^write_bytes/ {print $7}' )
3015                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3016                 if (( ${write_bytes:-0} > 0 ))
3017                 then
3018                         all_zeros=false
3019                         break;
3020                 fi
3021         done
3022
3023         $all_zeros || return 0
3024
3025         # Write four bytes
3026         echo foo > $DIR/$tdir/bar
3027         # Really write them
3028         sync
3029
3030         # Total up write_bytes after writing.  We'd better find non-zeros.
3031         for ostnum in $(seq $OSTCOUNT); do
3032                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3033                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3034                         obdfilter/$ostname/stats |
3035                         awk '/^write_bytes/ {print $7}' )
3036                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3037                 if (( ${write_bytes:-0} > 0 ))
3038                 then
3039                         all_zeros=false
3040                         break;
3041                 fi
3042         done
3043
3044         if $all_zeros
3045         then
3046                 for ostnum in $(seq $OSTCOUNT); do
3047                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3048                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3049                         do_facet ost$ostnum lctl get_param -n \
3050                                 obdfilter/$ostname/stats
3051                 done
3052                 error "OST not keeping write_bytes stats (b22312)"
3053         fi
3054 }
3055 run_test 33c "test llobdstat and write_bytes"
3056
3057 test_33d() {
3058         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         local MDTIDX=1
3062         local remote_dir=$DIR/$tdir/remote_dir
3063
3064         test_mkdir $DIR/$tdir
3065         $LFS mkdir -i $MDTIDX $remote_dir ||
3066                 error "create remote directory failed"
3067
3068         touch $remote_dir/$tfile
3069         chmod 444 $remote_dir/$tfile
3070         chown $RUNAS_ID $remote_dir/$tfile
3071
3072         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3073
3074         chown $RUNAS_ID $remote_dir
3075         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3076                                         error "create" || true
3077         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3078                                     error "open RDWR" || true
3079         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3080 }
3081 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3082
3083 test_33e() {
3084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3085
3086         mkdir $DIR/$tdir
3087
3088         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3089         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3090         mkdir $DIR/$tdir/local_dir
3091
3092         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3093         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3094         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3095
3096         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3097                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3098
3099         rmdir $DIR/$tdir/* || error "rmdir failed"
3100
3101         umask 777
3102         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3103         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3104         mkdir $DIR/$tdir/local_dir
3105
3106         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3107         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3108         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3109
3110         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3111                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3112
3113         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3114
3115         umask 000
3116         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3117         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3118         mkdir $DIR/$tdir/local_dir
3119
3120         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3121         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3122         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3123
3124         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3125                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3126 }
3127 run_test 33e "mkdir and striped directory should have same mode"
3128
3129 cleanup_33f() {
3130         trap 0
3131         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3132 }
3133
3134 test_33f() {
3135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3136         remote_mds_nodsh && skip "remote MDS with nodsh"
3137
3138         mkdir $DIR/$tdir
3139         chmod go+rwx $DIR/$tdir
3140         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3141         trap cleanup_33f EXIT
3142
3143         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3144                 error "cannot create striped directory"
3145
3146         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3147                 error "cannot create files in striped directory"
3148
3149         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3150                 error "cannot remove files in striped directory"
3151
3152         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3153                 error "cannot remove striped directory"
3154
3155         cleanup_33f
3156 }
3157 run_test 33f "nonroot user can create, access, and remove a striped directory"
3158
3159 test_33g() {
3160         mkdir -p $DIR/$tdir/dir2
3161
3162         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3163         echo $err
3164         [[ $err =~ "exists" ]] || error "Not exists error"
3165 }
3166 run_test 33g "nonroot user create already existing root created file"
3167
3168 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3169 test_34a() {
3170         rm -f $DIR/f34
3171         $MCREATE $DIR/f34 || error "mcreate failed"
3172         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3173                 error "getstripe failed"
3174         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3175         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3176                 error "getstripe failed"
3177         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3178                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3179 }
3180 run_test 34a "truncate file that has not been opened ==========="
3181
3182 test_34b() {
3183         [ ! -f $DIR/f34 ] && test_34a
3184         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3185                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3186         $OPENFILE -f O_RDONLY $DIR/f34
3187         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3188                 error "getstripe failed"
3189         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3190                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3191 }
3192 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3193
3194 test_34c() {
3195         [ ! -f $DIR/f34 ] && test_34a
3196         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3197                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3198         $OPENFILE -f O_RDWR $DIR/f34
3199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3200                 error "$LFS getstripe failed"
3201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3203 }
3204 run_test 34c "O_RDWR opening file-with-size works =============="
3205
3206 test_34d() {
3207         [ ! -f $DIR/f34 ] && test_34a
3208         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3209                 error "dd failed"
3210         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3211                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3212         rm $DIR/f34
3213 }
3214 run_test 34d "write to sparse file ============================="
3215
3216 test_34e() {
3217         rm -f $DIR/f34e
3218         $MCREATE $DIR/f34e || error "mcreate failed"
3219         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3220         $CHECKSTAT -s 1000 $DIR/f34e ||
3221                 error "Size of $DIR/f34e not equal to 1000 bytes"
3222         $OPENFILE -f O_RDWR $DIR/f34e
3223         $CHECKSTAT -s 1000 $DIR/f34e ||
3224                 error "Size of $DIR/f34e not equal to 1000 bytes"
3225 }
3226 run_test 34e "create objects, some with size and some without =="
3227
3228 test_34f() { # bug 6242, 6243
3229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3230
3231         SIZE34F=48000
3232         rm -f $DIR/f34f
3233         $MCREATE $DIR/f34f || error "mcreate failed"
3234         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3235         dd if=$DIR/f34f of=$TMP/f34f
3236         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3237         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3238         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3239         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3240         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3241 }
3242 run_test 34f "read from a file with no objects until EOF ======="
3243
3244 test_34g() {
3245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3246
3247         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3248                 error "dd failed"
3249         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3250         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3251                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3252         cancel_lru_locks osc
3253         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3254                 error "wrong size after lock cancel"
3255
3256         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3257         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3258                 error "expanding truncate failed"
3259         cancel_lru_locks osc
3260         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3261                 error "wrong expanded size after lock cancel"
3262 }
3263 run_test 34g "truncate long file ==============================="
3264
3265 test_34h() {
3266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3267
3268         local gid=10
3269         local sz=1000
3270
3271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3272         sync # Flush the cache so that multiop below does not block on cache
3273              # flush when getting the group lock
3274         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3275         MULTIPID=$!
3276
3277         # Since just timed wait is not good enough, let's do a sync write
3278         # that way we are sure enough time for a roundtrip + processing
3279         # passed + 2 seconds of extra margin.
3280         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3281         rm $DIR/${tfile}-1
3282         sleep 2
3283
3284         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3285                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3286                 kill -9 $MULTIPID
3287         fi
3288         wait $MULTIPID
3289         local nsz=`stat -c %s $DIR/$tfile`
3290         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3291 }
3292 run_test 34h "ftruncate file under grouplock should not block"
3293
3294 test_35a() {
3295         cp /bin/sh $DIR/f35a
3296         chmod 444 $DIR/f35a
3297         chown $RUNAS_ID $DIR/f35a
3298         $RUNAS $DIR/f35a && error || true
3299         rm $DIR/f35a
3300 }
3301 run_test 35a "exec file with mode 444 (should return and not leak)"
3302
3303 test_36a() {
3304         rm -f $DIR/f36
3305         utime $DIR/f36 || error "utime failed for MDS"
3306 }
3307 run_test 36a "MDS utime check (mknod, utime)"
3308
3309 test_36b() {
3310         echo "" > $DIR/f36
3311         utime $DIR/f36 || error "utime failed for OST"
3312 }
3313 run_test 36b "OST utime check (open, utime)"
3314
3315 test_36c() {
3316         rm -f $DIR/d36/f36
3317         test_mkdir $DIR/d36
3318         chown $RUNAS_ID $DIR/d36
3319         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3320 }
3321 run_test 36c "non-root MDS utime check (mknod, utime)"
3322
3323 test_36d() {
3324         [ ! -d $DIR/d36 ] && test_36c
3325         echo "" > $DIR/d36/f36
3326         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3327 }
3328 run_test 36d "non-root OST utime check (open, utime)"
3329
3330 test_36e() {
3331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3332
3333         test_mkdir $DIR/$tdir
3334         touch $DIR/$tdir/$tfile
3335         $RUNAS utime $DIR/$tdir/$tfile &&
3336                 error "utime worked, expected failure" || true
3337 }
3338 run_test 36e "utime on non-owned file (should return error)"
3339
3340 subr_36fh() {
3341         local fl="$1"
3342         local LANG_SAVE=$LANG
3343         local LC_LANG_SAVE=$LC_LANG
3344         export LANG=C LC_LANG=C # for date language
3345
3346         DATESTR="Dec 20  2000"
3347         test_mkdir $DIR/$tdir
3348         lctl set_param fail_loc=$fl
3349         date; date +%s
3350         cp /etc/hosts $DIR/$tdir/$tfile
3351         sync & # write RPC generated with "current" inode timestamp, but delayed
3352         sleep 1
3353         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3354         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3355         cancel_lru_locks $OSC
3356         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3357         date; date +%s
3358         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3359                 echo "BEFORE: $LS_BEFORE" && \
3360                 echo "AFTER : $LS_AFTER" && \
3361                 echo "WANT  : $DATESTR" && \
3362                 error "$DIR/$tdir/$tfile timestamps changed" || true
3363
3364         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3365 }
3366
3367 test_36f() {
3368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3369
3370         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3371         subr_36fh "0x80000214"
3372 }
3373 run_test 36f "utime on file racing with OST BRW write =========="
3374
3375 test_36g() {
3376         remote_ost_nodsh && skip "remote OST with nodsh"
3377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3378         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3379                 skip "Need MDS version at least 2.12.51"
3380
3381         local fmd_max_age
3382         local fmd
3383         local facet="ost1"
3384         local tgt="obdfilter"
3385
3386         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3387
3388         test_mkdir $DIR/$tdir
3389         fmd_max_age=$(do_facet $facet \
3390                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3391                 head -n 1")
3392
3393         echo "FMD max age: ${fmd_max_age}s"
3394         touch $DIR/$tdir/$tfile
3395         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3396                 gawk '{cnt=cnt+$1}  END{print cnt}')
3397         echo "FMD before: $fmd"
3398         [[ $fmd == 0 ]] &&
3399                 error "FMD wasn't create by touch"
3400         sleep $((fmd_max_age + 12))
3401         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3402                 gawk '{cnt=cnt+$1}  END{print cnt}')
3403         echo "FMD after: $fmd"
3404         [[ $fmd == 0 ]] ||
3405                 error "FMD wasn't expired by ping"
3406 }
3407 run_test 36g "FMD cache expiry ====================="
3408
3409 test_36h() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3413         subr_36fh "0x80000227"
3414 }
3415 run_test 36h "utime on file racing with OST BRW write =========="
3416
3417 test_36i() {
3418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3419
3420         test_mkdir $DIR/$tdir
3421         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3422
3423         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3424         local new_mtime=$((mtime + 200))
3425
3426         #change Modify time of striped dir
3427         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3428                         error "change mtime failed"
3429
3430         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3431
3432         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3433 }
3434 run_test 36i "change mtime on striped directory"
3435
3436 # test_37 - duplicate with tests 32q 32r
3437
3438 test_38() {
3439         local file=$DIR/$tfile
3440         touch $file
3441         openfile -f O_DIRECTORY $file
3442         local RC=$?
3443         local ENOTDIR=20
3444         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3445         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3446 }
3447 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3448
3449 test_39a() { # was test_39
3450         touch $DIR/$tfile
3451         touch $DIR/${tfile}2
3452 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3453 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3454 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3455         sleep 2
3456         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3457         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3458                 echo "mtime"
3459                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3460                 echo "atime"
3461                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3462                 echo "ctime"
3463                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3464                 error "O_TRUNC didn't change timestamps"
3465         fi
3466 }
3467 run_test 39a "mtime changed on create"
3468
3469 test_39b() {
3470         test_mkdir -c1 $DIR/$tdir
3471         cp -p /etc/passwd $DIR/$tdir/fopen
3472         cp -p /etc/passwd $DIR/$tdir/flink
3473         cp -p /etc/passwd $DIR/$tdir/funlink
3474         cp -p /etc/passwd $DIR/$tdir/frename
3475         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3476
3477         sleep 1
3478         echo "aaaaaa" >> $DIR/$tdir/fopen
3479         echo "aaaaaa" >> $DIR/$tdir/flink
3480         echo "aaaaaa" >> $DIR/$tdir/funlink
3481         echo "aaaaaa" >> $DIR/$tdir/frename
3482
3483         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3484         local link_new=`stat -c %Y $DIR/$tdir/flink`
3485         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3486         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3487
3488         cat $DIR/$tdir/fopen > /dev/null
3489         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3490         rm -f $DIR/$tdir/funlink2
3491         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3492
3493         for (( i=0; i < 2; i++ )) ; do
3494                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3495                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3496                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3497                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3498
3499                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3500                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3501                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3502                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3503
3504                 cancel_lru_locks $OSC
3505                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3506         done
3507 }
3508 run_test 39b "mtime change on open, link, unlink, rename  ======"
3509
3510 # this should be set to past
3511 TEST_39_MTIME=`date -d "1 year ago" +%s`
3512
3513 # bug 11063
3514 test_39c() {
3515         touch $DIR1/$tfile
3516         sleep 2
3517         local mtime0=`stat -c %Y $DIR1/$tfile`
3518
3519         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3520         local mtime1=`stat -c %Y $DIR1/$tfile`
3521         [ "$mtime1" = $TEST_39_MTIME ] || \
3522                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3523
3524         local d1=`date +%s`
3525         echo hello >> $DIR1/$tfile
3526         local d2=`date +%s`
3527         local mtime2=`stat -c %Y $DIR1/$tfile`
3528         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3529                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3530
3531         mv $DIR1/$tfile $DIR1/$tfile-1
3532
3533         for (( i=0; i < 2; i++ )) ; do
3534                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3535                 [ "$mtime2" = "$mtime3" ] || \
3536                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3537
3538                 cancel_lru_locks $OSC
3539                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3540         done
3541 }
3542 run_test 39c "mtime change on rename ==========================="
3543
3544 # bug 21114
3545 test_39d() {
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         touch $DIR1/$tfile
3549         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3550
3551         for (( i=0; i < 2; i++ )) ; do
3552                 local mtime=`stat -c %Y $DIR1/$tfile`
3553                 [ $mtime = $TEST_39_MTIME ] || \
3554                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3555
3556                 cancel_lru_locks $OSC
3557                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3558         done
3559 }
3560 run_test 39d "create, utime, stat =============================="
3561
3562 # bug 21114
3563 test_39e() {
3564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3565
3566         touch $DIR1/$tfile
3567         local mtime1=`stat -c %Y $DIR1/$tfile`
3568
3569         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3570
3571         for (( i=0; i < 2; i++ )) ; do
3572                 local mtime2=`stat -c %Y $DIR1/$tfile`
3573                 [ $mtime2 = $TEST_39_MTIME ] || \
3574                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3575
3576                 cancel_lru_locks $OSC
3577                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3578         done
3579 }
3580 run_test 39e "create, stat, utime, stat ========================"
3581
3582 # bug 21114
3583 test_39f() {
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         touch $DIR1/$tfile
3587         mtime1=`stat -c %Y $DIR1/$tfile`
3588
3589         sleep 2
3590         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3591
3592         for (( i=0; i < 2; i++ )) ; do
3593                 local mtime2=`stat -c %Y $DIR1/$tfile`
3594                 [ $mtime2 = $TEST_39_MTIME ] || \
3595                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3596
3597                 cancel_lru_locks $OSC
3598                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3599         done
3600 }
3601 run_test 39f "create, stat, sleep, utime, stat ================="
3602
3603 # bug 11063
3604 test_39g() {
3605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3606
3607         echo hello >> $DIR1/$tfile
3608         local mtime1=`stat -c %Y $DIR1/$tfile`
3609
3610         sleep 2
3611         chmod o+r $DIR1/$tfile
3612
3613         for (( i=0; i < 2; i++ )) ; do
3614                 local mtime2=`stat -c %Y $DIR1/$tfile`
3615                 [ "$mtime1" = "$mtime2" ] || \
3616                         error "lost mtime: $mtime2, should be $mtime1"
3617
3618                 cancel_lru_locks $OSC
3619                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3620         done
3621 }
3622 run_test 39g "write, chmod, stat ==============================="
3623
3624 # bug 11063
3625 test_39h() {
3626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3627
3628         touch $DIR1/$tfile
3629         sleep 1
3630
3631         local d1=`date`
3632         echo hello >> $DIR1/$tfile
3633         local mtime1=`stat -c %Y $DIR1/$tfile`
3634
3635         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3636         local d2=`date`
3637         if [ "$d1" != "$d2" ]; then
3638                 echo "write and touch not within one second"
3639         else
3640                 for (( i=0; i < 2; i++ )) ; do
3641                         local mtime2=`stat -c %Y $DIR1/$tfile`
3642                         [ "$mtime2" = $TEST_39_MTIME ] || \
3643                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3644
3645                         cancel_lru_locks $OSC
3646                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3647                 done
3648         fi
3649 }
3650 run_test 39h "write, utime within one second, stat ============="
3651
3652 test_39i() {
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         touch $DIR1/$tfile
3656         sleep 1
3657
3658         echo hello >> $DIR1/$tfile
3659         local mtime1=`stat -c %Y $DIR1/$tfile`
3660
3661         mv $DIR1/$tfile $DIR1/$tfile-1
3662
3663         for (( i=0; i < 2; i++ )) ; do
3664                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3665
3666                 [ "$mtime1" = "$mtime2" ] || \
3667                         error "lost mtime: $mtime2, should be $mtime1"
3668
3669                 cancel_lru_locks $OSC
3670                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3671         done
3672 }
3673 run_test 39i "write, rename, stat =============================="
3674
3675 test_39j() {
3676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3677
3678         start_full_debug_logging
3679         touch $DIR1/$tfile
3680         sleep 1
3681
3682         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3683         lctl set_param fail_loc=0x80000412
3684         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3685                 error "multiop failed"
3686         local multipid=$!
3687         local mtime1=`stat -c %Y $DIR1/$tfile`
3688
3689         mv $DIR1/$tfile $DIR1/$tfile-1
3690
3691         kill -USR1 $multipid
3692         wait $multipid || error "multiop close failed"
3693
3694         for (( i=0; i < 2; i++ )) ; do
3695                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3696                 [ "$mtime1" = "$mtime2" ] ||
3697                         error "mtime is lost on close: $mtime2, " \
3698                               "should be $mtime1"
3699
3700                 cancel_lru_locks $OSC
3701                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3702         done
3703         lctl set_param fail_loc=0
3704         stop_full_debug_logging
3705 }
3706 run_test 39j "write, rename, close, stat ======================="
3707
3708 test_39k() {
3709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3710
3711         touch $DIR1/$tfile
3712         sleep 1
3713
3714         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3715         local multipid=$!
3716         local mtime1=`stat -c %Y $DIR1/$tfile`
3717
3718         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3719
3720         kill -USR1 $multipid
3721         wait $multipid || error "multiop close failed"
3722
3723         for (( i=0; i < 2; i++ )) ; do
3724                 local mtime2=`stat -c %Y $DIR1/$tfile`
3725
3726                 [ "$mtime2" = $TEST_39_MTIME ] || \
3727                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3728
3729                 cancel_lru_locks osc
3730                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3731         done
3732 }
3733 run_test 39k "write, utime, close, stat ========================"
3734
3735 # this should be set to future
3736 TEST_39_ATIME=`date -d "1 year" +%s`
3737
3738 test_39l() {
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3740         remote_mds_nodsh && skip "remote MDS with nodsh"
3741
3742         local atime_diff=$(do_facet $SINGLEMDS \
3743                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3744         rm -rf $DIR/$tdir
3745         mkdir -p $DIR/$tdir
3746
3747         # test setting directory atime to future
3748         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3749         local atime=$(stat -c %X $DIR/$tdir)
3750         [ "$atime" = $TEST_39_ATIME ] ||
3751                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3752
3753         # test setting directory atime from future to now
3754         local now=$(date +%s)
3755         touch -a -d @$now $DIR/$tdir
3756
3757         atime=$(stat -c %X $DIR/$tdir)
3758         [ "$atime" -eq "$now"  ] ||
3759                 error "atime is not updated from future: $atime, $now"
3760
3761         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3762         sleep 3
3763
3764         # test setting directory atime when now > dir atime + atime_diff
3765         local d1=$(date +%s)
3766         ls $DIR/$tdir
3767         local d2=$(date +%s)
3768         cancel_lru_locks mdc
3769         atime=$(stat -c %X $DIR/$tdir)
3770         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3771                 error "atime is not updated  : $atime, should be $d2"
3772
3773         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3774         sleep 3
3775
3776         # test not setting directory atime when now < dir atime + atime_diff
3777         ls $DIR/$tdir
3778         cancel_lru_locks mdc
3779         atime=$(stat -c %X $DIR/$tdir)
3780         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3781                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3782
3783         do_facet $SINGLEMDS \
3784                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3785 }
3786 run_test 39l "directory atime update ==========================="
3787
3788 test_39m() {
3789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3790
3791         touch $DIR1/$tfile
3792         sleep 2
3793         local far_past_mtime=$(date -d "May 29 1953" +%s)
3794         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3795
3796         touch -m -d @$far_past_mtime $DIR1/$tfile
3797         touch -a -d @$far_past_atime $DIR1/$tfile
3798
3799         for (( i=0; i < 2; i++ )) ; do
3800                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3801                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3802                         error "atime or mtime set incorrectly"
3803
3804                 cancel_lru_locks $OSC
3805                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3806         done
3807 }
3808 run_test 39m "test atime and mtime before 1970"
3809
3810 test_39n() { # LU-3832
3811         remote_mds_nodsh && skip "remote MDS with nodsh"
3812
3813         local atime_diff=$(do_facet $SINGLEMDS \
3814                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3815         local atime0
3816         local atime1
3817         local atime2
3818
3819         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3820
3821         rm -rf $DIR/$tfile
3822         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3823         atime0=$(stat -c %X $DIR/$tfile)
3824
3825         sleep 5
3826         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3827         atime1=$(stat -c %X $DIR/$tfile)
3828
3829         sleep 5
3830         cancel_lru_locks mdc
3831         cancel_lru_locks osc
3832         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3833         atime2=$(stat -c %X $DIR/$tfile)
3834
3835         do_facet $SINGLEMDS \
3836                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3837
3838         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3839         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3840 }
3841 run_test 39n "check that O_NOATIME is honored"
3842
3843 test_39o() {
3844         TESTDIR=$DIR/$tdir/$tfile
3845         [ -e $TESTDIR ] && rm -rf $TESTDIR
3846         mkdir -p $TESTDIR
3847         cd $TESTDIR
3848         links1=2
3849         ls
3850         mkdir a b
3851         ls
3852         links2=$(stat -c %h .)
3853         [ $(($links1 + 2)) != $links2 ] &&
3854                 error "wrong links count $(($links1 + 2)) != $links2"
3855         rmdir b
3856         links3=$(stat -c %h .)
3857         [ $(($links1 + 1)) != $links3 ] &&
3858                 error "wrong links count $links1 != $links3"
3859         return 0
3860 }
3861 run_test 39o "directory cached attributes updated after create"
3862
3863 test_39p() {
3864         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3865
3866         local MDTIDX=1
3867         TESTDIR=$DIR/$tdir/$tdir
3868         [ -e $TESTDIR ] && rm -rf $TESTDIR
3869         test_mkdir -p $TESTDIR
3870         cd $TESTDIR
3871         links1=2
3872         ls
3873         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3874         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3875         ls
3876         links2=$(stat -c %h .)
3877         [ $(($links1 + 2)) != $links2 ] &&
3878                 error "wrong links count $(($links1 + 2)) != $links2"
3879         rmdir remote_dir2
3880         links3=$(stat -c %h .)
3881         [ $(($links1 + 1)) != $links3 ] &&
3882                 error "wrong links count $links1 != $links3"
3883         return 0
3884 }
3885 run_test 39p "remote directory cached attributes updated after create ========"
3886
3887
3888 test_39q() { # LU-8041
3889         local testdir=$DIR/$tdir
3890         mkdir -p $testdir
3891         multiop_bg_pause $testdir D_c || error "multiop failed"
3892         local multipid=$!
3893         cancel_lru_locks mdc
3894         kill -USR1 $multipid
3895         local atime=$(stat -c %X $testdir)
3896         [ "$atime" -ne 0 ] || error "atime is zero"
3897 }
3898 run_test 39q "close won't zero out atime"
3899
3900 test_40() {
3901         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3902         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3903                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3904         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3905                 error "$tfile is not 4096 bytes in size"
3906 }
3907 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3908
3909 test_41() {
3910         # bug 1553
3911         small_write $DIR/f41 18
3912 }
3913 run_test 41 "test small file write + fstat ====================="
3914
3915 count_ost_writes() {
3916         lctl get_param -n ${OSC}.*.stats |
3917                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3918                         END { printf("%0.0f", writes) }'
3919 }
3920
3921 # decent default
3922 WRITEBACK_SAVE=500
3923 DIRTY_RATIO_SAVE=40
3924 MAX_DIRTY_RATIO=50
3925 BG_DIRTY_RATIO_SAVE=10
3926 MAX_BG_DIRTY_RATIO=25
3927
3928 start_writeback() {
3929         trap 0
3930         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3931         # dirty_ratio, dirty_background_ratio
3932         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3933                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3934                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3935                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3936         else
3937                 # if file not here, we are a 2.4 kernel
3938                 kill -CONT `pidof kupdated`
3939         fi
3940 }
3941
3942 stop_writeback() {
3943         # setup the trap first, so someone cannot exit the test at the
3944         # exact wrong time and mess up a machine
3945         trap start_writeback EXIT
3946         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3947         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3948                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3949                 sysctl -w vm.dirty_writeback_centisecs=0
3950                 sysctl -w vm.dirty_writeback_centisecs=0
3951                 # save and increase /proc/sys/vm/dirty_ratio
3952                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3953                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3954                 # save and increase /proc/sys/vm/dirty_background_ratio
3955                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3956                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3957         else
3958                 # if file not here, we are a 2.4 kernel
3959                 kill -STOP `pidof kupdated`
3960         fi
3961 }
3962
3963 # ensure that all stripes have some grant before we test client-side cache
3964 setup_test42() {
3965         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3966                 dd if=/dev/zero of=$i bs=4k count=1
3967                 rm $i
3968         done
3969 }
3970
3971 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3972 # file truncation, and file removal.
3973 test_42a() {
3974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3975
3976         setup_test42
3977         cancel_lru_locks $OSC
3978         stop_writeback
3979         sync; sleep 1; sync # just to be safe
3980         BEFOREWRITES=`count_ost_writes`
3981         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3982         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3983         AFTERWRITES=`count_ost_writes`
3984         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3985                 error "$BEFOREWRITES < $AFTERWRITES"
3986         start_writeback
3987 }
3988 run_test 42a "ensure that we don't flush on close"
3989
3990 test_42b() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         setup_test42
3994         cancel_lru_locks $OSC
3995         stop_writeback
3996         sync
3997         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3998         BEFOREWRITES=$(count_ost_writes)
3999         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4000         AFTERWRITES=$(count_ost_writes)
4001         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4002                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4003         fi
4004         BEFOREWRITES=$(count_ost_writes)
4005         sync || error "sync: $?"
4006         AFTERWRITES=$(count_ost_writes)
4007         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4008                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4009         fi
4010         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4011         start_writeback
4012         return 0
4013 }
4014 run_test 42b "test destroy of file with cached dirty data ======"
4015
4016 # if these tests just want to test the effect of truncation,
4017 # they have to be very careful.  consider:
4018 # - the first open gets a {0,EOF}PR lock
4019 # - the first write conflicts and gets a {0, count-1}PW
4020 # - the rest of the writes are under {count,EOF}PW
4021 # - the open for truncate tries to match a {0,EOF}PR
4022 #   for the filesize and cancels the PWs.
4023 # any number of fixes (don't get {0,EOF} on open, match
4024 # composite locks, do smarter file size management) fix
4025 # this, but for now we want these tests to verify that
4026 # the cancellation with truncate intent works, so we
4027 # start the file with a full-file pw lock to match against
4028 # until the truncate.
4029 trunc_test() {
4030         test=$1
4031         file=$DIR/$test
4032         offset=$2
4033         cancel_lru_locks $OSC
4034         stop_writeback
4035         # prime the file with 0,EOF PW to match
4036         touch $file
4037         $TRUNCATE $file 0
4038         sync; sync
4039         # now the real test..
4040         dd if=/dev/zero of=$file bs=1024 count=100
4041         BEFOREWRITES=`count_ost_writes`
4042         $TRUNCATE $file $offset
4043         cancel_lru_locks $OSC
4044         AFTERWRITES=`count_ost_writes`
4045         start_writeback
4046 }
4047
4048 test_42c() {
4049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4050
4051         trunc_test 42c 1024
4052         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4053                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4054         rm $file
4055 }
4056 run_test 42c "test partial truncate of file with cached dirty data"
4057
4058 test_42d() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         trunc_test 42d 0
4062         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4063                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4064         rm $file
4065 }
4066 run_test 42d "test complete truncate of file with cached dirty data"
4067
4068 test_42e() { # bug22074
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070
4071         local TDIR=$DIR/${tdir}e
4072         local pages=16 # hardcoded 16 pages, don't change it.
4073         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4074         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4075         local max_dirty_mb
4076         local warmup_files
4077
4078         test_mkdir $DIR/${tdir}e
4079         $LFS setstripe -c 1 $TDIR
4080         createmany -o $TDIR/f $files
4081
4082         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4083
4084         # we assume that with $OSTCOUNT files, at least one of them will
4085         # be allocated on OST0.
4086         warmup_files=$((OSTCOUNT * max_dirty_mb))
4087         createmany -o $TDIR/w $warmup_files
4088
4089         # write a large amount of data into one file and sync, to get good
4090         # avail_grant number from OST.
4091         for ((i=0; i<$warmup_files; i++)); do
4092                 idx=$($LFS getstripe -i $TDIR/w$i)
4093                 [ $idx -ne 0 ] && continue
4094                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4095                 break
4096         done
4097         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4098         sync
4099         $LCTL get_param $proc_osc0/cur_dirty_bytes
4100         $LCTL get_param $proc_osc0/cur_grant_bytes
4101
4102         # create as much dirty pages as we can while not to trigger the actual
4103         # RPCs directly. but depends on the env, VFS may trigger flush during this
4104         # period, hopefully we are good.
4105         for ((i=0; i<$warmup_files; i++)); do
4106                 idx=$($LFS getstripe -i $TDIR/w$i)
4107                 [ $idx -ne 0 ] && continue
4108                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4109         done
4110         $LCTL get_param $proc_osc0/cur_dirty_bytes
4111         $LCTL get_param $proc_osc0/cur_grant_bytes
4112
4113         # perform the real test
4114         $LCTL set_param $proc_osc0/rpc_stats 0
4115         for ((;i<$files; i++)); do
4116                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4117                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4118         done
4119         sync
4120         $LCTL get_param $proc_osc0/rpc_stats
4121
4122         local percent=0
4123         local have_ppr=false
4124         $LCTL get_param $proc_osc0/rpc_stats |
4125                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4126                         # skip lines until we are at the RPC histogram data
4127                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4128                         $have_ppr || continue
4129
4130                         # we only want the percent stat for < 16 pages
4131                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4132
4133                         percent=$((percent + WPCT))
4134                         if [[ $percent -gt 15 ]]; then
4135                                 error "less than 16-pages write RPCs" \
4136                                       "$percent% > 15%"
4137                                 break
4138                         fi
4139                 done
4140         rm -rf $TDIR
4141 }
4142 run_test 42e "verify sub-RPC writes are not done synchronously"
4143
4144 test_43A() { # was test_43
4145         test_mkdir $DIR/$tdir
4146         cp -p /bin/ls $DIR/$tdir/$tfile
4147         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4148         pid=$!
4149         # give multiop a chance to open
4150         sleep 1
4151
4152         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4153         kill -USR1 $pid
4154 }
4155 run_test 43A "execution of file opened for write should return -ETXTBSY"
4156
4157 test_43a() {
4158         test_mkdir $DIR/$tdir
4159         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4160         $DIR/$tdir/sleep 60 &
4161         SLEEP_PID=$!
4162         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4163         kill $SLEEP_PID
4164 }
4165 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4166
4167 test_43b() {
4168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4169
4170         test_mkdir $DIR/$tdir
4171         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4172         $DIR/$tdir/sleep 60 &
4173         SLEEP_PID=$!
4174         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4175         kill $SLEEP_PID
4176 }
4177 run_test 43b "truncate of file being executed should return -ETXTBSY"
4178
4179 test_43c() {
4180         local testdir="$DIR/$tdir"
4181         test_mkdir $testdir
4182         cp $SHELL $testdir/
4183         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4184                 ( cd $testdir && md5sum -c )
4185 }
4186 run_test 43c "md5sum of copy into lustre"
4187
4188 test_44A() { # was test_44
4189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4190
4191         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4192         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4193 }
4194 run_test 44A "zero length read from a sparse stripe"
4195
4196 test_44a() {
4197         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4198                 awk '{ print $2 }')
4199         [ -z "$nstripe" ] && skip "can't get stripe info"
4200         [[ $nstripe -gt $OSTCOUNT ]] &&
4201                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4202
4203         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4204                 awk '{ print $2 }')
4205         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4206                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4207                         awk '{ print $2 }')
4208         fi
4209
4210         OFFSETS="0 $((stride/2)) $((stride-1))"
4211         for offset in $OFFSETS; do
4212                 for i in $(seq 0 $((nstripe-1))); do
4213                         local GLOBALOFFSETS=""
4214                         # size in Bytes
4215                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4216                         local myfn=$DIR/d44a-$size
4217                         echo "--------writing $myfn at $size"
4218                         ll_sparseness_write $myfn $size ||
4219                                 error "ll_sparseness_write"
4220                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4221                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4222                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4223
4224                         for j in $(seq 0 $((nstripe-1))); do
4225                                 # size in Bytes
4226                                 size=$((((j + $nstripe )*$stride + $offset)))
4227                                 ll_sparseness_write $myfn $size ||
4228                                         error "ll_sparseness_write"
4229                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4230                         done
4231                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4232                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4233                         rm -f $myfn
4234                 done
4235         done
4236 }
4237 run_test 44a "test sparse pwrite ==============================="
4238
4239 dirty_osc_total() {
4240         tot=0
4241         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4242                 tot=$(($tot + $d))
4243         done
4244         echo $tot
4245 }
4246 do_dirty_record() {
4247         before=`dirty_osc_total`
4248         echo executing "\"$*\""
4249         eval $*
4250         after=`dirty_osc_total`
4251         echo before $before, after $after
4252 }
4253 test_45() {
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         f="$DIR/f45"
4257         # Obtain grants from OST if it supports it
4258         echo blah > ${f}_grant
4259         stop_writeback
4260         sync
4261         do_dirty_record "echo blah > $f"
4262         [[ $before -eq $after ]] && error "write wasn't cached"
4263         do_dirty_record "> $f"
4264         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4265         do_dirty_record "echo blah > $f"
4266         [[ $before -eq $after ]] && error "write wasn't cached"
4267         do_dirty_record "sync"
4268         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4269         do_dirty_record "echo blah > $f"
4270         [[ $before -eq $after ]] && error "write wasn't cached"
4271         do_dirty_record "cancel_lru_locks osc"
4272         [[ $before -gt $after ]] ||
4273                 error "lock cancellation didn't lower dirty count"
4274         start_writeback
4275 }
4276 run_test 45 "osc io page accounting ============================"
4277
4278 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4279 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4280 # objects offset and an assert hit when an rpc was built with 1023's mapped
4281 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4282 test_46() {
4283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4284
4285         f="$DIR/f46"
4286         stop_writeback
4287         sync
4288         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4289         sync
4290         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4291         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4292         sync
4293         start_writeback
4294 }
4295 run_test 46 "dirtying a previously written page ================"
4296
4297 # test_47 is removed "Device nodes check" is moved to test_28
4298
4299 test_48a() { # bug 2399
4300         [ "$mds1_FSTYPE" = "zfs" ] &&
4301         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4302                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4303
4304         test_mkdir $DIR/$tdir
4305         cd $DIR/$tdir
4306         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4307         test_mkdir $DIR/$tdir
4308         touch foo || error "'touch foo' failed after recreating cwd"
4309         test_mkdir bar
4310         touch .foo || error "'touch .foo' failed after recreating cwd"
4311         test_mkdir .bar
4312         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4313         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4314         cd . || error "'cd .' failed after recreating cwd"
4315         mkdir . && error "'mkdir .' worked after recreating cwd"
4316         rmdir . && error "'rmdir .' worked after recreating cwd"
4317         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4318         cd .. || error "'cd ..' failed after recreating cwd"
4319 }
4320 run_test 48a "Access renamed working dir (should return errors)="
4321
4322 test_48b() { # bug 2399
4323         rm -rf $DIR/$tdir
4324         test_mkdir $DIR/$tdir
4325         cd $DIR/$tdir
4326         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4327         touch foo && error "'touch foo' worked after removing cwd"
4328         mkdir foo && error "'mkdir foo' worked after removing cwd"
4329         touch .foo && error "'touch .foo' worked after removing cwd"
4330         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4331         ls . > /dev/null && error "'ls .' worked after removing cwd"
4332         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4333         mkdir . && error "'mkdir .' worked after removing cwd"
4334         rmdir . && error "'rmdir .' worked after removing cwd"
4335         ln -s . foo && error "'ln -s .' worked after removing cwd"
4336         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4337 }
4338 run_test 48b "Access removed working dir (should return errors)="
4339
4340 test_48c() { # bug 2350
4341         #lctl set_param debug=-1
4342         #set -vx
4343         rm -rf $DIR/$tdir
4344         test_mkdir -p $DIR/$tdir/dir
4345         cd $DIR/$tdir/dir
4346         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4347         $TRACE touch foo && error "touch foo worked after removing cwd"
4348         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4349         touch .foo && error "touch .foo worked after removing cwd"
4350         mkdir .foo && error "mkdir .foo worked after removing cwd"
4351         $TRACE ls . && error "'ls .' worked after removing cwd"
4352         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4353         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4354         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4355         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4356         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4357 }
4358 run_test 48c "Access removed working subdir (should return errors)"
4359
4360 test_48d() { # bug 2350
4361         #lctl set_param debug=-1
4362         #set -vx
4363         rm -rf $DIR/$tdir
4364         test_mkdir -p $DIR/$tdir/dir
4365         cd $DIR/$tdir/dir
4366         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4367         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4368         $TRACE touch foo && error "'touch foo' worked after removing parent"
4369         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4370         touch .foo && error "'touch .foo' worked after removing parent"
4371         mkdir .foo && error "mkdir .foo worked after removing parent"
4372         $TRACE ls . && error "'ls .' worked after removing parent"
4373         $TRACE ls .. && error "'ls ..' worked after removing parent"
4374         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4375         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4376         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4377         true
4378 }
4379 run_test 48d "Access removed parent subdir (should return errors)"
4380
4381 test_48e() { # bug 4134
4382         #lctl set_param debug=-1
4383         #set -vx
4384         rm -rf $DIR/$tdir
4385         test_mkdir -p $DIR/$tdir/dir
4386         cd $DIR/$tdir/dir
4387         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4388         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4389         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4390         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4391         # On a buggy kernel addition of "touch foo" after cd .. will
4392         # produce kernel oops in lookup_hash_it
4393         touch ../foo && error "'cd ..' worked after recreate parent"
4394         cd $DIR
4395         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4396 }
4397 run_test 48e "Access to recreated parent subdir (should return errors)"
4398
4399 test_49() { # LU-1030
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402
4403         # get ost1 size - lustre-OST0000
4404         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4405                 awk '{ print $4 }')
4406         # write 800M at maximum
4407         [[ $ost1_size -lt 2 ]] && ost1_size=2
4408         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4409
4410         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4411         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4412         local dd_pid=$!
4413
4414         # change max_pages_per_rpc while writing the file
4415         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4416         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4417         # loop until dd process exits
4418         while ps ax -opid | grep -wq $dd_pid; do
4419                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4420                 sleep $((RANDOM % 5 + 1))
4421         done
4422         # restore original max_pages_per_rpc
4423         $LCTL set_param $osc1_mppc=$orig_mppc
4424         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4425 }
4426 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4427
4428 test_50() {
4429         # bug 1485
4430         test_mkdir $DIR/$tdir
4431         cd $DIR/$tdir
4432         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4433 }
4434 run_test 50 "special situations: /proc symlinks  ==============="
4435
4436 test_51a() {    # was test_51
4437         # bug 1516 - create an empty entry right after ".." then split dir
4438         test_mkdir -c1 $DIR/$tdir
4439         touch $DIR/$tdir/foo
4440         $MCREATE $DIR/$tdir/bar
4441         rm $DIR/$tdir/foo
4442         createmany -m $DIR/$tdir/longfile 201
4443         FNUM=202
4444         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4445                 $MCREATE $DIR/$tdir/longfile$FNUM
4446                 FNUM=$(($FNUM + 1))
4447                 echo -n "+"
4448         done
4449         echo
4450         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4451 }
4452 run_test 51a "special situations: split htree with empty entry =="
4453
4454 cleanup_print_lfs_df () {
4455         trap 0
4456         $LFS df
4457         $LFS df -i
4458 }
4459
4460 test_51b() {
4461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4462
4463         local dir=$DIR/$tdir
4464         local nrdirs=$((65536 + 100))
4465
4466         # cleanup the directory
4467         rm -fr $dir
4468
4469         test_mkdir -c1 $dir
4470
4471         $LFS df
4472         $LFS df -i
4473         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4474         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4475         [[ $numfree -lt $nrdirs ]] &&
4476                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4477
4478         # need to check free space for the directories as well
4479         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4480         numfree=$(( blkfree / $(fs_inode_ksize) ))
4481         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4482
4483         trap cleanup_print_lfs_df EXIT
4484
4485         # create files
4486         createmany -d $dir/d $nrdirs || {
4487                 unlinkmany $dir/d $nrdirs
4488                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4489         }
4490
4491         # really created :
4492         nrdirs=$(ls -U $dir | wc -l)
4493
4494         # unlink all but 100 subdirectories, then check it still works
4495         local left=100
4496         local delete=$((nrdirs - left))
4497
4498         $LFS df
4499         $LFS df -i
4500
4501         # for ldiskfs the nlink count should be 1, but this is OSD specific
4502         # and so this is listed for informational purposes only
4503         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4504         unlinkmany -d $dir/d $delete ||
4505                 error "unlink of first $delete subdirs failed"
4506
4507         echo "nlink between: $(stat -c %h $dir)"
4508         local found=$(ls -U $dir | wc -l)
4509         [ $found -ne $left ] &&
4510                 error "can't find subdirs: found only $found, expected $left"
4511
4512         unlinkmany -d $dir/d $delete $left ||
4513                 error "unlink of second $left subdirs failed"
4514         # regardless of whether the backing filesystem tracks nlink accurately
4515         # or not, the nlink count shouldn't be more than "." and ".." here
4516         local after=$(stat -c %h $dir)
4517         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4518                 echo "nlink after: $after"
4519
4520         cleanup_print_lfs_df
4521 }
4522 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4523
4524 test_51d() {
4525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4526         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4527
4528         test_mkdir $DIR/$tdir
4529         createmany -o $DIR/$tdir/t- 1000
4530         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4531         for N in $(seq 0 $((OSTCOUNT - 1))); do
4532                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4533                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4534                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4535                         '($1 == '$N') { objs += 1 } \
4536                         END { printf("%0.0f", objs) }')
4537                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4538         done
4539         unlinkmany $DIR/$tdir/t- 1000
4540
4541         NLAST=0
4542         for N in $(seq 1 $((OSTCOUNT - 1))); do
4543                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4544                         error "OST $N has less objects vs OST $NLAST" \
4545                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4546                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4547                         error "OST $N has less objects vs OST $NLAST" \
4548                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4549
4550                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4551                         error "OST $N has less #0 objects vs OST $NLAST" \
4552                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4553                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4554                         error "OST $N has less #0 objects vs OST $NLAST" \
4555                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4556                 NLAST=$N
4557         done
4558         rm -f $TMP/$tfile
4559 }
4560 run_test 51d "check object distribution"
4561
4562 test_51e() {
4563         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4564                 skip_env "ldiskfs only test"
4565         fi
4566
4567         test_mkdir -c1 $DIR/$tdir
4568         test_mkdir -c1 $DIR/$tdir/d0
4569
4570         touch $DIR/$tdir/d0/foo
4571         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4572                 error "file exceed 65000 nlink limit!"
4573         unlinkmany $DIR/$tdir/d0/f- 65001
4574         return 0
4575 }
4576 run_test 51e "check file nlink limit"
4577
4578 test_51f() {
4579         test_mkdir $DIR/$tdir
4580
4581         local max=100000
4582         local ulimit_old=$(ulimit -n)
4583         local spare=20 # number of spare fd's for scripts/libraries, etc.
4584         local mdt=$($LFS getstripe -m $DIR/$tdir)
4585         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4586
4587         echo "MDT$mdt numfree=$numfree, max=$max"
4588         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4589         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4590                 while ! ulimit -n $((numfree + spare)); do
4591                         numfree=$((numfree * 3 / 4))
4592                 done
4593                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4594         else
4595                 echo "left ulimit at $ulimit_old"
4596         fi
4597
4598         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4599                 unlinkmany $DIR/$tdir/f $numfree
4600                 error "create+open $numfree files in $DIR/$tdir failed"
4601         }
4602         ulimit -n $ulimit_old
4603
4604         # if createmany exits at 120s there will be fewer than $numfree files
4605         unlinkmany $DIR/$tdir/f $numfree || true
4606 }
4607 run_test 51f "check many open files limit"
4608
4609 test_52a() {
4610         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4611         test_mkdir $DIR/$tdir
4612         touch $DIR/$tdir/foo
4613         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4614         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4615         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4616         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4617         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4618                                         error "link worked"
4619         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4620         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4621         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4622                                                      error "lsattr"
4623         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4624         cp -r $DIR/$tdir $TMP/
4625         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4626 }
4627 run_test 52a "append-only flag test (should return errors)"
4628
4629 test_52b() {
4630         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4631         test_mkdir $DIR/$tdir
4632         touch $DIR/$tdir/foo
4633         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4634         cat test > $DIR/$tdir/foo && error "cat test worked"
4635         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4636         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4637         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4638                                         error "link worked"
4639         echo foo >> $DIR/$tdir/foo && error "echo worked"
4640         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4641         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4642         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4643         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4644                                                         error "lsattr"
4645         chattr -i $DIR/$tdir/foo || error "chattr failed"
4646
4647         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4648 }
4649 run_test 52b "immutable flag test (should return errors) ======="
4650
4651 test_53() {
4652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4653         remote_mds_nodsh && skip "remote MDS with nodsh"
4654         remote_ost_nodsh && skip "remote OST with nodsh"
4655
4656         local param
4657         local param_seq
4658         local ostname
4659         local mds_last
4660         local mds_last_seq
4661         local ost_last
4662         local ost_last_seq
4663         local ost_last_id
4664         local ostnum
4665         local node
4666         local found=false
4667         local support_last_seq=true
4668
4669         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4670                 support_last_seq=false
4671
4672         # only test MDT0000
4673         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4674         local value
4675         for value in $(do_facet $SINGLEMDS \
4676                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4677                 param=$(echo ${value[0]} | cut -d "=" -f1)
4678                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4679
4680                 if $support_last_seq; then
4681                         param_seq=$(echo $param |
4682                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4683                         mds_last_seq=$(do_facet $SINGLEMDS \
4684                                        $LCTL get_param -n $param_seq)
4685                 fi
4686                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4687
4688                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4689                 node=$(facet_active_host ost$((ostnum+1)))
4690                 param="obdfilter.$ostname.last_id"
4691                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4692                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4693                         ost_last_id=$ost_last
4694
4695                         if $support_last_seq; then
4696                                 ost_last_id=$(echo $ost_last |
4697                                               awk -F':' '{print $2}' |
4698                                               sed -e "s/^0x//g")
4699                                 ost_last_seq=$(echo $ost_last |
4700                                                awk -F':' '{print $1}')
4701                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4702                         fi
4703
4704                         if [[ $ost_last_id != $mds_last ]]; then
4705                                 error "$ost_last_id != $mds_last"
4706                         else
4707                                 found=true
4708                                 break
4709                         fi
4710                 done
4711         done
4712         $found || error "can not match last_seq/last_id for $mdtosc"
4713         return 0
4714 }
4715 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4716
4717 test_54a() {
4718         perl -MSocket -e ';' || skip "no Socket perl module installed"
4719
4720         $SOCKETSERVER $DIR/socket ||
4721                 error "$SOCKETSERVER $DIR/socket failed: $?"
4722         $SOCKETCLIENT $DIR/socket ||
4723                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4724         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4725 }
4726 run_test 54a "unix domain socket test =========================="
4727
4728 test_54b() {
4729         f="$DIR/f54b"
4730         mknod $f c 1 3
4731         chmod 0666 $f
4732         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4733 }
4734 run_test 54b "char device works in lustre ======================"
4735
4736 find_loop_dev() {
4737         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4738         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4739         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4740
4741         for i in $(seq 3 7); do
4742                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4743                 LOOPDEV=$LOOPBASE$i
4744                 LOOPNUM=$i
4745                 break
4746         done
4747 }
4748
4749 cleanup_54c() {
4750         local rc=0
4751         loopdev="$DIR/loop54c"
4752
4753         trap 0
4754         $UMOUNT $DIR/$tdir || rc=$?
4755         losetup -d $loopdev || true
4756         losetup -d $LOOPDEV || true
4757         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4758         return $rc
4759 }
4760
4761 test_54c() {
4762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4763
4764         loopdev="$DIR/loop54c"
4765
4766         find_loop_dev
4767         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4768         trap cleanup_54c EXIT
4769         mknod $loopdev b 7 $LOOPNUM
4770         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4771         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4772         losetup $loopdev $DIR/$tfile ||
4773                 error "can't set up $loopdev for $DIR/$tfile"
4774         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4775         test_mkdir $DIR/$tdir
4776         mount -t ext2 $loopdev $DIR/$tdir ||
4777                 error "error mounting $loopdev on $DIR/$tdir"
4778         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4779                 error "dd write"
4780         df $DIR/$tdir
4781         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4782                 error "dd read"
4783         cleanup_54c
4784 }
4785 run_test 54c "block device works in lustre ====================="
4786
4787 test_54d() {
4788         f="$DIR/f54d"
4789         string="aaaaaa"
4790         mknod $f p
4791         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4792 }
4793 run_test 54d "fifo device works in lustre ======================"
4794
4795 test_54e() {
4796         f="$DIR/f54e"
4797         string="aaaaaa"
4798         cp -aL /dev/console $f
4799         echo $string > $f || error "echo $string to $f failed"
4800 }
4801 run_test 54e "console/tty device works in lustre ======================"
4802
4803 test_56a() {
4804         local numfiles=3
4805         local dir=$DIR/$tdir
4806
4807         rm -rf $dir
4808         test_mkdir -p $dir/dir
4809         for i in $(seq $numfiles); do
4810                 touch $dir/file$i
4811                 touch $dir/dir/file$i
4812         done
4813
4814         local numcomp=$($LFS getstripe --component-count $dir)
4815
4816         [[ $numcomp == 0 ]] && numcomp=1
4817
4818         # test lfs getstripe with --recursive
4819         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4820
4821         [[ $filenum -eq $((numfiles * 2)) ]] ||
4822                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4823         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4824         [[ $filenum -eq $numfiles ]] ||
4825                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4826         echo "$LFS getstripe showed obdidx or l_ost_idx"
4827
4828         # test lfs getstripe with file instead of dir
4829         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4830         [[ $filenum -eq 1 ]] ||
4831                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4832         echo "$LFS getstripe file1 passed"
4833
4834         #test lfs getstripe with --verbose
4835         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4836         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4837                 error "$LFS getstripe --verbose $dir: "\
4838                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4839         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4840                 error "$LFS getstripe $dir: showed lmm_magic"
4841
4842         #test lfs getstripe with -v prints lmm_fid
4843         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4844         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4845                 error "$LFS getstripe -v $dir: "\
4846                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4847         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4848                 error "$LFS getstripe $dir: showed lmm_fid by default"
4849         echo "$LFS getstripe --verbose passed"
4850
4851         #check for FID information
4852         local fid1=$($LFS getstripe --fid $dir/file1)
4853         local fid2=$($LFS getstripe --verbose $dir/file1 |
4854                      awk '/lmm_fid: / { print $2; exit; }')
4855         local fid3=$($LFS path2fid $dir/file1)
4856
4857         [ "$fid1" != "$fid2" ] &&
4858                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4859         [ "$fid1" != "$fid3" ] &&
4860                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4861         echo "$LFS getstripe --fid passed"
4862
4863         #test lfs getstripe with --obd
4864         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4865                 error "$LFS getstripe --obd wrong_uuid: should return error"
4866
4867         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4868
4869         local ostidx=1
4870         local obduuid=$(ostuuid_from_index $ostidx)
4871         local found=$($LFS getstripe -r --obd $obduuid $dir |
4872                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4873
4874         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4875         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4876                 ((filenum--))
4877         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4878                 ((filenum--))
4879
4880         [[ $found -eq $filenum ]] ||
4881                 error "$LFS getstripe --obd: found $found expect $filenum"
4882         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4883                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4884                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4885                 error "$LFS getstripe --obd: should not show file on other obd"
4886         echo "$LFS getstripe --obd passed"
4887 }
4888 run_test 56a "check $LFS getstripe"
4889
4890 test_56b() {
4891         local dir=$DIR/$tdir
4892         local numdirs=3
4893
4894         test_mkdir $dir
4895         for i in $(seq $numdirs); do
4896                 test_mkdir $dir/dir$i
4897         done
4898
4899         # test lfs getdirstripe default mode is non-recursion, which is
4900         # different from lfs getstripe
4901         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4902
4903         [[ $dircnt -eq 1 ]] ||
4904                 error "$LFS getdirstripe: found $dircnt, not 1"
4905         dircnt=$($LFS getdirstripe --recursive $dir |
4906                 grep -c lmv_stripe_count)
4907         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4908                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4909 }
4910 run_test 56b "check $LFS getdirstripe"
4911
4912 test_56c() {
4913         remote_ost_nodsh && skip "remote OST with nodsh"
4914
4915         local ost_idx=0
4916         local ost_name=$(ostname_from_index $ost_idx)
4917         local old_status=$(ost_dev_status $ost_idx)
4918
4919         [[ -z "$old_status" ]] ||
4920                 skip_env "OST $ost_name is in $old_status status"
4921
4922         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4923         sleep_maxage
4924
4925         local new_status=$(ost_dev_status $ost_idx)
4926
4927         [[ "$new_status" = "D" ]] ||
4928                 error "OST $ost_name is in status of '$new_status', not 'D'"
4929
4930         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4931         sleep_maxage
4932
4933         new_status=$(ost_dev_status $ost_idx)
4934         [[ -z "$new_status" ]] ||
4935                 error "OST $ost_name is in status of '$new_status', not ''"
4936 }
4937 run_test 56c "check 'lfs df' showing device status"
4938
4939 NUMFILES=3
4940 NUMDIRS=3
4941 setup_56() {
4942         local local_tdir="$1"
4943         local local_numfiles="$2"
4944         local local_numdirs="$3"
4945         local dir_params="$4"
4946         local dir_stripe_params="$5"
4947
4948         if [ ! -d "$local_tdir" ] ; then
4949                 test_mkdir -p $dir_stripe_params $local_tdir
4950                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4951                 for i in $(seq $local_numfiles) ; do
4952                         touch $local_tdir/file$i
4953                 done
4954                 for i in $(seq $local_numdirs) ; do
4955                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4956                         for j in $(seq $local_numfiles) ; do
4957                                 touch $local_tdir/dir$i/file$j
4958                         done
4959                 done
4960         fi
4961 }
4962
4963 setup_56_special() {
4964         local local_tdir=$1
4965         local local_numfiles=$2
4966         local local_numdirs=$3
4967
4968         setup_56 $local_tdir $local_numfiles $local_numdirs
4969
4970         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4971                 for i in $(seq $local_numfiles) ; do
4972                         mknod $local_tdir/loop${i}b b 7 $i
4973                         mknod $local_tdir/null${i}c c 1 3
4974                         ln -s $local_tdir/file1 $local_tdir/link${i}
4975                 done
4976                 for i in $(seq $local_numdirs) ; do
4977                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4978                         mknod $local_tdir/dir$i/null${i}c c 1 3
4979                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4980                 done
4981         fi
4982 }
4983
4984 test_56g() {
4985         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4986         local expected=$(($NUMDIRS + 2))
4987
4988         setup_56 $dir $NUMFILES $NUMDIRS
4989
4990         # test lfs find with -name
4991         for i in $(seq $NUMFILES) ; do
4992                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4993
4994                 [ $nums -eq $expected ] ||
4995                         error "lfs find -name '*$i' $dir wrong: "\
4996                               "found $nums, expected $expected"
4997         done
4998 }
4999 run_test 56g "check lfs find -name"
5000
5001 test_56h() {
5002         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5003         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5004
5005         setup_56 $dir $NUMFILES $NUMDIRS
5006
5007         # test lfs find with ! -name
5008         for i in $(seq $NUMFILES) ; do
5009                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5010
5011                 [ $nums -eq $expected ] ||
5012                         error "lfs find ! -name '*$i' $dir wrong: "\
5013                               "found $nums, expected $expected"
5014         done
5015 }
5016 run_test 56h "check lfs find ! -name"
5017
5018 test_56i() {
5019         local dir=$DIR/$tdir
5020
5021         test_mkdir $dir
5022
5023         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5024         local out=$($cmd)
5025
5026         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5027 }
5028 run_test 56i "check 'lfs find -ost UUID' skips directories"
5029
5030 test_56j() {
5031         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5032
5033         setup_56_special $dir $NUMFILES $NUMDIRS
5034
5035         local expected=$((NUMDIRS + 1))
5036         local cmd="$LFS find -type d $dir"
5037         local nums=$($cmd | wc -l)
5038
5039         [ $nums -eq $expected ] ||
5040                 error "'$cmd' wrong: found $nums, expected $expected"
5041 }
5042 run_test 56j "check lfs find -type d"
5043
5044 test_56k() {
5045         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5046
5047         setup_56_special $dir $NUMFILES $NUMDIRS
5048
5049         local expected=$(((NUMDIRS + 1) * NUMFILES))
5050         local cmd="$LFS find -type f $dir"
5051         local nums=$($cmd | wc -l)
5052
5053         [ $nums -eq $expected ] ||
5054                 error "'$cmd' wrong: found $nums, expected $expected"
5055 }
5056 run_test 56k "check lfs find -type f"
5057
5058 test_56l() {
5059         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5060
5061         setup_56_special $dir $NUMFILES $NUMDIRS
5062
5063         local expected=$((NUMDIRS + NUMFILES))
5064         local cmd="$LFS find -type b $dir"
5065         local nums=$($cmd | wc -l)
5066
5067         [ $nums -eq $expected ] ||
5068                 error "'$cmd' wrong: found $nums, expected $expected"
5069 }
5070 run_test 56l "check lfs find -type b"
5071
5072 test_56m() {
5073         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5074
5075         setup_56_special $dir $NUMFILES $NUMDIRS
5076
5077         local expected=$((NUMDIRS + NUMFILES))
5078         local cmd="$LFS find -type c $dir"
5079         local nums=$($cmd | wc -l)
5080         [ $nums -eq $expected ] ||
5081                 error "'$cmd' wrong: found $nums, expected $expected"
5082 }
5083 run_test 56m "check lfs find -type c"
5084
5085 test_56n() {
5086         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5087         setup_56_special $dir $NUMFILES $NUMDIRS
5088
5089         local expected=$((NUMDIRS + NUMFILES))
5090         local cmd="$LFS find -type l $dir"
5091         local nums=$($cmd | wc -l)
5092
5093         [ $nums -eq $expected ] ||
5094                 error "'$cmd' wrong: found $nums, expected $expected"
5095 }
5096 run_test 56n "check lfs find -type l"
5097
5098 test_56o() {
5099         local dir=$DIR/$tdir
5100
5101         setup_56 $dir $NUMFILES $NUMDIRS
5102         utime $dir/file1 > /dev/null || error "utime (1)"
5103         utime $dir/file2 > /dev/null || error "utime (2)"
5104         utime $dir/dir1 > /dev/null || error "utime (3)"
5105         utime $dir/dir2 > /dev/null || error "utime (4)"
5106         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5107         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5108
5109         local expected=4
5110         local nums=$($LFS find -mtime +0 $dir | wc -l)
5111
5112         [ $nums -eq $expected ] ||
5113                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5114
5115         expected=12
5116         cmd="$LFS find -mtime 0 $dir"
5117         nums=$($cmd | wc -l)
5118         [ $nums -eq $expected ] ||
5119                 error "'$cmd' wrong: found $nums, expected $expected"
5120 }
5121 run_test 56o "check lfs find -mtime for old files"
5122
5123 test_56ob() {
5124         local dir=$DIR/$tdir
5125         local expected=1
5126         local count=0
5127
5128         # just to make sure there is something that won't be found
5129         test_mkdir $dir
5130         touch $dir/$tfile.now
5131
5132         for age in year week day hour min; do
5133                 count=$((count + 1))
5134
5135                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5136                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5137                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5138
5139                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5140                 local nums=$($cmd | wc -l)
5141                 [ $nums -eq $expected ] ||
5142                         error "'$cmd' wrong: found $nums, expected $expected"
5143
5144                 cmd="$LFS find $dir -atime $count${age:0:1}"
5145                 nums=$($cmd | wc -l)
5146                 [ $nums -eq $expected ] ||
5147                         error "'$cmd' wrong: found $nums, expected $expected"
5148         done
5149
5150         sleep 2
5151         cmd="$LFS find $dir -ctime +1s -type f"
5152         nums=$($cmd | wc -l)
5153         (( $nums == $count * 2 + 1)) ||
5154                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5155 }
5156 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5157
5158 test_56p() {
5159         [ $RUNAS_ID -eq $UID ] &&
5160                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5161
5162         local dir=$DIR/$tdir
5163
5164         setup_56 $dir $NUMFILES $NUMDIRS
5165         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5166
5167         local expected=$NUMFILES
5168         local cmd="$LFS find -uid $RUNAS_ID $dir"
5169         local nums=$($cmd | wc -l)
5170
5171         [ $nums -eq $expected ] ||
5172                 error "'$cmd' wrong: found $nums, expected $expected"
5173
5174         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5175         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5176         nums=$($cmd | wc -l)
5177         [ $nums -eq $expected ] ||
5178                 error "'$cmd' wrong: found $nums, expected $expected"
5179 }
5180 run_test 56p "check lfs find -uid and ! -uid"
5181
5182 test_56q() {
5183         [ $RUNAS_ID -eq $UID ] &&
5184                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5185
5186         local dir=$DIR/$tdir
5187
5188         setup_56 $dir $NUMFILES $NUMDIRS
5189         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5190
5191         local expected=$NUMFILES
5192         local cmd="$LFS find -gid $RUNAS_GID $dir"
5193         local nums=$($cmd | wc -l)
5194
5195         [ $nums -eq $expected ] ||
5196                 error "'$cmd' wrong: found $nums, expected $expected"
5197
5198         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5199         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5200         nums=$($cmd | wc -l)
5201         [ $nums -eq $expected ] ||
5202                 error "'$cmd' wrong: found $nums, expected $expected"
5203 }
5204 run_test 56q "check lfs find -gid and ! -gid"
5205
5206 test_56r() {
5207         local dir=$DIR/$tdir
5208
5209         setup_56 $dir $NUMFILES $NUMDIRS
5210
5211         local expected=12
5212         local cmd="$LFS find -size 0 -type f -lazy $dir"
5213         local nums=$($cmd | wc -l)
5214
5215         [ $nums -eq $expected ] ||
5216                 error "'$cmd' wrong: found $nums, expected $expected"
5217         cmd="$LFS find -size 0 -type f $dir"
5218         nums=$($cmd | wc -l)
5219         [ $nums -eq $expected ] ||
5220                 error "'$cmd' wrong: found $nums, expected $expected"
5221
5222         expected=0
5223         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5224         nums=$($cmd | wc -l)
5225         [ $nums -eq $expected ] ||
5226                 error "'$cmd' wrong: found $nums, expected $expected"
5227         cmd="$LFS find ! -size 0 -type f $dir"
5228         nums=$($cmd | wc -l)
5229         [ $nums -eq $expected ] ||
5230                 error "'$cmd' wrong: found $nums, expected $expected"
5231
5232         echo "test" > $dir/$tfile
5233         echo "test2" > $dir/$tfile.2 && sync
5234         expected=1
5235         cmd="$LFS find -size 5 -type f -lazy $dir"
5236         nums=$($cmd | wc -l)
5237         [ $nums -eq $expected ] ||
5238                 error "'$cmd' wrong: found $nums, expected $expected"
5239         cmd="$LFS find -size 5 -type f $dir"
5240         nums=$($cmd | wc -l)
5241         [ $nums -eq $expected ] ||
5242                 error "'$cmd' wrong: found $nums, expected $expected"
5243
5244         expected=1
5245         cmd="$LFS find -size +5 -type f -lazy $dir"
5246         nums=$($cmd | wc -l)
5247         [ $nums -eq $expected ] ||
5248                 error "'$cmd' wrong: found $nums, expected $expected"
5249         cmd="$LFS find -size +5 -type f $dir"
5250         nums=$($cmd | wc -l)
5251         [ $nums -eq $expected ] ||
5252                 error "'$cmd' wrong: found $nums, expected $expected"
5253
5254         expected=2
5255         cmd="$LFS find -size +0 -type f -lazy $dir"
5256         nums=$($cmd | wc -l)
5257         [ $nums -eq $expected ] ||
5258                 error "'$cmd' wrong: found $nums, expected $expected"
5259         cmd="$LFS find -size +0 -type f $dir"
5260         nums=$($cmd | wc -l)
5261         [ $nums -eq $expected ] ||
5262                 error "'$cmd' wrong: found $nums, expected $expected"
5263
5264         expected=2
5265         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5266         nums=$($cmd | wc -l)
5267         [ $nums -eq $expected ] ||
5268                 error "'$cmd' wrong: found $nums, expected $expected"
5269         cmd="$LFS find ! -size -5 -type f $dir"
5270         nums=$($cmd | wc -l)
5271         [ $nums -eq $expected ] ||
5272                 error "'$cmd' wrong: found $nums, expected $expected"
5273
5274         expected=12
5275         cmd="$LFS find -size -5 -type f -lazy $dir"
5276         nums=$($cmd | wc -l)
5277         [ $nums -eq $expected ] ||
5278                 error "'$cmd' wrong: found $nums, expected $expected"
5279         cmd="$LFS find -size -5 -type f $dir"
5280         nums=$($cmd | wc -l)
5281         [ $nums -eq $expected ] ||
5282                 error "'$cmd' wrong: found $nums, expected $expected"
5283 }
5284 run_test 56r "check lfs find -size works"
5285
5286 test_56s() { # LU-611 #LU-9369
5287         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5288
5289         local dir=$DIR/$tdir
5290         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5291
5292         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5293         for i in $(seq $NUMDIRS); do
5294                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5295         done
5296
5297         local expected=$NUMDIRS
5298         local cmd="$LFS find -c $OSTCOUNT $dir"
5299         local nums=$($cmd | wc -l)
5300
5301         [ $nums -eq $expected ] || {
5302                 $LFS getstripe -R $dir
5303                 error "'$cmd' wrong: found $nums, expected $expected"
5304         }
5305
5306         expected=$((NUMDIRS + onestripe))
5307         cmd="$LFS find -stripe-count +0 -type f $dir"
5308         nums=$($cmd | wc -l)
5309         [ $nums -eq $expected ] || {
5310                 $LFS getstripe -R $dir
5311                 error "'$cmd' wrong: found $nums, expected $expected"
5312         }
5313
5314         expected=$onestripe
5315         cmd="$LFS find -stripe-count 1 -type f $dir"
5316         nums=$($cmd | wc -l)
5317         [ $nums -eq $expected ] || {
5318                 $LFS getstripe -R $dir
5319                 error "'$cmd' wrong: found $nums, expected $expected"
5320         }
5321
5322         cmd="$LFS find -stripe-count -2 -type f $dir"
5323         nums=$($cmd | wc -l)
5324         [ $nums -eq $expected ] || {
5325                 $LFS getstripe -R $dir
5326                 error "'$cmd' wrong: found $nums, expected $expected"
5327         }
5328
5329         expected=0
5330         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5331         nums=$($cmd | wc -l)
5332         [ $nums -eq $expected ] || {
5333                 $LFS getstripe -R $dir
5334                 error "'$cmd' wrong: found $nums, expected $expected"
5335         }
5336 }
5337 run_test 56s "check lfs find -stripe-count works"
5338
5339 test_56t() { # LU-611 #LU-9369
5340         local dir=$DIR/$tdir
5341
5342         setup_56 $dir 0 $NUMDIRS
5343         for i in $(seq $NUMDIRS); do
5344                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5345         done
5346
5347         local expected=$NUMDIRS
5348         local cmd="$LFS find -S 8M $dir"
5349         local nums=$($cmd | wc -l)
5350
5351         [ $nums -eq $expected ] || {
5352                 $LFS getstripe -R $dir
5353                 error "'$cmd' wrong: found $nums, expected $expected"
5354         }
5355         rm -rf $dir
5356
5357         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5358
5359         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5360
5361         expected=$(((NUMDIRS + 1) * NUMFILES))
5362         cmd="$LFS find -stripe-size 512k -type f $dir"
5363         nums=$($cmd | wc -l)
5364         [ $nums -eq $expected ] ||
5365                 error "'$cmd' wrong: found $nums, expected $expected"
5366
5367         cmd="$LFS find -stripe-size +320k -type f $dir"
5368         nums=$($cmd | wc -l)
5369         [ $nums -eq $expected ] ||
5370                 error "'$cmd' wrong: found $nums, expected $expected"
5371
5372         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5373         cmd="$LFS find -stripe-size +200k -type f $dir"
5374         nums=$($cmd | wc -l)
5375         [ $nums -eq $expected ] ||
5376                 error "'$cmd' wrong: found $nums, expected $expected"
5377
5378         cmd="$LFS find -stripe-size -640k -type f $dir"
5379         nums=$($cmd | wc -l)
5380         [ $nums -eq $expected ] ||
5381                 error "'$cmd' wrong: found $nums, expected $expected"
5382
5383         expected=4
5384         cmd="$LFS find -stripe-size 256k -type f $dir"
5385         nums=$($cmd | wc -l)
5386         [ $nums -eq $expected ] ||
5387                 error "'$cmd' wrong: found $nums, expected $expected"
5388
5389         cmd="$LFS find -stripe-size -320k -type f $dir"
5390         nums=$($cmd | wc -l)
5391         [ $nums -eq $expected ] ||
5392                 error "'$cmd' wrong: found $nums, expected $expected"
5393
5394         expected=0
5395         cmd="$LFS find -stripe-size 1024k -type f $dir"
5396         nums=$($cmd | wc -l)
5397         [ $nums -eq $expected ] ||
5398                 error "'$cmd' wrong: found $nums, expected $expected"
5399 }
5400 run_test 56t "check lfs find -stripe-size works"
5401
5402 test_56u() { # LU-611
5403         local dir=$DIR/$tdir
5404
5405         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5406
5407         if [[ $OSTCOUNT -gt 1 ]]; then
5408                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5409                 onestripe=4
5410         else
5411                 onestripe=0
5412         fi
5413
5414         local expected=$(((NUMDIRS + 1) * NUMFILES))
5415         local cmd="$LFS find -stripe-index 0 -type f $dir"
5416         local nums=$($cmd | wc -l)
5417
5418         [ $nums -eq $expected ] ||
5419                 error "'$cmd' wrong: found $nums, expected $expected"
5420
5421         expected=$onestripe
5422         cmd="$LFS find -stripe-index 1 -type f $dir"
5423         nums=$($cmd | wc -l)
5424         [ $nums -eq $expected ] ||
5425                 error "'$cmd' wrong: found $nums, expected $expected"
5426
5427         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5428         nums=$($cmd | wc -l)
5429         [ $nums -eq $expected ] ||
5430                 error "'$cmd' wrong: found $nums, expected $expected"
5431
5432         expected=0
5433         # This should produce an error and not return any files
5434         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5435         nums=$($cmd 2>/dev/null | wc -l)
5436         [ $nums -eq $expected ] ||
5437                 error "'$cmd' wrong: found $nums, expected $expected"
5438
5439         if [[ $OSTCOUNT -gt 1 ]]; then
5440                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5441                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5442                 nums=$($cmd | wc -l)
5443                 [ $nums -eq $expected ] ||
5444                         error "'$cmd' wrong: found $nums, expected $expected"
5445         fi
5446 }
5447 run_test 56u "check lfs find -stripe-index works"
5448
5449 test_56v() {
5450         local mdt_idx=0
5451         local dir=$DIR/$tdir
5452
5453         setup_56 $dir $NUMFILES $NUMDIRS
5454
5455         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5456         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5457
5458         for file in $($LFS find -m $UUID $dir); do
5459                 file_midx=$($LFS getstripe -m $file)
5460                 [ $file_midx -eq $mdt_idx ] ||
5461                         error "lfs find -m $UUID != getstripe -m $file_midx"
5462         done
5463 }
5464 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5465
5466 test_56w() {
5467         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5469
5470         local dir=$DIR/$tdir
5471
5472         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5473
5474         local stripe_size=$($LFS getstripe -S -d $dir) ||
5475                 error "$LFS getstripe -S -d $dir failed"
5476         stripe_size=${stripe_size%% *}
5477
5478         local file_size=$((stripe_size * OSTCOUNT))
5479         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5480         local required_space=$((file_num * file_size))
5481         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5482                            head -n1)
5483         [[ $free_space -le $((required_space / 1024)) ]] &&
5484                 skip_env "need $required_space, have $free_space kbytes"
5485
5486         local dd_bs=65536
5487         local dd_count=$((file_size / dd_bs))
5488
5489         # write data into the files
5490         local i
5491         local j
5492         local file
5493
5494         for i in $(seq $NUMFILES); do
5495                 file=$dir/file$i
5496                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5497                         error "write data into $file failed"
5498         done
5499         for i in $(seq $NUMDIRS); do
5500                 for j in $(seq $NUMFILES); do
5501                         file=$dir/dir$i/file$j
5502                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5503                                 error "write data into $file failed"
5504                 done
5505         done
5506
5507         # $LFS_MIGRATE will fail if hard link migration is unsupported
5508         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5509                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5510                         error "creating links to $dir/dir1/file1 failed"
5511         fi
5512
5513         local expected=-1
5514
5515         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5516
5517         # lfs_migrate file
5518         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5519
5520         echo "$cmd"
5521         eval $cmd || error "$cmd failed"
5522
5523         check_stripe_count $dir/file1 $expected
5524
5525         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5526         then
5527                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5528                 # OST 1 if it is on OST 0. This file is small enough to
5529                 # be on only one stripe.
5530                 file=$dir/migr_1_ost
5531                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5532                         error "write data into $file failed"
5533                 local obdidx=$($LFS getstripe -i $file)
5534                 local oldmd5=$(md5sum $file)
5535                 local newobdidx=0
5536
5537                 [[ $obdidx -eq 0 ]] && newobdidx=1
5538                 cmd="$LFS migrate -i $newobdidx $file"
5539                 echo $cmd
5540                 eval $cmd || error "$cmd failed"
5541
5542                 local realobdix=$($LFS getstripe -i $file)
5543                 local newmd5=$(md5sum $file)
5544
5545                 [[ $newobdidx -ne $realobdix ]] &&
5546                         error "new OST is different (was=$obdidx, "\
5547                               "wanted=$newobdidx, got=$realobdix)"
5548                 [[ "$oldmd5" != "$newmd5" ]] &&
5549                         error "md5sum differ: $oldmd5, $newmd5"
5550         fi
5551
5552         # lfs_migrate dir
5553         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5554         echo "$cmd"
5555         eval $cmd || error "$cmd failed"
5556
5557         for j in $(seq $NUMFILES); do
5558                 check_stripe_count $dir/dir1/file$j $expected
5559         done
5560
5561         # lfs_migrate works with lfs find
5562         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5563              $LFS_MIGRATE -y -c $expected"
5564         echo "$cmd"
5565         eval $cmd || error "$cmd failed"
5566
5567         for i in $(seq 2 $NUMFILES); do
5568                 check_stripe_count $dir/file$i $expected
5569         done
5570         for i in $(seq 2 $NUMDIRS); do
5571                 for j in $(seq $NUMFILES); do
5572                 check_stripe_count $dir/dir$i/file$j $expected
5573                 done
5574         done
5575 }
5576 run_test 56w "check lfs_migrate -c stripe_count works"
5577
5578 test_56wb() {
5579         local file1=$DIR/$tdir/file1
5580         local create_pool=false
5581         local initial_pool=$($LFS getstripe -p $DIR)
5582         local pool_list=()
5583         local pool=""
5584
5585         echo -n "Creating test dir..."
5586         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5587         echo "done."
5588
5589         echo -n "Creating test file..."
5590         touch $file1 || error "cannot create file"
5591         echo "done."
5592
5593         echo -n "Detecting existing pools..."
5594         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5595
5596         if [ ${#pool_list[@]} -gt 0 ]; then
5597                 echo "${pool_list[@]}"
5598                 for thispool in "${pool_list[@]}"; do
5599                         if [[ -z "$initial_pool" ||
5600                               "$initial_pool" != "$thispool" ]]; then
5601                                 pool="$thispool"
5602                                 echo "Using existing pool '$pool'"
5603                                 break
5604                         fi
5605                 done
5606         else
5607                 echo "none detected."
5608         fi
5609         if [ -z "$pool" ]; then
5610                 pool=${POOL:-testpool}
5611                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5612                 echo -n "Creating pool '$pool'..."
5613                 create_pool=true
5614                 pool_add $pool &> /dev/null ||
5615                         error "pool_add failed"
5616                 echo "done."
5617
5618                 echo -n "Adding target to pool..."
5619                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5620                         error "pool_add_targets failed"
5621                 echo "done."
5622         fi
5623
5624         echo -n "Setting pool using -p option..."
5625         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5626                 error "migrate failed rc = $?"
5627         echo "done."
5628
5629         echo -n "Verifying test file is in pool after migrating..."
5630         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5631                 error "file was not migrated to pool $pool"
5632         echo "done."
5633
5634         echo -n "Removing test file from pool '$pool'..."
5635         $LFS migrate $file1 &> /dev/null ||
5636                 error "cannot remove from pool"
5637         [ "$($LFS getstripe -p $file1)" ] &&
5638                 error "pool still set"
5639         echo "done."
5640
5641         echo -n "Setting pool using --pool option..."
5642         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5643                 error "migrate failed rc = $?"
5644         echo "done."
5645
5646         # Clean up
5647         rm -f $file1
5648         if $create_pool; then
5649                 destroy_test_pools 2> /dev/null ||
5650                         error "destroy test pools failed"
5651         fi
5652 }
5653 run_test 56wb "check lfs_migrate pool support"
5654
5655 test_56wc() {
5656         local file1="$DIR/$tdir/file1"
5657
5658         echo -n "Creating test dir..."
5659         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5660         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5661         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5662                 error "cannot set stripe"
5663         echo "done"
5664
5665         echo -n "Setting initial stripe for test file..."
5666         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5667                 error "cannot set stripe"
5668         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5669                 error "stripe size not set"
5670         echo "done."
5671
5672         # File currently set to -S 512K -c 1
5673
5674         # Ensure -c and -S options are rejected when -R is set
5675         echo -n "Verifying incompatible options are detected..."
5676         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5677                 error "incompatible -c and -R options not detected"
5678         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5679                 error "incompatible -S and -R options not detected"
5680         echo "done."
5681
5682         # Ensure unrecognized options are passed through to 'lfs migrate'
5683         echo -n "Verifying -S option is passed through to lfs migrate..."
5684         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5685                 error "migration failed"
5686         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5687                 error "file was not restriped"
5688         echo "done."
5689
5690         # File currently set to -S 1M -c 1
5691
5692         # Ensure long options are supported
5693         echo -n "Verifying long options supported..."
5694         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5695                 error "long option without argument not supported"
5696         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5697                 error "long option with argument not supported"
5698         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5699                 error "file not restriped with --stripe-size option"
5700         echo "done."
5701
5702         # File currently set to -S 512K -c 1
5703
5704         if [ "$OSTCOUNT" -gt 1 ]; then
5705                 echo -n "Verifying explicit stripe count can be set..."
5706                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5707                         error "migrate failed"
5708                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5709                         error "file not restriped to explicit count"
5710                 echo "done."
5711         fi
5712
5713         # File currently set to -S 512K -c 1 or -S 512K -c 2
5714
5715         # Ensure parent striping is used if -R is set, and no stripe
5716         # count or size is specified
5717         echo -n "Setting stripe for parent directory..."
5718         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5719                 error "cannot set stripe"
5720         echo "done."
5721
5722         echo -n "Verifying restripe option uses parent stripe settings..."
5723         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5724                 error "migrate failed"
5725         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5726                 error "file not restriped to parent settings"
5727         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5728                 error "file not restriped to parent settings"
5729         echo "done."
5730
5731         # File currently set to -S 1M -c 1
5732
5733         # Ensure striping is preserved if -R is not set, and no stripe
5734         # count or size is specified
5735         echo -n "Verifying striping size preserved when not specified..."
5736         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5737         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5738                 error "cannot set stripe on parent directory"
5739         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5740                 error "migrate failed"
5741         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5742                 error "file was restriped"
5743         echo "done."
5744
5745         # Ensure file name properly detected when final option has no argument
5746         echo -n "Verifying file name properly detected..."
5747         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5748                 error "file name interpreted as option argument"
5749         echo "done."
5750
5751         # Clean up
5752         rm -f "$file1"
5753 }
5754 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5755
5756 test_56wd() {
5757         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5758
5759         local file1=$DIR/$tdir/file1
5760
5761         echo -n "Creating test dir..."
5762         test_mkdir $DIR/$tdir || error "cannot create dir"
5763         echo "done."
5764
5765         echo -n "Creating test file..."
5766         touch $file1
5767         echo "done."
5768
5769         # Ensure 'lfs migrate' will fail by using a non-existent option,
5770         # and make sure rsync is not called to recover
5771         echo -n "Make sure --no-rsync option works..."
5772         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5773                 grep -q 'refusing to fall back to rsync' ||
5774                 error "rsync was called with --no-rsync set"
5775         echo "done."
5776
5777         # Ensure rsync is called without trying 'lfs migrate' first
5778         echo -n "Make sure --rsync option works..."
5779         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5780                 grep -q 'falling back to rsync' &&
5781                 error "lfs migrate was called with --rsync set"
5782         echo "done."
5783
5784         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5785         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5786                 grep -q 'at the same time' ||
5787                 error "--rsync and --no-rsync accepted concurrently"
5788         echo "done."
5789
5790         # Clean up
5791         rm -f $file1
5792 }
5793 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5794
5795 test_56x() {
5796         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5797         check_swap_layouts_support
5798
5799         local dir=$DIR/$tdir
5800         local ref1=/etc/passwd
5801         local file1=$dir/file1
5802
5803         test_mkdir $dir || error "creating dir $dir"
5804         $LFS setstripe -c 2 $file1
5805         cp $ref1 $file1
5806         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5807         stripe=$($LFS getstripe -c $file1)
5808         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5809         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5810
5811         # clean up
5812         rm -f $file1
5813 }
5814 run_test 56x "lfs migration support"
5815
5816 test_56xa() {
5817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5818         check_swap_layouts_support
5819
5820         local dir=$DIR/$tdir/$testnum
5821
5822         test_mkdir -p $dir
5823
5824         local ref1=/etc/passwd
5825         local file1=$dir/file1
5826
5827         $LFS setstripe -c 2 $file1
5828         cp $ref1 $file1
5829         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5830
5831         local stripe=$($LFS getstripe -c $file1)
5832
5833         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5834         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5835
5836         # clean up
5837         rm -f $file1
5838 }
5839 run_test 56xa "lfs migration --block support"
5840
5841 check_migrate_links() {
5842         local dir="$1"
5843         local file1="$dir/file1"
5844         local begin="$2"
5845         local count="$3"
5846         local total_count=$(($begin + $count - 1))
5847         local symlink_count=10
5848         local uniq_count=10
5849
5850         if [ ! -f "$file1" ]; then
5851                 echo -n "creating initial file..."
5852                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5853                         error "cannot setstripe initial file"
5854                 echo "done"
5855
5856                 echo -n "creating symlinks..."
5857                 for s in $(seq 1 $symlink_count); do
5858                         ln -s "$file1" "$dir/slink$s" ||
5859                                 error "cannot create symlinks"
5860                 done
5861                 echo "done"
5862
5863                 echo -n "creating nonlinked files..."
5864                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5865                         error "cannot create nonlinked files"
5866                 echo "done"
5867         fi
5868
5869         # create hard links
5870         if [ ! -f "$dir/file$total_count" ]; then
5871                 echo -n "creating hard links $begin:$total_count..."
5872                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5873                         /dev/null || error "cannot create hard links"
5874                 echo "done"
5875         fi
5876
5877         echo -n "checking number of hard links listed in xattrs..."
5878         local fid=$($LFS getstripe -F "$file1")
5879         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5880
5881         echo "${#paths[*]}"
5882         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5883                         skip "hard link list has unexpected size, skipping test"
5884         fi
5885         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5886                         error "link names should exceed xattrs size"
5887         fi
5888
5889         echo -n "migrating files..."
5890         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5891         local rc=$?
5892         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5893         echo "done"
5894
5895         # make sure all links have been properly migrated
5896         echo -n "verifying files..."
5897         fid=$($LFS getstripe -F "$file1") ||
5898                 error "cannot get fid for file $file1"
5899         for i in $(seq 2 $total_count); do
5900                 local fid2=$($LFS getstripe -F $dir/file$i)
5901
5902                 [ "$fid2" == "$fid" ] ||
5903                         error "migrated hard link has mismatched FID"
5904         done
5905
5906         # make sure hard links were properly detected, and migration was
5907         # performed only once for the entire link set; nonlinked files should
5908         # also be migrated
5909         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5910         local expected=$(($uniq_count + 1))
5911
5912         [ "$actual" -eq  "$expected" ] ||
5913                 error "hard links individually migrated ($actual != $expected)"
5914
5915         # make sure the correct number of hard links are present
5916         local hardlinks=$(stat -c '%h' "$file1")
5917
5918         [ $hardlinks -eq $total_count ] ||
5919                 error "num hard links $hardlinks != $total_count"
5920         echo "done"
5921
5922         return 0
5923 }
5924
5925 test_56xb() {
5926         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5927                 skip "Need MDS version at least 2.10.55"
5928
5929         local dir="$DIR/$tdir"
5930
5931         test_mkdir "$dir" || error "cannot create dir $dir"
5932
5933         echo "testing lfs migrate mode when all links fit within xattrs"
5934         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5935
5936         echo "testing rsync mode when all links fit within xattrs"
5937         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5938
5939         echo "testing lfs migrate mode when all links do not fit within xattrs"
5940         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5941
5942         echo "testing rsync mode when all links do not fit within xattrs"
5943         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5944
5945
5946         # clean up
5947         rm -rf $dir
5948 }
5949 run_test 56xb "lfs migration hard link support"
5950
5951 test_56xc() {
5952         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5953
5954         local dir="$DIR/$tdir"
5955
5956         test_mkdir "$dir" || error "cannot create dir $dir"
5957
5958         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5959         echo -n "Setting initial stripe for 20MB test file..."
5960         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5961         echo "done"
5962         echo -n "Sizing 20MB test file..."
5963         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5964         echo "done"
5965         echo -n "Verifying small file autostripe count is 1..."
5966         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5967                 error "cannot migrate 20MB file"
5968         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5969                 error "cannot get stripe for $dir/20mb"
5970         [ $stripe_count -eq 1 ] ||
5971                 error "unexpected stripe count $stripe_count for 20MB file"
5972         rm -f "$dir/20mb"
5973         echo "done"
5974
5975         # Test 2: File is small enough to fit within the available space on
5976         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5977         # have at least an additional 1KB for each desired stripe for test 3
5978         echo -n "Setting stripe for 1GB test file..."
5979         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5980         echo "done"
5981         echo -n "Sizing 1GB test file..."
5982         # File size is 1GB + 3KB
5983         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5984                 error "cannot create 1GB test file"
5985         echo "done"
5986         echo -n "Migrating 1GB file..."
5987         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5988                 error "cannot migrate file"
5989         echo "done"
5990         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5991         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5992                 error "cannot get stripe for $dir/1gb"
5993         [ $stripe_count -eq 2 ] ||
5994                 error "unexpected stripe count $stripe_count (expected 2)"
5995         echo "done"
5996
5997         # Test 3: File is too large to fit within the available space on
5998         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5999         if [ $OSTCOUNT -ge 3 ]; then
6000                 # The required available space is calculated as
6001                 # file size (1GB + 3KB) / OST count (3).
6002                 local kb_per_ost=349526
6003
6004                 echo -n "Migrating 1GB file..."
6005                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6006                         /dev/null || error "cannot migrate file"
6007                 echo "done"
6008
6009                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6010                 echo -n "Verifying autostripe count with limited space..."
6011                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6012                         error "unexpected stripe count $stripe_count (wanted 3)"
6013                 echo "done"
6014         fi
6015
6016         # clean up
6017         rm -rf $dir
6018 }
6019 run_test 56xc "lfs migration autostripe"
6020
6021 test_56y() {
6022         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6023                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6024
6025         local res=""
6026         local dir=$DIR/$tdir
6027         local f1=$dir/file1
6028         local f2=$dir/file2
6029
6030         test_mkdir -p $dir || error "creating dir $dir"
6031         touch $f1 || error "creating std file $f1"
6032         $MULTIOP $f2 H2c || error "creating released file $f2"
6033
6034         # a directory can be raid0, so ask only for files
6035         res=$($LFS find $dir -L raid0 -type f | wc -l)
6036         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6037
6038         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6039         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6040
6041         # only files can be released, so no need to force file search
6042         res=$($LFS find $dir -L released)
6043         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6044
6045         res=$($LFS find $dir -type f \! -L released)
6046         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6047 }
6048 run_test 56y "lfs find -L raid0|released"
6049
6050 test_56z() { # LU-4824
6051         # This checks to make sure 'lfs find' continues after errors
6052         # There are two classes of errors that should be caught:
6053         # - If multiple paths are provided, all should be searched even if one
6054         #   errors out
6055         # - If errors are encountered during the search, it should not terminate
6056         #   early
6057         local dir=$DIR/$tdir
6058         local i
6059
6060         test_mkdir $dir
6061         for i in d{0..9}; do
6062                 test_mkdir $dir/$i
6063         done
6064         touch $dir/d{0..9}/$tfile
6065         $LFS find $DIR/non_existent_dir $dir &&
6066                 error "$LFS find did not return an error"
6067         # Make a directory unsearchable. This should NOT be the last entry in
6068         # directory order.  Arbitrarily pick the 6th entry
6069         chmod 700 $($LFS find $dir -type d | sed '6!d')
6070
6071         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6072
6073         # The user should be able to see 10 directories and 9 files
6074         [ $count == 19 ] || error "$LFS find did not continue after error"
6075 }
6076 run_test 56z "lfs find should continue after an error"
6077
6078 test_56aa() { # LU-5937
6079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6080
6081         local dir=$DIR/$tdir
6082
6083         mkdir $dir
6084         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6085
6086         createmany -o $dir/striped_dir/${tfile}- 1024
6087         local dirs=$($LFS find --size +8k $dir/)
6088
6089         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6090 }
6091 run_test 56aa "lfs find --size under striped dir"
6092
6093 test_56ab() { # LU-10705
6094         test_mkdir $DIR/$tdir
6095         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6096         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6097         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6098         # Flush writes to ensure valid blocks.  Need to be more thorough for
6099         # ZFS, since blocks are not allocated/returned to client immediately.
6100         sync_all_data
6101         wait_zfs_commit ost1 2
6102         cancel_lru_locks osc
6103         ls -ls $DIR/$tdir
6104
6105         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6106
6107         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6108
6109         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6110         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6111
6112         rm -f $DIR/$tdir/$tfile.[123]
6113 }
6114 run_test 56ab "lfs find --blocks"
6115
6116 test_56ba() {
6117         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6118                 skip "Need MDS version at least 2.10.50"
6119
6120         # Create composite files with one component
6121         local dir=$DIR/$tdir
6122
6123         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6124         # Create composite files with three components
6125         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6126         # Create non-composite files
6127         createmany -o $dir/${tfile}- 10
6128
6129         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6130
6131         [[ $nfiles == 10 ]] ||
6132                 error "lfs find -E 1M found $nfiles != 10 files"
6133
6134         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6135         [[ $nfiles == 25 ]] ||
6136                 error "lfs find ! -E 1M found $nfiles != 25 files"
6137
6138         # All files have a component that starts at 0
6139         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6140         [[ $nfiles == 35 ]] ||
6141                 error "lfs find --component-start 0 - $nfiles != 35 files"
6142
6143         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6144         [[ $nfiles == 15 ]] ||
6145                 error "lfs find --component-start 2M - $nfiles != 15 files"
6146
6147         # All files created here have a componenet that does not starts at 2M
6148         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6149         [[ $nfiles == 35 ]] ||
6150                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6151
6152         # Find files with a specified number of components
6153         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6154         [[ $nfiles == 15 ]] ||
6155                 error "lfs find --component-count 3 - $nfiles != 15 files"
6156
6157         # Remember non-composite files have a component count of zero
6158         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6159         [[ $nfiles == 10 ]] ||
6160                 error "lfs find --component-count 0 - $nfiles != 10 files"
6161
6162         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6163         [[ $nfiles == 20 ]] ||
6164                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6165
6166         # All files have a flag called "init"
6167         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6168         [[ $nfiles == 35 ]] ||
6169                 error "lfs find --component-flags init - $nfiles != 35 files"
6170
6171         # Multi-component files will have a component not initialized
6172         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6173         [[ $nfiles == 15 ]] ||
6174                 error "lfs find !--component-flags init - $nfiles != 15 files"
6175
6176         rm -rf $dir
6177
6178 }
6179 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6180
6181 test_56ca() {
6182         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6183                 skip "Need MDS version at least 2.10.57"
6184
6185         local td=$DIR/$tdir
6186         local tf=$td/$tfile
6187         local dir
6188         local nfiles
6189         local cmd
6190         local i
6191         local j
6192
6193         # create mirrored directories and mirrored files
6194         mkdir $td || error "mkdir $td failed"
6195         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6196         createmany -o $tf- 10 || error "create $tf- failed"
6197
6198         for i in $(seq 2); do
6199                 dir=$td/dir$i
6200                 mkdir $dir || error "mkdir $dir failed"
6201                 $LFS mirror create -N$((3 + i)) $dir ||
6202                         error "create mirrored dir $dir failed"
6203                 createmany -o $dir/$tfile- 10 ||
6204                         error "create $dir/$tfile- failed"
6205         done
6206
6207         # change the states of some mirrored files
6208         echo foo > $tf-6
6209         for i in $(seq 2); do
6210                 dir=$td/dir$i
6211                 for j in $(seq 4 9); do
6212                         echo foo > $dir/$tfile-$j
6213                 done
6214         done
6215
6216         # find mirrored files with specific mirror count
6217         cmd="$LFS find --mirror-count 3 --type f $td"
6218         nfiles=$($cmd | wc -l)
6219         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6220
6221         cmd="$LFS find ! --mirror-count 3 --type f $td"
6222         nfiles=$($cmd | wc -l)
6223         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6224
6225         cmd="$LFS find --mirror-count +2 --type f $td"
6226         nfiles=$($cmd | wc -l)
6227         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6228
6229         cmd="$LFS find --mirror-count -6 --type f $td"
6230         nfiles=$($cmd | wc -l)
6231         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6232
6233         # find mirrored files with specific file state
6234         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6235         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6236
6237         cmd="$LFS find --mirror-state=ro --type f $td"
6238         nfiles=$($cmd | wc -l)
6239         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6240
6241         cmd="$LFS find ! --mirror-state=ro --type f $td"
6242         nfiles=$($cmd | wc -l)
6243         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6244
6245         cmd="$LFS find --mirror-state=wp --type f $td"
6246         nfiles=$($cmd | wc -l)
6247         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6248
6249         cmd="$LFS find ! --mirror-state=sp --type f $td"
6250         nfiles=$($cmd | wc -l)
6251         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6252 }
6253 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6254
6255 test_57a() {
6256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6257         # note test will not do anything if MDS is not local
6258         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6259                 skip_env "ldiskfs only test"
6260         fi
6261         remote_mds_nodsh && skip "remote MDS with nodsh"
6262
6263         local MNTDEV="osd*.*MDT*.mntdev"
6264         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6265         [ -z "$DEV" ] && error "can't access $MNTDEV"
6266         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6267                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6268                         error "can't access $DEV"
6269                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6270                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6271                 rm $TMP/t57a.dump
6272         done
6273 }
6274 run_test 57a "verify MDS filesystem created with large inodes =="
6275
6276 test_57b() {
6277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6278         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6279                 skip_env "ldiskfs only test"
6280         fi
6281         remote_mds_nodsh && skip "remote MDS with nodsh"
6282
6283         local dir=$DIR/$tdir
6284         local filecount=100
6285         local file1=$dir/f1
6286         local fileN=$dir/f$filecount
6287
6288         rm -rf $dir || error "removing $dir"
6289         test_mkdir -c1 $dir
6290         local mdtidx=$($LFS getstripe -m $dir)
6291         local mdtname=MDT$(printf %04x $mdtidx)
6292         local facet=mds$((mdtidx + 1))
6293
6294         echo "mcreating $filecount files"
6295         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6296
6297         # verify that files do not have EAs yet
6298         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6299                 error "$file1 has an EA"
6300         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6301                 error "$fileN has an EA"
6302
6303         sync
6304         sleep 1
6305         df $dir  #make sure we get new statfs data
6306         local mdsfree=$(do_facet $facet \
6307                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6308         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6309         local file
6310
6311         echo "opening files to create objects/EAs"
6312         for file in $(seq -f $dir/f%g 1 $filecount); do
6313                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6314                         error "opening $file"
6315         done
6316
6317         # verify that files have EAs now
6318         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6319         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6320
6321         sleep 1  #make sure we get new statfs data
6322         df $dir
6323         local mdsfree2=$(do_facet $facet \
6324                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6325         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6326
6327         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6328                 if [ "$mdsfree" != "$mdsfree2" ]; then
6329                         error "MDC before $mdcfree != after $mdcfree2"
6330                 else
6331                         echo "MDC before $mdcfree != after $mdcfree2"
6332                         echo "unable to confirm if MDS has large inodes"
6333                 fi
6334         fi
6335         rm -rf $dir
6336 }
6337 run_test 57b "default LOV EAs are stored inside large inodes ==="
6338
6339 test_58() {
6340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6341         [ -z "$(which wiretest 2>/dev/null)" ] &&
6342                         skip_env "could not find wiretest"
6343
6344         wiretest
6345 }
6346 run_test 58 "verify cross-platform wire constants =============="
6347
6348 test_59() {
6349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6350
6351         echo "touch 130 files"
6352         createmany -o $DIR/f59- 130
6353         echo "rm 130 files"
6354         unlinkmany $DIR/f59- 130
6355         sync
6356         # wait for commitment of removal
6357         wait_delete_completed
6358 }
6359 run_test 59 "verify cancellation of llog records async ========="
6360
6361 TEST60_HEAD="test_60 run $RANDOM"
6362 test_60a() {
6363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6364         remote_mgs_nodsh && skip "remote MGS with nodsh"
6365         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6366                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6367                         skip_env "missing subtest run-llog.sh"
6368
6369         log "$TEST60_HEAD - from kernel mode"
6370         do_facet mgs "$LCTL dk > /dev/null"
6371         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6372         do_facet mgs $LCTL dk > $TMP/$tfile
6373
6374         # LU-6388: test llog_reader
6375         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6376         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6377         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6378                         skip_env "missing llog_reader"
6379         local fstype=$(facet_fstype mgs)
6380         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6381                 skip_env "Only for ldiskfs or zfs type mgs"
6382
6383         local mntpt=$(facet_mntpt mgs)
6384         local mgsdev=$(mgsdevname 1)
6385         local fid_list
6386         local fid
6387         local rec_list
6388         local rec
6389         local rec_type
6390         local obj_file
6391         local path
6392         local seq
6393         local oid
6394         local pass=true
6395
6396         #get fid and record list
6397         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6398                 tail -n 4))
6399         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6400                 tail -n 4))
6401         #remount mgs as ldiskfs or zfs type
6402         stop mgs || error "stop mgs failed"
6403         mount_fstype mgs || error "remount mgs failed"
6404         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6405                 fid=${fid_list[i]}
6406                 rec=${rec_list[i]}
6407                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6408                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6409                 oid=$((16#$oid))
6410
6411                 case $fstype in
6412                         ldiskfs )
6413                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6414                         zfs )
6415                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6416                 esac
6417                 echo "obj_file is $obj_file"
6418                 do_facet mgs $llog_reader $obj_file
6419
6420                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6421                         awk '{ print $3 }' | sed -e "s/^type=//g")
6422                 if [ $rec_type != $rec ]; then
6423                         echo "FAILED test_60a wrong record type $rec_type," \
6424                               "should be $rec"
6425                         pass=false
6426                         break
6427                 fi
6428
6429                 #check obj path if record type is LLOG_LOGID_MAGIC
6430                 if [ "$rec" == "1064553b" ]; then
6431                         path=$(do_facet mgs $llog_reader $obj_file |
6432                                 grep "path=" | awk '{ print $NF }' |
6433                                 sed -e "s/^path=//g")
6434                         if [ $obj_file != $mntpt/$path ]; then
6435                                 echo "FAILED test_60a wrong obj path" \
6436                                       "$montpt/$path, should be $obj_file"
6437                                 pass=false
6438                                 break
6439                         fi
6440                 fi
6441         done
6442         rm -f $TMP/$tfile
6443         #restart mgs before "error", otherwise it will block the next test
6444         stop mgs || error "stop mgs failed"
6445         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6446         $pass || error "test failed, see FAILED test_60a messages for specifics"
6447 }
6448 run_test 60a "llog_test run from kernel module and test llog_reader"
6449
6450 test_60b() { # bug 6411
6451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6452
6453         dmesg > $DIR/$tfile
6454         LLOG_COUNT=$(do_facet mgs dmesg |
6455                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6456                           /llog_[a-z]*.c:[0-9]/ {
6457                                 if (marker)
6458                                         from_marker++
6459                                 from_begin++
6460                           }
6461                           END {
6462                                 if (marker)
6463                                         print from_marker
6464                                 else
6465                                         print from_begin
6466                           }")
6467
6468         [[ $LLOG_COUNT -gt 120 ]] &&
6469                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6470 }
6471 run_test 60b "limit repeated messages from CERROR/CWARN"
6472
6473 test_60c() {
6474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6475
6476         echo "create 5000 files"
6477         createmany -o $DIR/f60c- 5000
6478 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6479         lctl set_param fail_loc=0x80000137
6480         unlinkmany $DIR/f60c- 5000
6481         lctl set_param fail_loc=0
6482 }
6483 run_test 60c "unlink file when mds full"
6484
6485 test_60d() {
6486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6487
6488         SAVEPRINTK=$(lctl get_param -n printk)
6489         # verify "lctl mark" is even working"
6490         MESSAGE="test message ID $RANDOM $$"
6491         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6492         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6493
6494         lctl set_param printk=0 || error "set lnet.printk failed"
6495         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6496         MESSAGE="new test message ID $RANDOM $$"
6497         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6498         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6499         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6500
6501         lctl set_param -n printk="$SAVEPRINTK"
6502 }
6503 run_test 60d "test printk console message masking"
6504
6505 test_60e() {
6506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6507         remote_mds_nodsh && skip "remote MDS with nodsh"
6508
6509         touch $DIR/$tfile
6510 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6511         do_facet mds1 lctl set_param fail_loc=0x15b
6512         rm $DIR/$tfile
6513 }
6514 run_test 60e "no space while new llog is being created"
6515
6516 test_60g() {
6517         local pid
6518
6519         test_mkdir -c $MDSCOUNT $DIR/$tdir
6520         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6521
6522         (
6523                 local index=0
6524                 while true; do
6525                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6526                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6527                         index=$((index + 1))
6528                 done
6529         ) &
6530
6531         pid=$!
6532
6533         for i in $(seq 100); do 
6534                 # define OBD_FAIL_OSD_TXN_START    0x19a
6535                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6536                 usleep 100
6537         done
6538
6539         kill -9 $pid
6540
6541         mkdir $DIR/$tdir/new || error "mkdir failed"
6542         rmdir $DIR/$tdir/new || error "rmdir failed"
6543 }
6544 run_test 60g "transaction abort won't cause MDT hung"
6545
6546 test_61a() {
6547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6548
6549         f="$DIR/f61"
6550         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6551         cancel_lru_locks osc
6552         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6553         sync
6554 }
6555 run_test 61a "mmap() writes don't make sync hang ================"
6556
6557 test_61b() {
6558         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6559 }
6560 run_test 61b "mmap() of unstriped file is successful"
6561
6562 # bug 2330 - insufficient obd_match error checking causes LBUG
6563 test_62() {
6564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6565
6566         f="$DIR/f62"
6567         echo foo > $f
6568         cancel_lru_locks osc
6569         lctl set_param fail_loc=0x405
6570         cat $f && error "cat succeeded, expect -EIO"
6571         lctl set_param fail_loc=0
6572 }
6573 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6574 # match every page all of the time.
6575 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6576
6577 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6578 # Though this test is irrelevant anymore, it helped to reveal some
6579 # other grant bugs (LU-4482), let's keep it.
6580 test_63a() {   # was test_63
6581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6582
6583         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6584
6585         for i in `seq 10` ; do
6586                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6587                 sleep 5
6588                 kill $!
6589                 sleep 1
6590         done
6591
6592         rm -f $DIR/f63 || true
6593 }
6594 run_test 63a "Verify oig_wait interruption does not crash ======="
6595
6596 # bug 2248 - async write errors didn't return to application on sync
6597 # bug 3677 - async write errors left page locked
6598 test_63b() {
6599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6600
6601         debugsave
6602         lctl set_param debug=-1
6603
6604         # ensure we have a grant to do async writes
6605         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6606         rm $DIR/$tfile
6607
6608         sync    # sync lest earlier test intercept the fail_loc
6609
6610         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6611         lctl set_param fail_loc=0x80000406
6612         $MULTIOP $DIR/$tfile Owy && \
6613                 error "sync didn't return ENOMEM"
6614         sync; sleep 2; sync     # do a real sync this time to flush page
6615         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6616                 error "locked page left in cache after async error" || true
6617         debugrestore
6618 }
6619 run_test 63b "async write errors should be returned to fsync ==="
6620
6621 test_64a () {
6622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6623
6624         df $DIR
6625         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6626 }
6627 run_test 64a "verify filter grant calculations (in kernel) ====="
6628
6629 test_64b () {
6630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6631
6632         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6633 }
6634 run_test 64b "check out-of-space detection on client"
6635
6636 test_64c() {
6637         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6638 }
6639 run_test 64c "verify grant shrink"
6640
6641 # this does exactly what osc_request.c:osc_announce_cached() does in
6642 # order to calculate max amount of grants to ask from server
6643 want_grant() {
6644         local tgt=$1
6645
6646         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6647         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6648
6649         ((rpc_in_flight ++));
6650         nrpages=$((nrpages * rpc_in_flight))
6651
6652         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6653
6654         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6655
6656         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6657         local undirty=$((nrpages * PAGE_SIZE))
6658
6659         local max_extent_pages
6660         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6661             grep grant_max_extent_size | awk '{print $2}')
6662         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6663         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6664         local grant_extent_tax
6665         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6666             grep grant_extent_tax | awk '{print $2}')
6667
6668         undirty=$((undirty + nrextents * grant_extent_tax))
6669
6670         echo $undirty
6671 }
6672
6673 # this is size of unit for grant allocation. It should be equal to
6674 # what tgt_grant.c:tgt_grant_chunk() calculates
6675 grant_chunk() {
6676         local tgt=$1
6677         local max_brw_size
6678         local grant_extent_tax
6679
6680         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6681             grep max_brw_size | awk '{print $2}')
6682
6683         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6684             grep grant_extent_tax | awk '{print $2}')
6685
6686         echo $(((max_brw_size + grant_extent_tax) * 2))
6687 }
6688
6689 test_64d() {
6690         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6691                 skip "OST < 2.10.55 doesn't limit grants enough"
6692
6693         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6694         local file=$DIR/$tfile
6695
6696         [[ $($LCTL get_param osc.${tgt}.import |
6697              grep "connect_flags:.*grant_param") ]] ||
6698                 skip "no grant_param connect flag"
6699
6700         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6701
6702         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6703
6704         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6705         stack_trap "rm -f $file" EXIT
6706
6707         $LFS setstripe $file -i 0 -c 1
6708         dd if=/dev/zero of=$file bs=1M count=1000 &
6709         ddpid=$!
6710
6711         while true
6712         do
6713                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6714                 if [[ $cur_grant -gt $max_cur_granted ]]
6715                 then
6716                         kill $ddpid
6717                         error "cur_grant $cur_grant > $max_cur_granted"
6718                 fi
6719                 kill -0 $ddpid
6720                 [[ $? -ne 0 ]] && break;
6721                 sleep 2
6722         done
6723
6724         rm -f $DIR/$tfile
6725         wait_delete_completed
6726         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6727 }
6728 run_test 64d "check grant limit exceed"
6729
6730 # bug 1414 - set/get directories' stripe info
6731 test_65a() {
6732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6733
6734         test_mkdir $DIR/$tdir
6735         touch $DIR/$tdir/f1
6736         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6737 }
6738 run_test 65a "directory with no stripe info"
6739
6740 test_65b() {
6741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6742
6743         test_mkdir $DIR/$tdir
6744         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6745
6746         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6747                                                 error "setstripe"
6748         touch $DIR/$tdir/f2
6749         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6750 }
6751 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6752
6753 test_65c() {
6754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6755         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6756
6757         test_mkdir $DIR/$tdir
6758         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6759
6760         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6761                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6762         touch $DIR/$tdir/f3
6763         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6764 }
6765 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6766
6767 test_65d() {
6768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6769
6770         test_mkdir $DIR/$tdir
6771         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6772         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6773
6774         if [[ $STRIPECOUNT -le 0 ]]; then
6775                 sc=1
6776         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6777 #LOV_MAX_STRIPE_COUNT is 2000
6778                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6779         else
6780                 sc=$(($STRIPECOUNT - 1))
6781         fi
6782         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6783         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6784         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6785                 error "lverify failed"
6786 }
6787 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6788
6789 test_65e() {
6790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6791
6792         test_mkdir $DIR/$tdir
6793
6794         $LFS setstripe $DIR/$tdir || error "setstripe"
6795         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6796                                         error "no stripe info failed"
6797         touch $DIR/$tdir/f6
6798         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6799 }
6800 run_test 65e "directory setstripe defaults"
6801
6802 test_65f() {
6803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6804
6805         test_mkdir $DIR/${tdir}f
6806         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6807                 error "setstripe succeeded" || true
6808 }
6809 run_test 65f "dir setstripe permission (should return error) ==="
6810
6811 test_65g() {
6812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6813
6814         test_mkdir $DIR/$tdir
6815         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6816
6817         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6818                 error "setstripe -S failed"
6819         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6820         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6821                 error "delete default stripe failed"
6822 }
6823 run_test 65g "directory setstripe -d"
6824
6825 test_65h() {
6826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6827
6828         test_mkdir $DIR/$tdir
6829         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6830
6831         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6832                 error "setstripe -S failed"
6833         test_mkdir $DIR/$tdir/dd1
6834         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6835                 error "stripe info inherit failed"
6836 }
6837 run_test 65h "directory stripe info inherit ===================="
6838
6839 test_65i() {
6840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6841
6842         save_layout_restore_at_exit $MOUNT
6843
6844         # bug6367: set non-default striping on root directory
6845         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6846
6847         # bug12836: getstripe on -1 default directory striping
6848         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6849
6850         # bug12836: getstripe -v on -1 default directory striping
6851         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6852
6853         # bug12836: new find on -1 default directory striping
6854         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6855 }
6856 run_test 65i "various tests to set root directory striping"
6857
6858 test_65j() { # bug6367
6859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6860
6861         sync; sleep 1
6862
6863         # if we aren't already remounting for each test, do so for this test
6864         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6865                 cleanup || error "failed to unmount"
6866                 setup
6867         fi
6868
6869         save_layout_restore_at_exit $MOUNT
6870
6871         $LFS setstripe -d $MOUNT || error "setstripe failed"
6872 }
6873 run_test 65j "set default striping on root directory (bug 6367)="
6874
6875 cleanup_65k() {
6876         rm -rf $DIR/$tdir
6877         wait_delete_completed
6878         do_facet $SINGLEMDS "lctl set_param -n \
6879                 osp.$ost*MDT0000.max_create_count=$max_count"
6880         do_facet $SINGLEMDS "lctl set_param -n \
6881                 osp.$ost*MDT0000.create_count=$count"
6882         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6883         echo $INACTIVE_OSC "is Activate"
6884
6885         wait_osc_import_state mds ost$ostnum FULL
6886 }
6887
6888 test_65k() { # bug11679
6889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6891         remote_mds_nodsh && skip "remote MDS with nodsh"
6892
6893         local disable_precreate=true
6894         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6895                 disable_precreate=false
6896
6897         echo "Check OST status: "
6898         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6899                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6900
6901         for OSC in $MDS_OSCS; do
6902                 echo $OSC "is active"
6903                 do_facet $SINGLEMDS lctl --device %$OSC activate
6904         done
6905
6906         for INACTIVE_OSC in $MDS_OSCS; do
6907                 local ost=$(osc_to_ost $INACTIVE_OSC)
6908                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6909                                lov.*md*.target_obd |
6910                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6911
6912                 mkdir -p $DIR/$tdir
6913                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6914                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6915
6916                 echo "Deactivate: " $INACTIVE_OSC
6917                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6918
6919                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6920                               osp.$ost*MDT0000.create_count")
6921                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6922                                   osp.$ost*MDT0000.max_create_count")
6923                 $disable_precreate &&
6924                         do_facet $SINGLEMDS "lctl set_param -n \
6925                                 osp.$ost*MDT0000.max_create_count=0"
6926
6927                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6928                         [ -f $DIR/$tdir/$idx ] && continue
6929                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6930                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6931                                 { cleanup_65k;
6932                                   error "setstripe $idx should succeed"; }
6933                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6934                 done
6935                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6936                 rmdir $DIR/$tdir
6937
6938                 do_facet $SINGLEMDS "lctl set_param -n \
6939                         osp.$ost*MDT0000.max_create_count=$max_count"
6940                 do_facet $SINGLEMDS "lctl set_param -n \
6941                         osp.$ost*MDT0000.create_count=$count"
6942                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6943                 echo $INACTIVE_OSC "is Activate"
6944
6945                 wait_osc_import_state mds ost$ostnum FULL
6946         done
6947 }
6948 run_test 65k "validate manual striping works properly with deactivated OSCs"
6949
6950 test_65l() { # bug 12836
6951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6952
6953         test_mkdir -p $DIR/$tdir/test_dir
6954         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6955         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6956 }
6957 run_test 65l "lfs find on -1 stripe dir ========================"
6958
6959 test_65m() {
6960         local layout=$(save_layout $MOUNT)
6961         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6962                 restore_layout $MOUNT $layout
6963                 error "setstripe should fail by non-root users"
6964         }
6965         true
6966 }
6967 run_test 65m "normal user can't set filesystem default stripe"
6968
6969 test_65n() {
6970         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6971         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6972                 skip "Need MDS version at least 2.12.50"
6973         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6974
6975         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6976         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6977         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6978
6979         local root_layout=$(save_layout $MOUNT)
6980         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6981
6982         # new subdirectory under root directory should not inherit
6983         # the default layout from root
6984         local dir1=$MOUNT/$tdir-1
6985         mkdir $dir1 || error "mkdir $dir1 failed"
6986         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6987                 error "$dir1 shouldn't have LOV EA"
6988
6989         # delete the default layout on root directory
6990         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6991
6992         local dir2=$MOUNT/$tdir-2
6993         mkdir $dir2 || error "mkdir $dir2 failed"
6994         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6995                 error "$dir2 shouldn't have LOV EA"
6996
6997         # set a new striping pattern on root directory
6998         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6999         local new_def_stripe_size=$((def_stripe_size * 2))
7000         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7001                 error "set stripe size on $MOUNT failed"
7002
7003         # new file created in $dir2 should inherit the new stripe size from
7004         # the filesystem default
7005         local file2=$dir2/$tfile-2
7006         touch $file2 || error "touch $file2 failed"
7007
7008         local file2_stripe_size=$($LFS getstripe -S $file2)
7009         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7010                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7011
7012         local dir3=$MOUNT/$tdir-3
7013         mkdir $dir3 || error "mkdir $dir3 failed"
7014         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7015                 error "$dir3 shouldn't have LOV EA"
7016
7017         # set OST pool on root directory
7018         local pool=$TESTNAME
7019         pool_add $pool || error "add $pool failed"
7020         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7021                 error "add targets to $pool failed"
7022
7023         $LFS setstripe -p $pool $MOUNT ||
7024                 error "set OST pool on $MOUNT failed"
7025
7026         # new file created in $dir3 should inherit the pool from
7027         # the filesystem default
7028         local file3=$dir3/$tfile-3
7029         touch $file3 || error "touch $file3 failed"
7030
7031         local file3_pool=$($LFS getstripe -p $file3)
7032         [[ "$file3_pool" = "$pool" ]] ||
7033                 error "$file3 didn't inherit OST pool $pool"
7034
7035         local dir4=$MOUNT/$tdir-4
7036         mkdir $dir4 || error "mkdir $dir4 failed"
7037         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7038                 error "$dir4 shouldn't have LOV EA"
7039
7040         # new file created in $dir4 should inherit the pool from
7041         # the filesystem default
7042         local file4=$dir4/$tfile-4
7043         touch $file4 || error "touch $file4 failed"
7044
7045         local file4_pool=$($LFS getstripe -p $file4)
7046         [[ "$file4_pool" = "$pool" ]] ||
7047                 error "$file4 didn't inherit OST pool $pool"
7048
7049         # new subdirectory under non-root directory should inherit
7050         # the default layout from its parent directory
7051         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7052                 error "set directory layout on $dir4 failed"
7053
7054         local dir5=$dir4/$tdir-5
7055         mkdir $dir5 || error "mkdir $dir5 failed"
7056
7057         local dir4_layout=$(get_layout_param $dir4)
7058         local dir5_layout=$(get_layout_param $dir5)
7059         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7060                 error "$dir5 should inherit the default layout from $dir4"
7061 }
7062 run_test 65n "don't inherit default layout from root for new subdirectories"
7063
7064 # bug 2543 - update blocks count on client
7065 test_66() {
7066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7067
7068         COUNT=${COUNT:-8}
7069         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7070         sync; sync_all_data; sync; sync_all_data
7071         cancel_lru_locks osc
7072         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7073         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7074 }
7075 run_test 66 "update inode blocks count on client ==============="
7076
7077 meminfo() {
7078         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7079 }
7080
7081 swap_used() {
7082         swapon -s | awk '($1 == "'$1'") { print $4 }'
7083 }
7084
7085 # bug5265, obdfilter oa2dentry return -ENOENT
7086 # #define OBD_FAIL_SRV_ENOENT 0x217
7087 test_69() {
7088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7089         remote_ost_nodsh && skip "remote OST with nodsh"
7090
7091         f="$DIR/$tfile"
7092         $LFS setstripe -c 1 -i 0 $f
7093
7094         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7095
7096         do_facet ost1 lctl set_param fail_loc=0x217
7097         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7098         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7099
7100         do_facet ost1 lctl set_param fail_loc=0
7101         $DIRECTIO write $f 0 2 || error "write error"
7102
7103         cancel_lru_locks osc
7104         $DIRECTIO read $f 0 1 || error "read error"
7105
7106         do_facet ost1 lctl set_param fail_loc=0x217
7107         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7108
7109         do_facet ost1 lctl set_param fail_loc=0
7110         rm -f $f
7111 }
7112 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7113
7114 test_71() {
7115         test_mkdir $DIR/$tdir
7116         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7117         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7118 }
7119 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7120
7121 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7123         [ "$RUNAS_ID" = "$UID" ] &&
7124                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7125         # Check that testing environment is properly set up. Skip if not
7126         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7127                 skip_env "User $RUNAS_ID does not exist - skipping"
7128
7129         touch $DIR/$tfile
7130         chmod 777 $DIR/$tfile
7131         chmod ug+s $DIR/$tfile
7132         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7133                 error "$RUNAS dd $DIR/$tfile failed"
7134         # See if we are still setuid/sgid
7135         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7136                 error "S/gid is not dropped on write"
7137         # Now test that MDS is updated too
7138         cancel_lru_locks mdc
7139         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7140                 error "S/gid is not dropped on MDS"
7141         rm -f $DIR/$tfile
7142 }
7143 run_test 72a "Test that remove suid works properly (bug5695) ===="
7144
7145 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7146         local perm
7147
7148         [ "$RUNAS_ID" = "$UID" ] &&
7149                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7150         [ "$RUNAS_ID" -eq 0 ] &&
7151                 skip_env "RUNAS_ID = 0 -- skipping"
7152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7153         # Check that testing environment is properly set up. Skip if not
7154         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7155                 skip_env "User $RUNAS_ID does not exist - skipping"
7156
7157         touch $DIR/${tfile}-f{g,u}
7158         test_mkdir $DIR/${tfile}-dg
7159         test_mkdir $DIR/${tfile}-du
7160         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7161         chmod g+s $DIR/${tfile}-{f,d}g
7162         chmod u+s $DIR/${tfile}-{f,d}u
7163         for perm in 777 2777 4777; do
7164                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7165                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7166                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7167                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7168         done
7169         true
7170 }
7171 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7172
7173 # bug 3462 - multiple simultaneous MDC requests
7174 test_73() {
7175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7176
7177         test_mkdir $DIR/d73-1
7178         test_mkdir $DIR/d73-2
7179         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7180         pid1=$!
7181
7182         lctl set_param fail_loc=0x80000129
7183         $MULTIOP $DIR/d73-1/f73-2 Oc &
7184         sleep 1
7185         lctl set_param fail_loc=0
7186
7187         $MULTIOP $DIR/d73-2/f73-3 Oc &
7188         pid3=$!
7189
7190         kill -USR1 $pid1
7191         wait $pid1 || return 1
7192
7193         sleep 25
7194
7195         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7196         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7197         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7198
7199         rm -rf $DIR/d73-*
7200 }
7201 run_test 73 "multiple MDC requests (should not deadlock)"
7202
7203 test_74a() { # bug 6149, 6184
7204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7205
7206         touch $DIR/f74a
7207         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7208         #
7209         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7210         # will spin in a tight reconnection loop
7211         $LCTL set_param fail_loc=0x8000030e
7212         # get any lock that won't be difficult - lookup works.
7213         ls $DIR/f74a
7214         $LCTL set_param fail_loc=0
7215         rm -f $DIR/f74a
7216         true
7217 }
7218 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7219
7220 test_74b() { # bug 13310
7221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7222
7223         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7224         #
7225         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7226         # will spin in a tight reconnection loop
7227         $LCTL set_param fail_loc=0x8000030e
7228         # get a "difficult" lock
7229         touch $DIR/f74b
7230         $LCTL set_param fail_loc=0
7231         rm -f $DIR/f74b
7232         true
7233 }
7234 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7235
7236 test_74c() {
7237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7238
7239         #define OBD_FAIL_LDLM_NEW_LOCK
7240         $LCTL set_param fail_loc=0x319
7241         touch $DIR/$tfile && error "touch successful"
7242         $LCTL set_param fail_loc=0
7243         true
7244 }
7245 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7246
7247 num_inodes() {
7248         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7249 }
7250
7251 test_76() { # Now for bug 20433, added originally in bug 1443
7252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7253
7254         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7255
7256         cancel_lru_locks osc
7257         BEFORE_INODES=$(num_inodes)
7258         echo "before inodes: $BEFORE_INODES"
7259         local COUNT=1000
7260         [ "$SLOW" = "no" ] && COUNT=100
7261         for i in $(seq $COUNT); do
7262                 touch $DIR/$tfile
7263                 rm -f $DIR/$tfile
7264         done
7265         cancel_lru_locks osc
7266         AFTER_INODES=$(num_inodes)
7267         echo "after inodes: $AFTER_INODES"
7268         local wait=0
7269         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7270                 sleep 2
7271                 AFTER_INODES=$(num_inodes)
7272                 wait=$((wait+2))
7273                 echo "wait $wait seconds inodes: $AFTER_INODES"
7274                 if [ $wait -gt 30 ]; then
7275                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7276                 fi
7277         done
7278 }
7279 run_test 76 "confirm clients recycle inodes properly ===="
7280
7281
7282 export ORIG_CSUM=""
7283 set_checksums()
7284 {
7285         # Note: in sptlrpc modes which enable its own bulk checksum, the
7286         # original crc32_le bulk checksum will be automatically disabled,
7287         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7288         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7289         # In this case set_checksums() will not be no-op, because sptlrpc
7290         # bulk checksum will be enabled all through the test.
7291
7292         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7293         lctl set_param -n osc.*.checksums $1
7294         return 0
7295 }
7296
7297 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7298                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7299 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7300                              tr -d [] | head -n1)}
7301 set_checksum_type()
7302 {
7303         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7304         log "set checksum type to $1"
7305         return 0
7306 }
7307 F77_TMP=$TMP/f77-temp
7308 F77SZ=8
7309 setup_f77() {
7310         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7311                 error "error writing to $F77_TMP"
7312 }
7313
7314 test_77a() { # bug 10889
7315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7316         $GSS && skip_env "could not run with gss"
7317
7318         [ ! -f $F77_TMP ] && setup_f77
7319         set_checksums 1
7320         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7321         set_checksums 0
7322         rm -f $DIR/$tfile
7323 }
7324 run_test 77a "normal checksum read/write operation"
7325
7326 test_77b() { # bug 10889
7327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7328         $GSS && skip_env "could not run with gss"
7329
7330         [ ! -f $F77_TMP ] && setup_f77
7331         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7332         $LCTL set_param fail_loc=0x80000409
7333         set_checksums 1
7334
7335         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7336                 error "dd error: $?"
7337         $LCTL set_param fail_loc=0
7338
7339         for algo in $CKSUM_TYPES; do
7340                 cancel_lru_locks osc
7341                 set_checksum_type $algo
7342                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7343                 $LCTL set_param fail_loc=0x80000408
7344                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7345                 $LCTL set_param fail_loc=0
7346         done
7347         set_checksums 0
7348         set_checksum_type $ORIG_CSUM_TYPE
7349         rm -f $DIR/$tfile
7350 }
7351 run_test 77b "checksum error on client write, read"
7352
7353 cleanup_77c() {
7354         trap 0
7355         set_checksums 0
7356         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7357         $check_ost &&
7358                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7359         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7360         $check_ost && [ -n "$ost_file_prefix" ] &&
7361                 do_facet ost1 rm -f ${ost_file_prefix}\*
7362 }
7363
7364 test_77c() {
7365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7366         $GSS && skip_env "could not run with gss"
7367         remote_ost_nodsh && skip "remote OST with nodsh"
7368
7369         local bad1
7370         local osc_file_prefix
7371         local osc_file
7372         local check_ost=false
7373         local ost_file_prefix
7374         local ost_file
7375         local orig_cksum
7376         local dump_cksum
7377         local fid
7378
7379         # ensure corruption will occur on first OSS/OST
7380         $LFS setstripe -i 0 $DIR/$tfile
7381
7382         [ ! -f $F77_TMP ] && setup_f77
7383         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7384                 error "dd write error: $?"
7385         fid=$($LFS path2fid $DIR/$tfile)
7386
7387         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7388         then
7389                 check_ost=true
7390                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7391                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7392         else
7393                 echo "OSS do not support bulk pages dump upon error"
7394         fi
7395
7396         osc_file_prefix=$($LCTL get_param -n debug_path)
7397         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7398
7399         trap cleanup_77c EXIT
7400
7401         set_checksums 1
7402         # enable bulk pages dump upon error on Client
7403         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7404         # enable bulk pages dump upon error on OSS
7405         $check_ost &&
7406                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7407
7408         # flush Client cache to allow next read to reach OSS
7409         cancel_lru_locks osc
7410
7411         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7412         $LCTL set_param fail_loc=0x80000408
7413         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7414         $LCTL set_param fail_loc=0
7415
7416         rm -f $DIR/$tfile
7417
7418         # check cksum dump on Client
7419         osc_file=$(ls ${osc_file_prefix}*)
7420         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7421         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7422         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7423         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7424         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7425                      cksum)
7426         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7427         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7428                 error "dump content does not match on Client"
7429
7430         $check_ost || skip "No need to check cksum dump on OSS"
7431
7432         # check cksum dump on OSS
7433         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7434         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7435         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7436         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7437         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7438                 error "dump content does not match on OSS"
7439
7440         cleanup_77c
7441 }
7442 run_test 77c "checksum error on client read with debug"
7443
7444 test_77d() { # bug 10889
7445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7446         $GSS && skip_env "could not run with gss"
7447
7448         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7449         $LCTL set_param fail_loc=0x80000409
7450         set_checksums 1
7451         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7452                 error "direct write: rc=$?"
7453         $LCTL set_param fail_loc=0
7454         set_checksums 0
7455
7456         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7457         $LCTL set_param fail_loc=0x80000408
7458         set_checksums 1
7459         cancel_lru_locks osc
7460         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7461                 error "direct read: rc=$?"
7462         $LCTL set_param fail_loc=0
7463         set_checksums 0
7464 }
7465 run_test 77d "checksum error on OST direct write, read"
7466
7467 test_77f() { # bug 10889
7468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7469         $GSS && skip_env "could not run with gss"
7470
7471         set_checksums 1
7472         for algo in $CKSUM_TYPES; do
7473                 cancel_lru_locks osc
7474                 set_checksum_type $algo
7475                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7476                 $LCTL set_param fail_loc=0x409
7477                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7478                         error "direct write succeeded"
7479                 $LCTL set_param fail_loc=0
7480         done
7481         set_checksum_type $ORIG_CSUM_TYPE
7482         set_checksums 0
7483 }
7484 run_test 77f "repeat checksum error on write (expect error)"
7485
7486 test_77g() { # bug 10889
7487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7488         $GSS && skip_env "could not run with gss"
7489         remote_ost_nodsh && skip "remote OST with nodsh"
7490
7491         [ ! -f $F77_TMP ] && setup_f77
7492
7493         local file=$DIR/$tfile
7494         stack_trap "rm -f $file" EXIT
7495
7496         $LFS setstripe -c 1 -i 0 $file
7497         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7498         do_facet ost1 lctl set_param fail_loc=0x8000021a
7499         set_checksums 1
7500         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7501                 error "write error: rc=$?"
7502         do_facet ost1 lctl set_param fail_loc=0
7503         set_checksums 0
7504
7505         cancel_lru_locks osc
7506         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7507         do_facet ost1 lctl set_param fail_loc=0x8000021b
7508         set_checksums 1
7509         cmp $F77_TMP $file || error "file compare failed"
7510         do_facet ost1 lctl set_param fail_loc=0
7511         set_checksums 0
7512 }
7513 run_test 77g "checksum error on OST write, read"
7514
7515 test_77k() { # LU-10906
7516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7517         $GSS && skip_env "could not run with gss"
7518
7519         local cksum_param="osc.$FSNAME*.checksums"
7520         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7521         local checksum
7522         local i
7523
7524         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7525         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7526         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7527                 EXIT
7528
7529         for i in 0 1; do
7530                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7531                         error "failed to set checksum=$i on MGS"
7532                 wait_update $HOSTNAME "$get_checksum" $i
7533                 #remount
7534                 echo "remount client, checksum should be $i"
7535                 remount_client $MOUNT || "failed to remount client"
7536                 checksum=$(eval $get_checksum)
7537                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7538         done
7539         # remove persistent param to avoid races with checksum mountopt below
7540         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7541                 error "failed to delete checksum on MGS"
7542
7543         for opt in "checksum" "nochecksum"; do
7544                 #remount with mount option
7545                 echo "remount client with option $opt, checksum should be $i"
7546                 umount_client $MOUNT || "failed to umount client"
7547                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7548                         "failed to mount client with option '$opt'"
7549                 checksum=$(eval $get_checksum)
7550                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7551                 i=$((i - 1))
7552         done
7553
7554         remount_client $MOUNT || "failed to remount client"
7555 }
7556 run_test 77k "enable/disable checksum correctly"
7557
7558 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7559 rm -f $F77_TMP
7560 unset F77_TMP
7561
7562 cleanup_test_78() {
7563         trap 0
7564         rm -f $DIR/$tfile
7565 }
7566
7567 test_78() { # bug 10901
7568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7569         remote_ost || skip_env "local OST"
7570
7571         NSEQ=5
7572         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7573         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7574         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7575         echo "MemTotal: $MEMTOTAL"
7576
7577         # reserve 256MB of memory for the kernel and other running processes,
7578         # and then take 1/2 of the remaining memory for the read/write buffers.
7579         if [ $MEMTOTAL -gt 512 ] ;then
7580                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7581         else
7582                 # for those poor memory-starved high-end clusters...
7583                 MEMTOTAL=$((MEMTOTAL / 2))
7584         fi
7585         echo "Mem to use for directio: $MEMTOTAL"
7586
7587         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7588         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7589         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7590         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7591                 head -n1)
7592         echo "Smallest OST: $SMALLESTOST"
7593         [[ $SMALLESTOST -lt 10240 ]] &&
7594                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7595
7596         trap cleanup_test_78 EXIT
7597
7598         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7599                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7600
7601         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7602         echo "File size: $F78SIZE"
7603         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7604         for i in $(seq 1 $NSEQ); do
7605                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7606                 echo directIO rdwr round $i of $NSEQ
7607                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7608         done
7609
7610         cleanup_test_78
7611 }
7612 run_test 78 "handle large O_DIRECT writes correctly ============"
7613
7614 test_79() { # bug 12743
7615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7616
7617         wait_delete_completed
7618
7619         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7620         BKFREE=$(calc_osc_kbytes kbytesfree)
7621         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7622
7623         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7624         DFTOTAL=`echo $STRING | cut -d, -f1`
7625         DFUSED=`echo $STRING  | cut -d, -f2`
7626         DFAVAIL=`echo $STRING | cut -d, -f3`
7627         DFFREE=$(($DFTOTAL - $DFUSED))
7628
7629         ALLOWANCE=$((64 * $OSTCOUNT))
7630
7631         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7632            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7633                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7634         fi
7635         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7636            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7637                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7638         fi
7639         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7640            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7641                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7642         fi
7643 }
7644 run_test 79 "df report consistency check ======================="
7645
7646 test_80() { # bug 10718
7647         remote_ost_nodsh && skip "remote OST with nodsh"
7648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7649
7650         # relax strong synchronous semantics for slow backends like ZFS
7651         local soc="obdfilter.*.sync_on_lock_cancel"
7652         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7653         local hosts=
7654         if [ "$soc_old" != "never" ] &&
7655                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7656                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7657                                 facet_active_host $host; done | sort -u)
7658                         do_nodes $hosts lctl set_param $soc=never
7659         fi
7660
7661         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7662         sync; sleep 1; sync
7663         local BEFORE=`date +%s`
7664         cancel_lru_locks osc
7665         local AFTER=`date +%s`
7666         local DIFF=$((AFTER-BEFORE))
7667         if [ $DIFF -gt 1 ] ; then
7668                 error "elapsed for 1M@1T = $DIFF"
7669         fi
7670
7671         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7672
7673         rm -f $DIR/$tfile
7674 }
7675 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7676
7677 test_81a() { # LU-456
7678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7679         remote_ost_nodsh && skip "remote OST with nodsh"
7680
7681         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7682         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7683         do_facet ost1 lctl set_param fail_loc=0x80000228
7684
7685         # write should trigger a retry and success
7686         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7687         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7688         RC=$?
7689         if [ $RC -ne 0 ] ; then
7690                 error "write should success, but failed for $RC"
7691         fi
7692 }
7693 run_test 81a "OST should retry write when get -ENOSPC ==============="
7694
7695 test_81b() { # LU-456
7696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7697         remote_ost_nodsh && skip "remote OST with nodsh"
7698
7699         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7700         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7701         do_facet ost1 lctl set_param fail_loc=0x228
7702
7703         # write should retry several times and return -ENOSPC finally
7704         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7705         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7706         RC=$?
7707         ENOSPC=28
7708         if [ $RC -ne $ENOSPC ] ; then
7709                 error "dd should fail for -ENOSPC, but succeed."
7710         fi
7711 }
7712 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7713
7714 test_82() { # LU-1031
7715         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7716         local gid1=14091995
7717         local gid2=16022000
7718
7719         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7720         local MULTIPID1=$!
7721         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7722         local MULTIPID2=$!
7723         kill -USR1 $MULTIPID2
7724         sleep 2
7725         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7726                 error "First grouplock does not block second one"
7727         else
7728                 echo "Second grouplock blocks first one"
7729         fi
7730         kill -USR1 $MULTIPID1
7731         wait $MULTIPID1
7732         wait $MULTIPID2
7733 }
7734 run_test 82 "Basic grouplock test"
7735
7736 test_99() {
7737         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7738
7739         test_mkdir $DIR/$tdir.cvsroot
7740         chown $RUNAS_ID $DIR/$tdir.cvsroot
7741
7742         cd $TMP
7743         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7744
7745         cd /etc/init.d
7746         # some versions of cvs import exit(1) when asked to import links or
7747         # files they can't read.  ignore those files.
7748         local toignore=$(find . -type l -printf '-I %f\n' -o \
7749                          ! -perm /4 -printf '-I %f\n')
7750         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7751                 $tdir.reposname vtag rtag
7752
7753         cd $DIR
7754         test_mkdir $DIR/$tdir.reposname
7755         chown $RUNAS_ID $DIR/$tdir.reposname
7756         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7757
7758         cd $DIR/$tdir.reposname
7759         $RUNAS touch foo99
7760         $RUNAS cvs add -m 'addmsg' foo99
7761         $RUNAS cvs update
7762         $RUNAS cvs commit -m 'nomsg' foo99
7763         rm -fr $DIR/$tdir.cvsroot
7764 }
7765 run_test 99 "cvs strange file/directory operations"
7766
7767 test_100() {
7768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7769         [[ "$NETTYPE" =~ tcp ]] ||
7770                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7771         remote_ost_nodsh && skip "remote OST with nodsh"
7772         remote_mds_nodsh && skip "remote MDS with nodsh"
7773         remote_servers ||
7774                 skip "useless for local single node setup"
7775
7776         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7777                 [ "$PROT" != "tcp" ] && continue
7778                 RPORT=$(echo $REMOTE | cut -d: -f2)
7779                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7780
7781                 rc=0
7782                 LPORT=`echo $LOCAL | cut -d: -f2`
7783                 if [ $LPORT -ge 1024 ]; then
7784                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7785                         netstat -tna
7786                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7787                 fi
7788         done
7789         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7790 }
7791 run_test 100 "check local port using privileged port ==========="
7792
7793 function get_named_value()
7794 {
7795     local tag
7796
7797     tag=$1
7798     while read ;do
7799         line=$REPLY
7800         case $line in
7801         $tag*)
7802             echo $line | sed "s/^$tag[ ]*//"
7803             break
7804             ;;
7805         esac
7806     done
7807 }
7808
7809 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7810                    awk '/^max_cached_mb/ { print $2 }')
7811
7812 cleanup_101a() {
7813         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7814         trap 0
7815 }
7816
7817 test_101a() {
7818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7819         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7820
7821         local s
7822         local discard
7823         local nreads=10000
7824         local cache_limit=32
7825
7826         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7827         trap cleanup_101a EXIT
7828         $LCTL set_param -n llite.*.read_ahead_stats 0
7829         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7830
7831         #
7832         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7833         #
7834         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7835         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7836
7837         discard=0
7838         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7839                 get_named_value 'read but discarded' | cut -d" " -f1); do
7840                         discard=$(($discard + $s))
7841         done
7842         cleanup_101a
7843
7844         if [[ $(($discard * 10)) -gt $nreads ]]; then
7845                 $LCTL get_param osc.*-osc*.rpc_stats
7846                 $LCTL get_param llite.*.read_ahead_stats
7847                 error "too many ($discard) discarded pages"
7848         fi
7849         rm -f $DIR/$tfile || true
7850 }
7851 run_test 101a "check read-ahead for random reads"
7852
7853 setup_test101bc() {
7854         test_mkdir $DIR/$tdir
7855         local ssize=$1
7856         local FILE_LENGTH=$2
7857         STRIPE_OFFSET=0
7858
7859         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7860
7861         local list=$(comma_list $(osts_nodes))
7862         set_osd_param $list '' read_cache_enable 0
7863         set_osd_param $list '' writethrough_cache_enable 0
7864
7865         trap cleanup_test101bc EXIT
7866         # prepare the read-ahead file
7867         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7868
7869         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7870                                 count=$FILE_SIZE_MB 2> /dev/null
7871
7872 }
7873
7874 cleanup_test101bc() {
7875         trap 0
7876         rm -rf $DIR/$tdir
7877         rm -f $DIR/$tfile
7878
7879         local list=$(comma_list $(osts_nodes))
7880         set_osd_param $list '' read_cache_enable 1
7881         set_osd_param $list '' writethrough_cache_enable 1
7882 }
7883
7884 calc_total() {
7885         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7886 }
7887
7888 ra_check_101() {
7889         local READ_SIZE=$1
7890         local STRIPE_SIZE=$2
7891         local FILE_LENGTH=$3
7892         local RA_INC=1048576
7893         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7894         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7895                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7896         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7897                         get_named_value 'read but discarded' |
7898                         cut -d" " -f1 | calc_total)
7899         if [[ $DISCARD -gt $discard_limit ]]; then
7900                 $LCTL get_param llite.*.read_ahead_stats
7901                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7902         else
7903                 echo "Read-ahead success for size ${READ_SIZE}"
7904         fi
7905 }
7906
7907 test_101b() {
7908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7909         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7910
7911         local STRIPE_SIZE=1048576
7912         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7913
7914         if [ $SLOW == "yes" ]; then
7915                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7916         else
7917                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7918         fi
7919
7920         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7921
7922         # prepare the read-ahead file
7923         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7924         cancel_lru_locks osc
7925         for BIDX in 2 4 8 16 32 64 128 256
7926         do
7927                 local BSIZE=$((BIDX*4096))
7928                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7929                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7930                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7931                 $LCTL set_param -n llite.*.read_ahead_stats 0
7932                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7933                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7934                 cancel_lru_locks osc
7935                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7936         done
7937         cleanup_test101bc
7938         true
7939 }
7940 run_test 101b "check stride-io mode read-ahead ================="
7941
7942 test_101c() {
7943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7944
7945         local STRIPE_SIZE=1048576
7946         local FILE_LENGTH=$((STRIPE_SIZE*100))
7947         local nreads=10000
7948         local rsize=65536
7949         local osc_rpc_stats
7950
7951         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7952
7953         cancel_lru_locks osc
7954         $LCTL set_param osc.*.rpc_stats 0
7955         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7956         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7957                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7958                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7959                 local size
7960
7961                 if [ $lines -le 20 ]; then
7962                         continue
7963                 fi
7964                 for size in 1 2 4 8; do
7965                         local rpc=$(echo "$stats" |
7966                                     awk '($1 == "'$size':") {print $2; exit; }')
7967                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7968                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7969                 done
7970                 echo "$osc_rpc_stats check passed!"
7971         done
7972         cleanup_test101bc
7973         true
7974 }
7975 run_test 101c "check stripe_size aligned read-ahead ================="
7976
7977 set_read_ahead() {
7978         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7979         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7980 }
7981
7982 test_101d() {
7983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7984
7985         local file=$DIR/$tfile
7986         local sz_MB=${FILESIZE_101d:-500}
7987         local ra_MB=${READAHEAD_MB:-40}
7988
7989         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7990         [ $free_MB -lt $sz_MB ] &&
7991                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7992
7993         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7994         $LFS setstripe -c -1 $file || error "setstripe failed"
7995
7996         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7997         echo Cancel LRU locks on lustre client to flush the client cache
7998         cancel_lru_locks osc
7999
8000         echo Disable read-ahead
8001         local old_READAHEAD=$(set_read_ahead 0)
8002
8003         echo Reading the test file $file with read-ahead disabled
8004         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8005
8006         echo Cancel LRU locks on lustre client to flush the client cache
8007         cancel_lru_locks osc
8008         echo Enable read-ahead with ${ra_MB}MB
8009         set_read_ahead $ra_MB
8010
8011         echo Reading the test file $file with read-ahead enabled
8012         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8013
8014         echo "read-ahead disabled time read $raOFF"
8015         echo "read-ahead enabled  time read $raON"
8016
8017         set_read_ahead $old_READAHEAD
8018         rm -f $file
8019         wait_delete_completed
8020
8021         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8022                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8023 }
8024 run_test 101d "file read with and without read-ahead enabled"
8025
8026 test_101e() {
8027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8028
8029         local file=$DIR/$tfile
8030         local size_KB=500  #KB
8031         local count=100
8032         local bsize=1024
8033
8034         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8035         local need_KB=$((count * size_KB))
8036         [[ $free_KB -le $need_KB ]] &&
8037                 skip_env "Need free space $need_KB, have $free_KB"
8038
8039         echo "Creating $count ${size_KB}K test files"
8040         for ((i = 0; i < $count; i++)); do
8041                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8042         done
8043
8044         echo "Cancel LRU locks on lustre client to flush the client cache"
8045         cancel_lru_locks $OSC
8046
8047         echo "Reset readahead stats"
8048         $LCTL set_param -n llite.*.read_ahead_stats 0
8049
8050         for ((i = 0; i < $count; i++)); do
8051                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8052         done
8053
8054         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8055                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8056
8057         for ((i = 0; i < $count; i++)); do
8058                 rm -rf $file.$i 2>/dev/null
8059         done
8060
8061         #10000 means 20% reads are missing in readahead
8062         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8063 }
8064 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8065
8066 test_101f() {
8067         which iozone || skip_env "no iozone installed"
8068
8069         local old_debug=$($LCTL get_param debug)
8070         old_debug=${old_debug#*=}
8071         $LCTL set_param debug="reada mmap"
8072
8073         # create a test file
8074         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8075
8076         echo Cancel LRU locks on lustre client to flush the client cache
8077         cancel_lru_locks osc
8078
8079         echo Reset readahead stats
8080         $LCTL set_param -n llite.*.read_ahead_stats 0
8081
8082         echo mmap read the file with small block size
8083         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8084                 > /dev/null 2>&1
8085
8086         echo checking missing pages
8087         $LCTL get_param llite.*.read_ahead_stats
8088         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8089                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8090
8091         $LCTL set_param debug="$old_debug"
8092         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8093         rm -f $DIR/$tfile
8094 }
8095 run_test 101f "check mmap read performance"
8096
8097 test_101g_brw_size_test() {
8098         local mb=$1
8099         local pages=$((mb * 1048576 / PAGE_SIZE))
8100         local file=$DIR/$tfile
8101
8102         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8103                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8104         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8105                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8106                         return 2
8107         done
8108
8109         stack_trap "rm -f $file" EXIT
8110         $LCTL set_param -n osc.*.rpc_stats=0
8111
8112         # 10 RPCs should be enough for the test
8113         local count=10
8114         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8115                 { error "dd write ${mb} MB blocks failed"; return 3; }
8116         cancel_lru_locks osc
8117         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8118                 { error "dd write ${mb} MB blocks failed"; return 4; }
8119
8120         # calculate number of full-sized read and write RPCs
8121         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8122                 sed -n '/pages per rpc/,/^$/p' |
8123                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8124                 END { print reads,writes }'))
8125         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8126                 return 5
8127         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8128                 return 6
8129
8130         return 0
8131 }
8132
8133 test_101g() {
8134         remote_ost_nodsh && skip "remote OST with nodsh"
8135
8136         local rpcs
8137         local osts=$(get_facets OST)
8138         local list=$(comma_list $(osts_nodes))
8139         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8140         local brw_size="obdfilter.*.brw_size"
8141
8142         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8143
8144         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8145
8146         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8147                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8148                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8149            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8150                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8151                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8152
8153                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8154                         suffix="M"
8155
8156                 if [[ $orig_mb -lt 16 ]]; then
8157                         save_lustre_params $osts "$brw_size" > $p
8158                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8159                                 error "set 16MB RPC size failed"
8160
8161                         echo "remount client to enable new RPC size"
8162                         remount_client $MOUNT || error "remount_client failed"
8163                 fi
8164
8165                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8166                 # should be able to set brw_size=12, but no rpc_stats for that
8167                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8168         fi
8169
8170         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8171
8172         if [[ $orig_mb -lt 16 ]]; then
8173                 restore_lustre_params < $p
8174                 remount_client $MOUNT || error "remount_client restore failed"
8175         fi
8176
8177         rm -f $p $DIR/$tfile
8178 }
8179 run_test 101g "Big bulk(4/16 MiB) readahead"
8180
8181 setup_test102() {
8182         test_mkdir $DIR/$tdir
8183         chown $RUNAS_ID $DIR/$tdir
8184         STRIPE_SIZE=65536
8185         STRIPE_OFFSET=1
8186         STRIPE_COUNT=$OSTCOUNT
8187         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8188
8189         trap cleanup_test102 EXIT
8190         cd $DIR
8191         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8192         cd $DIR/$tdir
8193         for num in 1 2 3 4; do
8194                 for count in $(seq 1 $STRIPE_COUNT); do
8195                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8196                                 local size=`expr $STRIPE_SIZE \* $num`
8197                                 local file=file"$num-$idx-$count"
8198                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8199                         done
8200                 done
8201         done
8202
8203         cd $DIR
8204         $1 tar cf $TMP/f102.tar $tdir --xattrs
8205 }
8206
8207 cleanup_test102() {
8208         trap 0
8209         rm -f $TMP/f102.tar
8210         rm -rf $DIR/d0.sanity/d102
8211 }
8212
8213 test_102a() {
8214         [ "$UID" != 0 ] && skip "must run as root"
8215         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8216                 skip_env "must have user_xattr"
8217
8218         [ -z "$(which setfattr 2>/dev/null)" ] &&
8219                 skip_env "could not find setfattr"
8220
8221         local testfile=$DIR/$tfile
8222
8223         touch $testfile
8224         echo "set/get xattr..."
8225         setfattr -n trusted.name1 -v value1 $testfile ||
8226                 error "setfattr -n trusted.name1=value1 $testfile failed"
8227         getfattr -n trusted.name1 $testfile 2> /dev/null |
8228           grep "trusted.name1=.value1" ||
8229                 error "$testfile missing trusted.name1=value1"
8230
8231         setfattr -n user.author1 -v author1 $testfile ||
8232                 error "setfattr -n user.author1=author1 $testfile failed"
8233         getfattr -n user.author1 $testfile 2> /dev/null |
8234           grep "user.author1=.author1" ||
8235                 error "$testfile missing trusted.author1=author1"
8236
8237         echo "listxattr..."
8238         setfattr -n trusted.name2 -v value2 $testfile ||
8239                 error "$testfile unable to set trusted.name2"
8240         setfattr -n trusted.name3 -v value3 $testfile ||
8241                 error "$testfile unable to set trusted.name3"
8242         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8243             grep "trusted.name" | wc -l) -eq 3 ] ||
8244                 error "$testfile missing 3 trusted.name xattrs"
8245
8246         setfattr -n user.author2 -v author2 $testfile ||
8247                 error "$testfile unable to set user.author2"
8248         setfattr -n user.author3 -v author3 $testfile ||
8249                 error "$testfile unable to set user.author3"
8250         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8251             grep "user.author" | wc -l) -eq 3 ] ||
8252                 error "$testfile missing 3 user.author xattrs"
8253
8254         echo "remove xattr..."
8255         setfattr -x trusted.name1 $testfile ||
8256                 error "$testfile error deleting trusted.name1"
8257         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8258                 error "$testfile did not delete trusted.name1 xattr"
8259
8260         setfattr -x user.author1 $testfile ||
8261                 error "$testfile error deleting user.author1"
8262         echo "set lustre special xattr ..."
8263         $LFS setstripe -c1 $testfile
8264         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8265                 awk -F "=" '/trusted.lov/ { print $2 }' )
8266         setfattr -n "trusted.lov" -v $lovea $testfile ||
8267                 error "$testfile doesn't ignore setting trusted.lov again"
8268         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8269                 error "$testfile allow setting invalid trusted.lov"
8270         rm -f $testfile
8271 }
8272 run_test 102a "user xattr test =================================="
8273
8274 test_102b() {
8275         [ -z "$(which setfattr 2>/dev/null)" ] &&
8276                 skip_env "could not find setfattr"
8277         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8278
8279         # b10930: get/set/list trusted.lov xattr
8280         echo "get/set/list trusted.lov xattr ..."
8281         local testfile=$DIR/$tfile
8282         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8283                 error "setstripe failed"
8284         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8285                 error "getstripe failed"
8286         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8287                 error "can't get trusted.lov from $testfile"
8288
8289         local testfile2=${testfile}2
8290         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8291                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8292
8293         $MCREATE $testfile2
8294         setfattr -n trusted.lov -v $value $testfile2
8295         local stripe_size=$($LFS getstripe -S $testfile2)
8296         local stripe_count=$($LFS getstripe -c $testfile2)
8297         [[ $stripe_size -eq 65536 ]] ||
8298                 error "stripe size $stripe_size != 65536"
8299         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8300                 error "stripe count $stripe_count != $STRIPECOUNT"
8301         rm -f $DIR/$tfile
8302 }
8303 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8304
8305 test_102c() {
8306         [ -z "$(which setfattr 2>/dev/null)" ] &&
8307                 skip_env "could not find setfattr"
8308         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8309
8310         # b10930: get/set/list lustre.lov xattr
8311         echo "get/set/list lustre.lov xattr ..."
8312         test_mkdir $DIR/$tdir
8313         chown $RUNAS_ID $DIR/$tdir
8314         local testfile=$DIR/$tdir/$tfile
8315         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8316                 error "setstripe failed"
8317         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8318                 error "getstripe failed"
8319         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8320         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8321
8322         local testfile2=${testfile}2
8323         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8324                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8325
8326         $RUNAS $MCREATE $testfile2
8327         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8328         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8329         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8330         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8331         [ $stripe_count -eq $STRIPECOUNT ] ||
8332                 error "stripe count $stripe_count != $STRIPECOUNT"
8333 }
8334 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8335
8336 compare_stripe_info1() {
8337         local stripe_index_all_zero=true
8338
8339         for num in 1 2 3 4; do
8340                 for count in $(seq 1 $STRIPE_COUNT); do
8341                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8342                                 local size=$((STRIPE_SIZE * num))
8343                                 local file=file"$num-$offset-$count"
8344                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8345                                 [[ $stripe_size -ne $size ]] &&
8346                                     error "$file: size $stripe_size != $size"
8347                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8348                                 # allow fewer stripes to be created, ORI-601
8349                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8350                                     error "$file: count $stripe_count != $count"
8351                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8352                                 [[ $stripe_index -ne 0 ]] &&
8353                                         stripe_index_all_zero=false
8354                         done
8355                 done
8356         done
8357         $stripe_index_all_zero &&
8358                 error "all files are being extracted starting from OST index 0"
8359         return 0
8360 }
8361
8362 have_xattrs_include() {
8363         tar --help | grep -q xattrs-include &&
8364                 echo --xattrs-include="lustre.*"
8365 }
8366
8367 test_102d() {
8368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8369         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8370
8371         XINC=$(have_xattrs_include)
8372         setup_test102
8373         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8374         cd $DIR/$tdir/$tdir
8375         compare_stripe_info1
8376 }
8377 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8378
8379 test_102f() {
8380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8381         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8382
8383         XINC=$(have_xattrs_include)
8384         setup_test102
8385         test_mkdir $DIR/$tdir.restore
8386         cd $DIR
8387         tar cf - --xattrs $tdir | tar xf - \
8388                 -C $DIR/$tdir.restore --xattrs $XINC
8389         cd $DIR/$tdir.restore/$tdir
8390         compare_stripe_info1
8391 }
8392 run_test 102f "tar copy files, not keep osts"
8393
8394 grow_xattr() {
8395         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8396                 skip "must have user_xattr"
8397         [ -z "$(which setfattr 2>/dev/null)" ] &&
8398                 skip_env "could not find setfattr"
8399         [ -z "$(which getfattr 2>/dev/null)" ] &&
8400                 skip_env "could not find getfattr"
8401
8402         local xsize=${1:-1024}  # in bytes
8403         local file=$DIR/$tfile
8404         local value="$(generate_string $xsize)"
8405         local xbig=trusted.big
8406         local toobig=$2
8407
8408         touch $file
8409         log "save $xbig on $file"
8410         if [ -z "$toobig" ]
8411         then
8412                 setfattr -n $xbig -v $value $file ||
8413                         error "saving $xbig on $file failed"
8414         else
8415                 setfattr -n $xbig -v $value $file &&
8416                         error "saving $xbig on $file succeeded"
8417                 return 0
8418         fi
8419
8420         local orig=$(get_xattr_value $xbig $file)
8421         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8422
8423         local xsml=trusted.sml
8424         log "save $xsml on $file"
8425         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8426
8427         local new=$(get_xattr_value $xbig $file)
8428         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8429
8430         log "grow $xsml on $file"
8431         setfattr -n $xsml -v "$value" $file ||
8432                 error "growing $xsml on $file failed"
8433
8434         new=$(get_xattr_value $xbig $file)
8435         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8436         log "$xbig still valid after growing $xsml"
8437
8438         rm -f $file
8439 }
8440
8441 test_102h() { # bug 15777
8442         grow_xattr 1024
8443 }
8444 run_test 102h "grow xattr from inside inode to external block"
8445
8446 test_102ha() {
8447         large_xattr_enabled || skip_env "ea_inode feature disabled"
8448
8449         echo "setting xattr of max xattr size: $(max_xattr_size)"
8450         grow_xattr $(max_xattr_size)
8451
8452         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8453         echo "This should fail:"
8454         grow_xattr $(($(max_xattr_size) + 10)) 1
8455 }
8456 run_test 102ha "grow xattr from inside inode to external inode"
8457
8458 test_102i() { # bug 17038
8459         [ -z "$(which getfattr 2>/dev/null)" ] &&
8460                 skip "could not find getfattr"
8461
8462         touch $DIR/$tfile
8463         ln -s $DIR/$tfile $DIR/${tfile}link
8464         getfattr -n trusted.lov $DIR/$tfile ||
8465                 error "lgetxattr on $DIR/$tfile failed"
8466         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8467                 grep -i "no such attr" ||
8468                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8469         rm -f $DIR/$tfile $DIR/${tfile}link
8470 }
8471 run_test 102i "lgetxattr test on symbolic link ============"
8472
8473 test_102j() {
8474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8475         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8476
8477         XINC=$(have_xattrs_include)
8478         setup_test102 "$RUNAS"
8479         chown $RUNAS_ID $DIR/$tdir
8480         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8481         cd $DIR/$tdir/$tdir
8482         compare_stripe_info1 "$RUNAS"
8483 }
8484 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8485
8486 test_102k() {
8487         [ -z "$(which setfattr 2>/dev/null)" ] &&
8488                 skip "could not find setfattr"
8489
8490         touch $DIR/$tfile
8491         # b22187 just check that does not crash for regular file.
8492         setfattr -n trusted.lov $DIR/$tfile
8493         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8494         local test_kdir=$DIR/$tdir
8495         test_mkdir $test_kdir
8496         local default_size=$($LFS getstripe -S $test_kdir)
8497         local default_count=$($LFS getstripe -c $test_kdir)
8498         local default_offset=$($LFS getstripe -i $test_kdir)
8499         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8500                 error 'dir setstripe failed'
8501         setfattr -n trusted.lov $test_kdir
8502         local stripe_size=$($LFS getstripe -S $test_kdir)
8503         local stripe_count=$($LFS getstripe -c $test_kdir)
8504         local stripe_offset=$($LFS getstripe -i $test_kdir)
8505         [ $stripe_size -eq $default_size ] ||
8506                 error "stripe size $stripe_size != $default_size"
8507         [ $stripe_count -eq $default_count ] ||
8508                 error "stripe count $stripe_count != $default_count"
8509         [ $stripe_offset -eq $default_offset ] ||
8510                 error "stripe offset $stripe_offset != $default_offset"
8511         rm -rf $DIR/$tfile $test_kdir
8512 }
8513 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8514
8515 test_102l() {
8516         [ -z "$(which getfattr 2>/dev/null)" ] &&
8517                 skip "could not find getfattr"
8518
8519         # LU-532 trusted. xattr is invisible to non-root
8520         local testfile=$DIR/$tfile
8521
8522         touch $testfile
8523
8524         echo "listxattr as user..."
8525         chown $RUNAS_ID $testfile
8526         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8527             grep -q "trusted" &&
8528                 error "$testfile trusted xattrs are user visible"
8529
8530         return 0;
8531 }
8532 run_test 102l "listxattr size test =================================="
8533
8534 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8535         local path=$DIR/$tfile
8536         touch $path
8537
8538         listxattr_size_check $path || error "listattr_size_check $path failed"
8539 }
8540 run_test 102m "Ensure listxattr fails on small bufffer ========"
8541
8542 cleanup_test102
8543
8544 getxattr() { # getxattr path name
8545         # Return the base64 encoding of the value of xattr name on path.
8546         local path=$1
8547         local name=$2
8548
8549         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8550         # file: $path
8551         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8552         #
8553         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8554
8555         getfattr --absolute-names --encoding=base64 --name=$name $path |
8556                 awk -F= -v name=$name '$1 == name {
8557                         print substr($0, index($0, "=") + 1);
8558         }'
8559 }
8560
8561 test_102n() { # LU-4101 mdt: protect internal xattrs
8562         [ -z "$(which setfattr 2>/dev/null)" ] &&
8563                 skip "could not find setfattr"
8564         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8565         then
8566                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8567         fi
8568
8569         local file0=$DIR/$tfile.0
8570         local file1=$DIR/$tfile.1
8571         local xattr0=$TMP/$tfile.0
8572         local xattr1=$TMP/$tfile.1
8573         local namelist="lov lma lmv link fid version som hsm"
8574         local name
8575         local value
8576
8577         rm -rf $file0 $file1 $xattr0 $xattr1
8578         touch $file0 $file1
8579
8580         # Get 'before' xattrs of $file1.
8581         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8582
8583         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8584                 namelist+=" lfsck_namespace"
8585         for name in $namelist; do
8586                 # Try to copy xattr from $file0 to $file1.
8587                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8588
8589                 setfattr --name=trusted.$name --value="$value" $file1 ||
8590                         error "setxattr 'trusted.$name' failed"
8591
8592                 # Try to set a garbage xattr.
8593                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8594
8595                 if [[ x$name == "xlov" ]]; then
8596                         setfattr --name=trusted.lov --value="$value" $file1 &&
8597                         error "setxattr invalid 'trusted.lov' success"
8598                 else
8599                         setfattr --name=trusted.$name --value="$value" $file1 ||
8600                                 error "setxattr invalid 'trusted.$name' failed"
8601                 fi
8602
8603                 # Try to remove the xattr from $file1. We don't care if this
8604                 # appears to succeed or fail, we just don't want there to be
8605                 # any changes or crashes.
8606                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8607         done
8608
8609         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8610         then
8611                 name="lfsck_ns"
8612                 # Try to copy xattr from $file0 to $file1.
8613                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8614
8615                 setfattr --name=trusted.$name --value="$value" $file1 ||
8616                         error "setxattr 'trusted.$name' failed"
8617
8618                 # Try to set a garbage xattr.
8619                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8620
8621                 setfattr --name=trusted.$name --value="$value" $file1 ||
8622                         error "setxattr 'trusted.$name' failed"
8623
8624                 # Try to remove the xattr from $file1. We don't care if this
8625                 # appears to succeed or fail, we just don't want there to be
8626                 # any changes or crashes.
8627                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8628         fi
8629
8630         # Get 'after' xattrs of file1.
8631         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8632
8633         if ! diff $xattr0 $xattr1; then
8634                 error "before and after xattrs of '$file1' differ"
8635         fi
8636
8637         rm -rf $file0 $file1 $xattr0 $xattr1
8638
8639         return 0
8640 }
8641 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8642
8643 test_102p() { # LU-4703 setxattr did not check ownership
8644         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8645                 skip "MDS needs to be at least 2.5.56"
8646
8647         local testfile=$DIR/$tfile
8648
8649         touch $testfile
8650
8651         echo "setfacl as user..."
8652         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8653         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8654
8655         echo "setfattr as user..."
8656         setfacl -m "u:$RUNAS_ID:---" $testfile
8657         $RUNAS setfattr -x system.posix_acl_access $testfile
8658         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8659 }
8660 run_test 102p "check setxattr(2) correctly fails without permission"
8661
8662 test_102q() {
8663         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8664                 skip "MDS needs to be at least 2.6.92"
8665
8666         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8667 }
8668 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8669
8670 test_102r() {
8671         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8672                 skip "MDS needs to be at least 2.6.93"
8673
8674         touch $DIR/$tfile || error "touch"
8675         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8676         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8677         rm $DIR/$tfile || error "rm"
8678
8679         #normal directory
8680         mkdir -p $DIR/$tdir || error "mkdir"
8681         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8682         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8683         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8684                 error "$testfile error deleting user.author1"
8685         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8686                 grep "user.$(basename $tdir)" &&
8687                 error "$tdir did not delete user.$(basename $tdir)"
8688         rmdir $DIR/$tdir || error "rmdir"
8689
8690         #striped directory
8691         test_mkdir $DIR/$tdir
8692         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8693         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8694         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8695                 error "$testfile error deleting user.author1"
8696         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8697                 grep "user.$(basename $tdir)" &&
8698                 error "$tdir did not delete user.$(basename $tdir)"
8699         rmdir $DIR/$tdir || error "rm striped dir"
8700 }
8701 run_test 102r "set EAs with empty values"
8702
8703 test_102s() {
8704         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8705                 skip "MDS needs to be at least 2.11.52"
8706
8707         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8708
8709         save_lustre_params client "llite.*.xattr_cache" > $save
8710
8711         for cache in 0 1; do
8712                 lctl set_param llite.*.xattr_cache=$cache
8713
8714                 rm -f $DIR/$tfile
8715                 touch $DIR/$tfile || error "touch"
8716                 for prefix in lustre security system trusted user; do
8717                         # Note getxattr() may fail with 'Operation not
8718                         # supported' or 'No such attribute' depending
8719                         # on prefix and cache.
8720                         getfattr -n $prefix.n102s $DIR/$tfile &&
8721                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8722                 done
8723         done
8724
8725         restore_lustre_params < $save
8726 }
8727 run_test 102s "getting nonexistent xattrs should fail"
8728
8729 test_102t() {
8730         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8731                 skip "MDS needs to be at least 2.11.52"
8732
8733         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8734
8735         save_lustre_params client "llite.*.xattr_cache" > $save
8736
8737         for cache in 0 1; do
8738                 lctl set_param llite.*.xattr_cache=$cache
8739
8740                 for buf_size in 0 256; do
8741                         rm -f $DIR/$tfile
8742                         touch $DIR/$tfile || error "touch"
8743                         setfattr -n user.multiop $DIR/$tfile
8744                         $MULTIOP $DIR/$tfile oa$buf_size ||
8745                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8746                 done
8747         done
8748
8749         restore_lustre_params < $save
8750 }
8751 run_test 102t "zero length xattr values handled correctly"
8752
8753 run_acl_subtest()
8754 {
8755     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8756     return $?
8757 }
8758
8759 test_103a() {
8760         [ "$UID" != 0 ] && skip "must run as root"
8761         $GSS && skip_env "could not run under gss"
8762         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8763                 skip_env "must have acl enabled"
8764         [ -z "$(which setfacl 2>/dev/null)" ] &&
8765                 skip_env "could not find setfacl"
8766         remote_mds_nodsh && skip "remote MDS with nodsh"
8767
8768         gpasswd -a daemon bin                           # LU-5641
8769         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8770
8771         declare -a identity_old
8772
8773         for num in $(seq $MDSCOUNT); do
8774                 switch_identity $num true || identity_old[$num]=$?
8775         done
8776
8777         SAVE_UMASK=$(umask)
8778         umask 0022
8779         mkdir -p $DIR/$tdir
8780         cd $DIR/$tdir
8781
8782         echo "performing cp ..."
8783         run_acl_subtest cp || error "run_acl_subtest cp failed"
8784         echo "performing getfacl-noacl..."
8785         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8786         echo "performing misc..."
8787         run_acl_subtest misc || error  "misc test failed"
8788         echo "performing permissions..."
8789         run_acl_subtest permissions || error "permissions failed"
8790         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8791         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8792                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8793                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8794         then
8795                 echo "performing permissions xattr..."
8796                 run_acl_subtest permissions_xattr ||
8797                         error "permissions_xattr failed"
8798         fi
8799         echo "performing setfacl..."
8800         run_acl_subtest setfacl || error  "setfacl test failed"
8801
8802         # inheritance test got from HP
8803         echo "performing inheritance..."
8804         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8805         chmod +x make-tree || error "chmod +x failed"
8806         run_acl_subtest inheritance || error "inheritance test failed"
8807         rm -f make-tree
8808
8809         echo "LU-974 ignore umask when acl is enabled..."
8810         run_acl_subtest 974 || error "LU-974 umask test failed"
8811         if [ $MDSCOUNT -ge 2 ]; then
8812                 run_acl_subtest 974_remote ||
8813                         error "LU-974 umask test failed under remote dir"
8814         fi
8815
8816         echo "LU-2561 newly created file is same size as directory..."
8817         if [ "$mds1_FSTYPE" != "zfs" ]; then
8818                 run_acl_subtest 2561 || error "LU-2561 test failed"
8819         else
8820                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8821         fi
8822
8823         run_acl_subtest 4924 || error "LU-4924 test failed"
8824
8825         cd $SAVE_PWD
8826         umask $SAVE_UMASK
8827
8828         for num in $(seq $MDSCOUNT); do
8829                 if [ "${identity_old[$num]}" = 1 ]; then
8830                         switch_identity $num false || identity_old[$num]=$?
8831                 fi
8832         done
8833 }
8834 run_test 103a "acl test"
8835
8836 test_103b() {
8837         declare -a pids
8838         local U
8839
8840         for U in {0..511}; do
8841                 {
8842                 local O=$(printf "%04o" $U)
8843
8844                 umask $(printf "%04o" $((511 ^ $O)))
8845                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8846                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8847
8848                 (( $S == ($O & 0666) )) ||
8849                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8850
8851                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8852                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8853                 (( $S == ($O & 0666) )) ||
8854                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8855
8856                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8857                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8858                 (( $S == ($O & 0666) )) ||
8859                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8860                 rm -f $DIR/$tfile.[smp]$0
8861                 } &
8862                 local pid=$!
8863
8864                 # limit the concurrently running threads to 64. LU-11878
8865                 local idx=$((U % 64))
8866                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8867                 pids[idx]=$pid
8868         done
8869         wait
8870 }
8871 run_test 103b "umask lfs setstripe"
8872
8873 test_103c() {
8874         mkdir -p $DIR/$tdir
8875         cp -rp $DIR/$tdir $DIR/$tdir.bak
8876
8877         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8878                 error "$DIR/$tdir shouldn't contain default ACL"
8879         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8880                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8881         true
8882 }
8883 run_test 103c "'cp -rp' won't set empty acl"
8884
8885 test_104a() {
8886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8887
8888         touch $DIR/$tfile
8889         lfs df || error "lfs df failed"
8890         lfs df -ih || error "lfs df -ih failed"
8891         lfs df -h $DIR || error "lfs df -h $DIR failed"
8892         lfs df -i $DIR || error "lfs df -i $DIR failed"
8893         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8894         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8895
8896         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8897         lctl --device %$OSC deactivate
8898         lfs df || error "lfs df with deactivated OSC failed"
8899         lctl --device %$OSC activate
8900         # wait the osc back to normal
8901         wait_osc_import_ready client ost
8902
8903         lfs df || error "lfs df with reactivated OSC failed"
8904         rm -f $DIR/$tfile
8905 }
8906 run_test 104a "lfs df [-ih] [path] test ========================="
8907
8908 test_104b() {
8909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8910         [ $RUNAS_ID -eq $UID ] &&
8911                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8912
8913         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8914                         grep "Permission denied" | wc -l)))
8915         if [ $denied_cnt -ne 0 ]; then
8916                 error "lfs check servers test failed"
8917         fi
8918 }
8919 run_test 104b "$RUNAS lfs check servers test ===================="
8920
8921 test_105a() {
8922         # doesn't work on 2.4 kernels
8923         touch $DIR/$tfile
8924         if $(flock_is_enabled); then
8925                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8926         else
8927                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8928         fi
8929         rm -f $DIR/$tfile
8930 }
8931 run_test 105a "flock when mounted without -o flock test ========"
8932
8933 test_105b() {
8934         touch $DIR/$tfile
8935         if $(flock_is_enabled); then
8936                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8937         else
8938                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8939         fi
8940         rm -f $DIR/$tfile
8941 }
8942 run_test 105b "fcntl when mounted without -o flock test ========"
8943
8944 test_105c() {
8945         touch $DIR/$tfile
8946         if $(flock_is_enabled); then
8947                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8948         else
8949                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8950         fi
8951         rm -f $DIR/$tfile
8952 }
8953 run_test 105c "lockf when mounted without -o flock test"
8954
8955 test_105d() { # bug 15924
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957
8958         test_mkdir $DIR/$tdir
8959         flock_is_enabled || skip_env "mount w/o flock enabled"
8960         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8961         $LCTL set_param fail_loc=0x80000315
8962         flocks_test 2 $DIR/$tdir
8963 }
8964 run_test 105d "flock race (should not freeze) ========"
8965
8966 test_105e() { # bug 22660 && 22040
8967         flock_is_enabled || skip_env "mount w/o flock enabled"
8968
8969         touch $DIR/$tfile
8970         flocks_test 3 $DIR/$tfile
8971 }
8972 run_test 105e "Two conflicting flocks from same process"
8973
8974 test_106() { #bug 10921
8975         test_mkdir $DIR/$tdir
8976         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8977         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8978 }
8979 run_test 106 "attempt exec of dir followed by chown of that dir"
8980
8981 test_107() {
8982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8983
8984         CDIR=`pwd`
8985         local file=core
8986
8987         cd $DIR
8988         rm -f $file
8989
8990         local save_pattern=$(sysctl -n kernel.core_pattern)
8991         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8992         sysctl -w kernel.core_pattern=$file
8993         sysctl -w kernel.core_uses_pid=0
8994
8995         ulimit -c unlimited
8996         sleep 60 &
8997         SLEEPPID=$!
8998
8999         sleep 1
9000
9001         kill -s 11 $SLEEPPID
9002         wait $SLEEPPID
9003         if [ -e $file ]; then
9004                 size=`stat -c%s $file`
9005                 [ $size -eq 0 ] && error "Fail to create core file $file"
9006         else
9007                 error "Fail to create core file $file"
9008         fi
9009         rm -f $file
9010         sysctl -w kernel.core_pattern=$save_pattern
9011         sysctl -w kernel.core_uses_pid=$save_uses_pid
9012         cd $CDIR
9013 }
9014 run_test 107 "Coredump on SIG"
9015
9016 test_110() {
9017         test_mkdir $DIR/$tdir
9018         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9019         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9020                 error "mkdir with 256 char should fail, but did not"
9021         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9022                 error "create with 255 char failed"
9023         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9024                 error "create with 256 char should fail, but did not"
9025
9026         ls -l $DIR/$tdir
9027         rm -rf $DIR/$tdir
9028 }
9029 run_test 110 "filename length checking"
9030
9031 #
9032 # Purpose: To verify dynamic thread (OSS) creation.
9033 #
9034 test_115() {
9035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9036         remote_ost_nodsh && skip "remote OST with nodsh"
9037
9038         # Lustre does not stop service threads once they are started.
9039         # Reset number of running threads to default.
9040         stopall
9041         setupall
9042
9043         local OSTIO_pre
9044         local save_params="$TMP/sanity-$TESTNAME.parameters"
9045
9046         # Get ll_ost_io count before I/O
9047         OSTIO_pre=$(do_facet ost1 \
9048                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9049         # Exit if lustre is not running (ll_ost_io not running).
9050         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9051
9052         echo "Starting with $OSTIO_pre threads"
9053         local thread_max=$((OSTIO_pre * 2))
9054         local rpc_in_flight=$((thread_max * 2))
9055         # Number of I/O Process proposed to be started.
9056         local nfiles
9057         local facets=$(get_facets OST)
9058
9059         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9060         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9061
9062         # Set in_flight to $rpc_in_flight
9063         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9064                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9065         nfiles=${rpc_in_flight}
9066         # Set ost thread_max to $thread_max
9067         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9068
9069         # 5 Minutes should be sufficient for max number of OSS
9070         # threads(thread_max) to be created.
9071         local timeout=300
9072
9073         # Start I/O.
9074         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9075         test_mkdir $DIR/$tdir
9076         for i in $(seq $nfiles); do
9077                 local file=$DIR/$tdir/${tfile}-$i
9078                 $LFS setstripe -c -1 -i 0 $file
9079                 ($WTL $file $timeout)&
9080         done
9081
9082         # I/O Started - Wait for thread_started to reach thread_max or report
9083         # error if thread_started is more than thread_max.
9084         echo "Waiting for thread_started to reach thread_max"
9085         local thread_started=0
9086         local end_time=$((SECONDS + timeout))
9087
9088         while [ $SECONDS -le $end_time ] ; do
9089                 echo -n "."
9090                 # Get ost i/o thread_started count.
9091                 thread_started=$(do_facet ost1 \
9092                         "$LCTL get_param \
9093                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9094                 # Break out if thread_started is equal/greater than thread_max
9095                 if [[ $thread_started -ge $thread_max ]]; then
9096                         echo ll_ost_io thread_started $thread_started, \
9097                                 equal/greater than thread_max $thread_max
9098                         break
9099                 fi
9100                 sleep 1
9101         done
9102
9103         # Cleanup - We have the numbers, Kill i/o jobs if running.
9104         jobcount=($(jobs -p))
9105         for i in $(seq 0 $((${#jobcount[@]}-1)))
9106         do
9107                 kill -9 ${jobcount[$i]}
9108                 if [ $? -ne 0 ] ; then
9109                         echo Warning: \
9110                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9111                 fi
9112         done
9113
9114         # Cleanup files left by WTL binary.
9115         for i in $(seq $nfiles); do
9116                 local file=$DIR/$tdir/${tfile}-$i
9117                 rm -rf $file
9118                 if [ $? -ne 0 ] ; then
9119                         echo "Warning: Failed to delete file $file"
9120                 fi
9121         done
9122
9123         restore_lustre_params <$save_params
9124         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9125
9126         # Error out if no new thread has started or Thread started is greater
9127         # than thread max.
9128         if [[ $thread_started -le $OSTIO_pre ||
9129                         $thread_started -gt $thread_max ]]; then
9130                 error "ll_ost_io: thread_started $thread_started" \
9131                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9132                       "No new thread started or thread started greater " \
9133                       "than thread_max."
9134         fi
9135 }
9136 run_test 115 "verify dynamic thread creation===================="
9137
9138 free_min_max () {
9139         wait_delete_completed
9140         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9141         echo "OST kbytes available: ${AVAIL[@]}"
9142         MAXV=${AVAIL[0]}
9143         MAXI=0
9144         MINV=${AVAIL[0]}
9145         MINI=0
9146         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9147                 #echo OST $i: ${AVAIL[i]}kb
9148                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9149                         MAXV=${AVAIL[i]}
9150                         MAXI=$i
9151                 fi
9152                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9153                         MINV=${AVAIL[i]}
9154                         MINI=$i
9155                 fi
9156         done
9157         echo "Min free space: OST $MINI: $MINV"
9158         echo "Max free space: OST $MAXI: $MAXV"
9159 }
9160
9161 test_116a() { # was previously test_116()
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9164         remote_mds_nodsh && skip "remote MDS with nodsh"
9165
9166         echo -n "Free space priority "
9167         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9168                 head -n1
9169         declare -a AVAIL
9170         free_min_max
9171
9172         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9173         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9174         trap simple_cleanup_common EXIT
9175
9176         # Check if we need to generate uneven OSTs
9177         test_mkdir -p $DIR/$tdir/OST${MINI}
9178         local FILL=$((MINV / 4))
9179         local DIFF=$((MAXV - MINV))
9180         local DIFF2=$((DIFF * 100 / MINV))
9181
9182         local threshold=$(do_facet $SINGLEMDS \
9183                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9184         threshold=${threshold%%%}
9185         echo -n "Check for uneven OSTs: "
9186         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9187
9188         if [[ $DIFF2 -gt $threshold ]]; then
9189                 echo "ok"
9190                 echo "Don't need to fill OST$MINI"
9191         else
9192                 # generate uneven OSTs. Write 2% over the QOS threshold value
9193                 echo "no"
9194                 DIFF=$((threshold - DIFF2 + 2))
9195                 DIFF2=$((MINV * DIFF / 100))
9196                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9197                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9198                         error "setstripe failed"
9199                 DIFF=$((DIFF2 / 2048))
9200                 i=0
9201                 while [ $i -lt $DIFF ]; do
9202                         i=$((i + 1))
9203                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9204                                 bs=2M count=1 2>/dev/null
9205                         echo -n .
9206                 done
9207                 echo .
9208                 sync
9209                 sleep_maxage
9210                 free_min_max
9211         fi
9212
9213         DIFF=$((MAXV - MINV))
9214         DIFF2=$((DIFF * 100 / MINV))
9215         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9216         if [ $DIFF2 -gt $threshold ]; then
9217                 echo "ok"
9218         else
9219                 echo "failed - QOS mode won't be used"
9220                 simple_cleanup_common
9221                 skip "QOS imbalance criteria not met"
9222         fi
9223
9224         MINI1=$MINI
9225         MINV1=$MINV
9226         MAXI1=$MAXI
9227         MAXV1=$MAXV
9228
9229         # now fill using QOS
9230         $LFS setstripe -c 1 $DIR/$tdir
9231         FILL=$((FILL / 200))
9232         if [ $FILL -gt 600 ]; then
9233                 FILL=600
9234         fi
9235         echo "writing $FILL files to QOS-assigned OSTs"
9236         i=0
9237         while [ $i -lt $FILL ]; do
9238                 i=$((i + 1))
9239                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9240                         count=1 2>/dev/null
9241                 echo -n .
9242         done
9243         echo "wrote $i 200k files"
9244         sync
9245         sleep_maxage
9246
9247         echo "Note: free space may not be updated, so measurements might be off"
9248         free_min_max
9249         DIFF2=$((MAXV - MINV))
9250         echo "free space delta: orig $DIFF final $DIFF2"
9251         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9252         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9253         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9254         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9255         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9256         if [[ $DIFF -gt 0 ]]; then
9257                 FILL=$((DIFF2 * 100 / DIFF - 100))
9258                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9259         fi
9260
9261         # Figure out which files were written where
9262         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9263                awk '/'$MINI1': / {print $2; exit}')
9264         echo $UUID
9265         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9266         echo "$MINC files created on smaller OST $MINI1"
9267         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9268                awk '/'$MAXI1': / {print $2; exit}')
9269         echo $UUID
9270         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9271         echo "$MAXC files created on larger OST $MAXI1"
9272         if [[ $MINC -gt 0 ]]; then
9273                 FILL=$((MAXC * 100 / MINC - 100))
9274                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9275         fi
9276         [[ $MAXC -gt $MINC ]] ||
9277                 error_ignore LU-9 "stripe QOS didn't balance free space"
9278         simple_cleanup_common
9279 }
9280 run_test 116a "stripe QOS: free space balance ==================="
9281
9282 test_116b() { # LU-2093
9283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9284         remote_mds_nodsh && skip "remote MDS with nodsh"
9285
9286 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9287         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9288                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9289         [ -z "$old_rr" ] && skip "no QOS"
9290         do_facet $SINGLEMDS lctl set_param \
9291                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9292         mkdir -p $DIR/$tdir
9293         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9294         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9295         do_facet $SINGLEMDS lctl set_param fail_loc=0
9296         rm -rf $DIR/$tdir
9297         do_facet $SINGLEMDS lctl set_param \
9298                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9299 }
9300 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9301
9302 test_117() # bug 10891
9303 {
9304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9305
9306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9307         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9308         lctl set_param fail_loc=0x21e
9309         > $DIR/$tfile || error "truncate failed"
9310         lctl set_param fail_loc=0
9311         echo "Truncate succeeded."
9312         rm -f $DIR/$tfile
9313 }
9314 run_test 117 "verify osd extend =========="
9315
9316 NO_SLOW_RESENDCOUNT=4
9317 export OLD_RESENDCOUNT=""
9318 set_resend_count () {
9319         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9320         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9321         lctl set_param -n $PROC_RESENDCOUNT $1
9322         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9323 }
9324
9325 # for reduce test_118* time (b=14842)
9326 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9327
9328 # Reset async IO behavior after error case
9329 reset_async() {
9330         FILE=$DIR/reset_async
9331
9332         # Ensure all OSCs are cleared
9333         $LFS setstripe -c -1 $FILE
9334         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9335         sync
9336         rm $FILE
9337 }
9338
9339 test_118a() #bug 11710
9340 {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342
9343         reset_async
9344
9345         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9346         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9347         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9348
9349         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9350                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9351                 return 1;
9352         fi
9353         rm -f $DIR/$tfile
9354 }
9355 run_test 118a "verify O_SYNC works =========="
9356
9357 test_118b()
9358 {
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360         remote_ost_nodsh && skip "remote OST with nodsh"
9361
9362         reset_async
9363
9364         #define OBD_FAIL_SRV_ENOENT 0x217
9365         set_nodes_failloc "$(osts_nodes)" 0x217
9366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9367         RC=$?
9368         set_nodes_failloc "$(osts_nodes)" 0
9369         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9370         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9371                     grep -c writeback)
9372
9373         if [[ $RC -eq 0 ]]; then
9374                 error "Must return error due to dropped pages, rc=$RC"
9375                 return 1;
9376         fi
9377
9378         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9379                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9380                 return 1;
9381         fi
9382
9383         echo "Dirty pages not leaked on ENOENT"
9384
9385         # Due to the above error the OSC will issue all RPCs syncronously
9386         # until a subsequent RPC completes successfully without error.
9387         $MULTIOP $DIR/$tfile Ow4096yc
9388         rm -f $DIR/$tfile
9389
9390         return 0
9391 }
9392 run_test 118b "Reclaim dirty pages on fatal error =========="
9393
9394 test_118c()
9395 {
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397
9398         # for 118c, restore the original resend count, LU-1940
9399         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9400                                 set_resend_count $OLD_RESENDCOUNT
9401         remote_ost_nodsh && skip "remote OST with nodsh"
9402
9403         reset_async
9404
9405         #define OBD_FAIL_OST_EROFS               0x216
9406         set_nodes_failloc "$(osts_nodes)" 0x216
9407
9408         # multiop should block due to fsync until pages are written
9409         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9410         MULTIPID=$!
9411         sleep 1
9412
9413         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9414                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9415         fi
9416
9417         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9418                     grep -c writeback)
9419         if [[ $WRITEBACK -eq 0 ]]; then
9420                 error "No page in writeback, writeback=$WRITEBACK"
9421         fi
9422
9423         set_nodes_failloc "$(osts_nodes)" 0
9424         wait $MULTIPID
9425         RC=$?
9426         if [[ $RC -ne 0 ]]; then
9427                 error "Multiop fsync failed, rc=$RC"
9428         fi
9429
9430         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9431         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9432                     grep -c writeback)
9433         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9434                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9435         fi
9436
9437         rm -f $DIR/$tfile
9438         echo "Dirty pages flushed via fsync on EROFS"
9439         return 0
9440 }
9441 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9442
9443 # continue to use small resend count to reduce test_118* time (b=14842)
9444 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9445
9446 test_118d()
9447 {
9448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9449         remote_ost_nodsh && skip "remote OST with nodsh"
9450
9451         reset_async
9452
9453         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9454         set_nodes_failloc "$(osts_nodes)" 0x214
9455         # multiop should block due to fsync until pages are written
9456         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9457         MULTIPID=$!
9458         sleep 1
9459
9460         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9461                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9462         fi
9463
9464         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9465                     grep -c writeback)
9466         if [[ $WRITEBACK -eq 0 ]]; then
9467                 error "No page in writeback, writeback=$WRITEBACK"
9468         fi
9469
9470         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9471         set_nodes_failloc "$(osts_nodes)" 0
9472
9473         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9474         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9475                     grep -c writeback)
9476         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9477                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9478         fi
9479
9480         rm -f $DIR/$tfile
9481         echo "Dirty pages gaurenteed flushed via fsync"
9482         return 0
9483 }
9484 run_test 118d "Fsync validation inject a delay of the bulk =========="
9485
9486 test_118f() {
9487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9488
9489         reset_async
9490
9491         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9492         lctl set_param fail_loc=0x8000040a
9493
9494         # Should simulate EINVAL error which is fatal
9495         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9496         RC=$?
9497         if [[ $RC -eq 0 ]]; then
9498                 error "Must return error due to dropped pages, rc=$RC"
9499         fi
9500
9501         lctl set_param fail_loc=0x0
9502
9503         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9504         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9505         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9506                     grep -c writeback)
9507         if [[ $LOCKED -ne 0 ]]; then
9508                 error "Locked pages remain in cache, locked=$LOCKED"
9509         fi
9510
9511         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9512                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9513         fi
9514
9515         rm -f $DIR/$tfile
9516         echo "No pages locked after fsync"
9517
9518         reset_async
9519         return 0
9520 }
9521 run_test 118f "Simulate unrecoverable OSC side error =========="
9522
9523 test_118g() {
9524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9525
9526         reset_async
9527
9528         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9529         lctl set_param fail_loc=0x406
9530
9531         # simulate local -ENOMEM
9532         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9533         RC=$?
9534
9535         lctl set_param fail_loc=0
9536         if [[ $RC -eq 0 ]]; then
9537                 error "Must return error due to dropped pages, rc=$RC"
9538         fi
9539
9540         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9541         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9542         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9543                         grep -c writeback)
9544         if [[ $LOCKED -ne 0 ]]; then
9545                 error "Locked pages remain in cache, locked=$LOCKED"
9546         fi
9547
9548         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9549                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9550         fi
9551
9552         rm -f $DIR/$tfile
9553         echo "No pages locked after fsync"
9554
9555         reset_async
9556         return 0
9557 }
9558 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9559
9560 test_118h() {
9561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9562         remote_ost_nodsh && skip "remote OST with nodsh"
9563
9564         reset_async
9565
9566         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9567         set_nodes_failloc "$(osts_nodes)" 0x20e
9568         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9569         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9570         RC=$?
9571
9572         set_nodes_failloc "$(osts_nodes)" 0
9573         if [[ $RC -eq 0 ]]; then
9574                 error "Must return error due to dropped pages, rc=$RC"
9575         fi
9576
9577         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9578         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9579         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9580                     grep -c writeback)
9581         if [[ $LOCKED -ne 0 ]]; then
9582                 error "Locked pages remain in cache, locked=$LOCKED"
9583         fi
9584
9585         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9586                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9587         fi
9588
9589         rm -f $DIR/$tfile
9590         echo "No pages locked after fsync"
9591
9592         return 0
9593 }
9594 run_test 118h "Verify timeout in handling recoverables errors  =========="
9595
9596 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9597
9598 test_118i() {
9599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9600         remote_ost_nodsh && skip "remote OST with nodsh"
9601
9602         reset_async
9603
9604         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9605         set_nodes_failloc "$(osts_nodes)" 0x20e
9606
9607         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9608         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9609         PID=$!
9610         sleep 5
9611         set_nodes_failloc "$(osts_nodes)" 0
9612
9613         wait $PID
9614         RC=$?
9615         if [[ $RC -ne 0 ]]; then
9616                 error "got error, but should be not, rc=$RC"
9617         fi
9618
9619         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9620         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9621         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9622         if [[ $LOCKED -ne 0 ]]; then
9623                 error "Locked pages remain in cache, locked=$LOCKED"
9624         fi
9625
9626         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9627                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9628         fi
9629
9630         rm -f $DIR/$tfile
9631         echo "No pages locked after fsync"
9632
9633         return 0
9634 }
9635 run_test 118i "Fix error before timeout in recoverable error  =========="
9636
9637 [ "$SLOW" = "no" ] && set_resend_count 4
9638
9639 test_118j() {
9640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9641         remote_ost_nodsh && skip "remote OST with nodsh"
9642
9643         reset_async
9644
9645         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9646         set_nodes_failloc "$(osts_nodes)" 0x220
9647
9648         # return -EIO from OST
9649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9650         RC=$?
9651         set_nodes_failloc "$(osts_nodes)" 0x0
9652         if [[ $RC -eq 0 ]]; then
9653                 error "Must return error due to dropped pages, rc=$RC"
9654         fi
9655
9656         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9657         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9658         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9659         if [[ $LOCKED -ne 0 ]]; then
9660                 error "Locked pages remain in cache, locked=$LOCKED"
9661         fi
9662
9663         # in recoverable error on OST we want resend and stay until it finished
9664         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9665                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9666         fi
9667
9668         rm -f $DIR/$tfile
9669         echo "No pages locked after fsync"
9670
9671         return 0
9672 }
9673 run_test 118j "Simulate unrecoverable OST side error =========="
9674
9675 test_118k()
9676 {
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678         remote_ost_nodsh && skip "remote OSTs with nodsh"
9679
9680         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9681         set_nodes_failloc "$(osts_nodes)" 0x20e
9682         test_mkdir $DIR/$tdir
9683
9684         for ((i=0;i<10;i++)); do
9685                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9686                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9687                 SLEEPPID=$!
9688                 sleep 0.500s
9689                 kill $SLEEPPID
9690                 wait $SLEEPPID
9691         done
9692
9693         set_nodes_failloc "$(osts_nodes)" 0
9694         rm -rf $DIR/$tdir
9695 }
9696 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9697
9698 test_118l() # LU-646
9699 {
9700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9701
9702         test_mkdir $DIR/$tdir
9703         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9704         rm -rf $DIR/$tdir
9705 }
9706 run_test 118l "fsync dir"
9707
9708 test_118m() # LU-3066
9709 {
9710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9711
9712         test_mkdir $DIR/$tdir
9713         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9714         rm -rf $DIR/$tdir
9715 }
9716 run_test 118m "fdatasync dir ========="
9717
9718 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9719
9720 test_118n()
9721 {
9722         local begin
9723         local end
9724
9725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9726         remote_ost_nodsh && skip "remote OSTs with nodsh"
9727
9728         # Sleep to avoid a cached response.
9729         #define OBD_STATFS_CACHE_SECONDS 1
9730         sleep 2
9731
9732         # Inject a 10 second delay in the OST_STATFS handler.
9733         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9734         set_nodes_failloc "$(osts_nodes)" 0x242
9735
9736         begin=$SECONDS
9737         stat --file-system $MOUNT > /dev/null
9738         end=$SECONDS
9739
9740         set_nodes_failloc "$(osts_nodes)" 0
9741
9742         if ((end - begin > 20)); then
9743             error "statfs took $((end - begin)) seconds, expected 10"
9744         fi
9745 }
9746 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9747
9748 test_119a() # bug 11737
9749 {
9750         BSIZE=$((512 * 1024))
9751         directio write $DIR/$tfile 0 1 $BSIZE
9752         # We ask to read two blocks, which is more than a file size.
9753         # directio will indicate an error when requested and actual
9754         # sizes aren't equeal (a normal situation in this case) and
9755         # print actual read amount.
9756         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9757         if [ "$NOB" != "$BSIZE" ]; then
9758                 error "read $NOB bytes instead of $BSIZE"
9759         fi
9760         rm -f $DIR/$tfile
9761 }
9762 run_test 119a "Short directIO read must return actual read amount"
9763
9764 test_119b() # bug 11737
9765 {
9766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9767
9768         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9769         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9770         sync
9771         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9772                 error "direct read failed"
9773         rm -f $DIR/$tfile
9774 }
9775 run_test 119b "Sparse directIO read must return actual read amount"
9776
9777 test_119c() # bug 13099
9778 {
9779         BSIZE=1048576
9780         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9781         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9782         rm -f $DIR/$tfile
9783 }
9784 run_test 119c "Testing for direct read hitting hole"
9785
9786 test_119d() # bug 15950
9787 {
9788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9789
9790         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9791         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9792         BSIZE=1048576
9793         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9794         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9795         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9796         lctl set_param fail_loc=0x40d
9797         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9798         pid_dio=$!
9799         sleep 1
9800         cat $DIR/$tfile > /dev/null &
9801         lctl set_param fail_loc=0
9802         pid_reads=$!
9803         wait $pid_dio
9804         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9805         sleep 2
9806         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9807         error "the read rpcs have not completed in 2s"
9808         rm -f $DIR/$tfile
9809         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9810 }
9811 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9812
9813 test_120a() {
9814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9815         remote_mds_nodsh && skip "remote MDS with nodsh"
9816         test_mkdir -i0 -c1 $DIR/$tdir
9817         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9818                 skip_env "no early lock cancel on server"
9819
9820         lru_resize_disable mdc
9821         lru_resize_disable osc
9822         cancel_lru_locks mdc
9823         # asynchronous object destroy at MDT could cause bl ast to client
9824         cancel_lru_locks osc
9825
9826         stat $DIR/$tdir > /dev/null
9827         can1=$(do_facet mds1 \
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         test_mkdir -i0 -c1 $DIR/$tdir/d1
9833         can2=$(do_facet mds1 \
9834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9835                awk '/ldlm_cancel/ {print $2}')
9836         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9837                awk '/ldlm_bl_callback/ {print $2}')
9838         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9839         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9840         lru_resize_enable mdc
9841         lru_resize_enable osc
9842 }
9843 run_test 120a "Early Lock Cancel: mkdir test"
9844
9845 test_120b() {
9846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9847         remote_mds_nodsh && skip "remote MDS with nodsh"
9848         test_mkdir $DIR/$tdir
9849         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9850                 skip_env "no early lock cancel on server"
9851
9852         lru_resize_disable mdc
9853         lru_resize_disable osc
9854         cancel_lru_locks mdc
9855         stat $DIR/$tdir > /dev/null
9856         can1=$(do_facet $SINGLEMDS \
9857                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9858                awk '/ldlm_cancel/ {print $2}')
9859         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9860                awk '/ldlm_bl_callback/ {print $2}')
9861         touch $DIR/$tdir/f1
9862         can2=$(do_facet $SINGLEMDS \
9863                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9864                awk '/ldlm_cancel/ {print $2}')
9865         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9866                awk '/ldlm_bl_callback/ {print $2}')
9867         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9868         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9869         lru_resize_enable mdc
9870         lru_resize_enable osc
9871 }
9872 run_test 120b "Early Lock Cancel: create test"
9873
9874 test_120c() {
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876         remote_mds_nodsh && skip "remote MDS with nodsh"
9877         test_mkdir -i0 -c1 $DIR/$tdir
9878         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9879                 skip "no early lock cancel on server"
9880
9881         lru_resize_disable mdc
9882         lru_resize_disable osc
9883         test_mkdir -i0 -c1 $DIR/$tdir/d1
9884         test_mkdir -i0 -c1 $DIR/$tdir/d2
9885         touch $DIR/$tdir/d1/f1
9886         cancel_lru_locks mdc
9887         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9888         can1=$(do_facet mds1 \
9889                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9890                awk '/ldlm_cancel/ {print $2}')
9891         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9892                awk '/ldlm_bl_callback/ {print $2}')
9893         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9894         can2=$(do_facet mds1 \
9895                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9896                awk '/ldlm_cancel/ {print $2}')
9897         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9898                awk '/ldlm_bl_callback/ {print $2}')
9899         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9900         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9901         lru_resize_enable mdc
9902         lru_resize_enable osc
9903 }
9904 run_test 120c "Early Lock Cancel: link test"
9905
9906 test_120d() {
9907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9908         remote_mds_nodsh && skip "remote MDS with nodsh"
9909         test_mkdir -i0 -c1 $DIR/$tdir
9910         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9911                 skip_env "no early lock cancel on server"
9912
9913         lru_resize_disable mdc
9914         lru_resize_disable osc
9915         touch $DIR/$tdir
9916         cancel_lru_locks mdc
9917         stat $DIR/$tdir > /dev/null
9918         can1=$(do_facet mds1 \
9919                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9920                awk '/ldlm_cancel/ {print $2}')
9921         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9922                awk '/ldlm_bl_callback/ {print $2}')
9923         chmod a+x $DIR/$tdir
9924         can2=$(do_facet mds1 \
9925                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9926                awk '/ldlm_cancel/ {print $2}')
9927         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9928                awk '/ldlm_bl_callback/ {print $2}')
9929         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9930         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9931         lru_resize_enable mdc
9932         lru_resize_enable osc
9933 }
9934 run_test 120d "Early Lock Cancel: setattr test"
9935
9936 test_120e() {
9937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9938         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9939                 skip_env "no early lock cancel on server"
9940         remote_mds_nodsh && skip "remote MDS with nodsh"
9941
9942         local dlmtrace_set=false
9943
9944         test_mkdir -i0 -c1 $DIR/$tdir
9945         lru_resize_disable mdc
9946         lru_resize_disable osc
9947         ! $LCTL get_param debug | grep -q dlmtrace &&
9948                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9949         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9950         cancel_lru_locks mdc
9951         cancel_lru_locks osc
9952         dd if=$DIR/$tdir/f1 of=/dev/null
9953         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9954         # XXX client can not do early lock cancel of OST lock
9955         # during unlink (LU-4206), so cancel osc lock now.
9956         sleep 2
9957         cancel_lru_locks osc
9958         can1=$(do_facet mds1 \
9959                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9960                awk '/ldlm_cancel/ {print $2}')
9961         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9962                awk '/ldlm_bl_callback/ {print $2}')
9963         unlink $DIR/$tdir/f1
9964         sleep 5
9965         can2=$(do_facet mds1 \
9966                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9967                awk '/ldlm_cancel/ {print $2}')
9968         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9969                awk '/ldlm_bl_callback/ {print $2}')
9970         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9971                 $LCTL dk $TMP/cancel.debug.txt
9972         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9973                 $LCTL dk $TMP/blocking.debug.txt
9974         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9975         lru_resize_enable mdc
9976         lru_resize_enable osc
9977 }
9978 run_test 120e "Early Lock Cancel: unlink test"
9979
9980 test_120f() {
9981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9982         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9983                 skip_env "no early lock cancel on server"
9984         remote_mds_nodsh && skip "remote MDS with nodsh"
9985
9986         test_mkdir -i0 -c1 $DIR/$tdir
9987         lru_resize_disable mdc
9988         lru_resize_disable osc
9989         test_mkdir -i0 -c1 $DIR/$tdir/d1
9990         test_mkdir -i0 -c1 $DIR/$tdir/d2
9991         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9992         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9993         cancel_lru_locks mdc
9994         cancel_lru_locks osc
9995         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9996         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9997         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9998         # XXX client can not do early lock cancel of OST lock
9999         # during rename (LU-4206), so cancel osc lock now.
10000         sleep 2
10001         cancel_lru_locks osc
10002         can1=$(do_facet mds1 \
10003                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10004                awk '/ldlm_cancel/ {print $2}')
10005         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10006                awk '/ldlm_bl_callback/ {print $2}')
10007         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10008         sleep 5
10009         can2=$(do_facet mds1 \
10010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10011                awk '/ldlm_cancel/ {print $2}')
10012         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10013                awk '/ldlm_bl_callback/ {print $2}')
10014         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10015         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10016         lru_resize_enable mdc
10017         lru_resize_enable osc
10018 }
10019 run_test 120f "Early Lock Cancel: rename test"
10020
10021 test_120g() {
10022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10023         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10024                 skip_env "no early lock cancel on server"
10025         remote_mds_nodsh && skip "remote MDS with nodsh"
10026
10027         lru_resize_disable mdc
10028         lru_resize_disable osc
10029         count=10000
10030         echo create $count files
10031         test_mkdir $DIR/$tdir
10032         cancel_lru_locks mdc
10033         cancel_lru_locks osc
10034         t0=$(date +%s)
10035
10036         can0=$(do_facet $SINGLEMDS \
10037                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10038                awk '/ldlm_cancel/ {print $2}')
10039         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10040                awk '/ldlm_bl_callback/ {print $2}')
10041         createmany -o $DIR/$tdir/f $count
10042         sync
10043         can1=$(do_facet $SINGLEMDS \
10044                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10045                awk '/ldlm_cancel/ {print $2}')
10046         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10047                awk '/ldlm_bl_callback/ {print $2}')
10048         t1=$(date +%s)
10049         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10050         echo rm $count files
10051         rm -r $DIR/$tdir
10052         sync
10053         can2=$(do_facet $SINGLEMDS \
10054                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10055                awk '/ldlm_cancel/ {print $2}')
10056         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10057                awk '/ldlm_bl_callback/ {print $2}')
10058         t2=$(date +%s)
10059         echo total: $count removes in $((t2-t1))
10060         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10061         sleep 2
10062         # wait for commitment of removal
10063         lru_resize_enable mdc
10064         lru_resize_enable osc
10065 }
10066 run_test 120g "Early Lock Cancel: performance test"
10067
10068 test_121() { #bug #10589
10069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10070
10071         rm -rf $DIR/$tfile
10072         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10073 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10074         lctl set_param fail_loc=0x310
10075         cancel_lru_locks osc > /dev/null
10076         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10077         lctl set_param fail_loc=0
10078         [[ $reads -eq $writes ]] ||
10079                 error "read $reads blocks, must be $writes blocks"
10080 }
10081 run_test 121 "read cancel race ========="
10082
10083 test_123a() { # was test 123, statahead(bug 11401)
10084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10085
10086         SLOWOK=0
10087         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10088                 log "testing UP system. Performance may be lower than expected."
10089                 SLOWOK=1
10090         fi
10091
10092         rm -rf $DIR/$tdir
10093         test_mkdir $DIR/$tdir
10094         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10095         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10096         MULT=10
10097         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10098                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10099
10100                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10101                 lctl set_param -n llite.*.statahead_max 0
10102                 lctl get_param llite.*.statahead_max
10103                 cancel_lru_locks mdc
10104                 cancel_lru_locks osc
10105                 stime=`date +%s`
10106                 time ls -l $DIR/$tdir | wc -l
10107                 etime=`date +%s`
10108                 delta=$((etime - stime))
10109                 log "ls $i files without statahead: $delta sec"
10110                 lctl set_param llite.*.statahead_max=$max
10111
10112                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10113                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10114                 cancel_lru_locks mdc
10115                 cancel_lru_locks osc
10116                 stime=`date +%s`
10117                 time ls -l $DIR/$tdir | wc -l
10118                 etime=`date +%s`
10119                 delta_sa=$((etime - stime))
10120                 log "ls $i files with statahead: $delta_sa sec"
10121                 lctl get_param -n llite.*.statahead_stats
10122                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10123
10124                 [[ $swrong -lt $ewrong ]] &&
10125                         log "statahead was stopped, maybe too many locks held!"
10126                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10127
10128                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10129                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10130                     lctl set_param -n llite.*.statahead_max 0
10131                     lctl get_param llite.*.statahead_max
10132                     cancel_lru_locks mdc
10133                     cancel_lru_locks osc
10134                     stime=`date +%s`
10135                     time ls -l $DIR/$tdir | wc -l
10136                     etime=`date +%s`
10137                     delta=$((etime - stime))
10138                     log "ls $i files again without statahead: $delta sec"
10139                     lctl set_param llite.*.statahead_max=$max
10140                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10141                         if [  $SLOWOK -eq 0 ]; then
10142                                 error "ls $i files is slower with statahead!"
10143                         else
10144                                 log "ls $i files is slower with statahead!"
10145                         fi
10146                         break
10147                     fi
10148                 fi
10149
10150                 [ $delta -gt 20 ] && break
10151                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10152                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10153         done
10154         log "ls done"
10155
10156         stime=`date +%s`
10157         rm -r $DIR/$tdir
10158         sync
10159         etime=`date +%s`
10160         delta=$((etime - stime))
10161         log "rm -r $DIR/$tdir/: $delta seconds"
10162         log "rm done"
10163         lctl get_param -n llite.*.statahead_stats
10164 }
10165 run_test 123a "verify statahead work"
10166
10167 test_123b () { # statahead(bug 15027)
10168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10169
10170         test_mkdir $DIR/$tdir
10171         createmany -o $DIR/$tdir/$tfile-%d 1000
10172
10173         cancel_lru_locks mdc
10174         cancel_lru_locks osc
10175
10176 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10177         lctl set_param fail_loc=0x80000803
10178         ls -lR $DIR/$tdir > /dev/null
10179         log "ls done"
10180         lctl set_param fail_loc=0x0
10181         lctl get_param -n llite.*.statahead_stats
10182         rm -r $DIR/$tdir
10183         sync
10184
10185 }
10186 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10187
10188 test_124a() {
10189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10190         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10191                 skip_env "no lru resize on server"
10192
10193         local NR=2000
10194
10195         test_mkdir $DIR/$tdir
10196
10197         log "create $NR files at $DIR/$tdir"
10198         createmany -o $DIR/$tdir/f $NR ||
10199                 error "failed to create $NR files in $DIR/$tdir"
10200
10201         cancel_lru_locks mdc
10202         ls -l $DIR/$tdir > /dev/null
10203
10204         local NSDIR=""
10205         local LRU_SIZE=0
10206         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10207                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10208                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10209                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10210                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10211                         log "NSDIR=$NSDIR"
10212                         log "NS=$(basename $NSDIR)"
10213                         break
10214                 fi
10215         done
10216
10217         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10218                 skip "Not enough cached locks created!"
10219         fi
10220         log "LRU=$LRU_SIZE"
10221
10222         local SLEEP=30
10223
10224         # We know that lru resize allows one client to hold $LIMIT locks
10225         # for 10h. After that locks begin to be killed by client.
10226         local MAX_HRS=10
10227         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10228         log "LIMIT=$LIMIT"
10229         if [ $LIMIT -lt $LRU_SIZE ]; then
10230                 skip "Limit is too small $LIMIT"
10231         fi
10232
10233         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10234         # killing locks. Some time was spent for creating locks. This means
10235         # that up to the moment of sleep finish we must have killed some of
10236         # them (10-100 locks). This depends on how fast ther were created.
10237         # Many of them were touched in almost the same moment and thus will
10238         # be killed in groups.
10239         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10240
10241         # Use $LRU_SIZE_B here to take into account real number of locks
10242         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10243         local LRU_SIZE_B=$LRU_SIZE
10244         log "LVF=$LVF"
10245         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10246         log "OLD_LVF=$OLD_LVF"
10247         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10248
10249         # Let's make sure that we really have some margin. Client checks
10250         # cached locks every 10 sec.
10251         SLEEP=$((SLEEP+20))
10252         log "Sleep ${SLEEP} sec"
10253         local SEC=0
10254         while ((SEC<$SLEEP)); do
10255                 echo -n "..."
10256                 sleep 5
10257                 SEC=$((SEC+5))
10258                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10259                 echo -n "$LRU_SIZE"
10260         done
10261         echo ""
10262         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10263         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10264
10265         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10266                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10267                 unlinkmany $DIR/$tdir/f $NR
10268                 return
10269         }
10270
10271         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10272         log "unlink $NR files at $DIR/$tdir"
10273         unlinkmany $DIR/$tdir/f $NR
10274 }
10275 run_test 124a "lru resize ======================================="
10276
10277 get_max_pool_limit()
10278 {
10279         local limit=$($LCTL get_param \
10280                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10281         local max=0
10282         for l in $limit; do
10283                 if [[ $l -gt $max ]]; then
10284                         max=$l
10285                 fi
10286         done
10287         echo $max
10288 }
10289
10290 test_124b() {
10291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10292         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10293                 skip_env "no lru resize on server"
10294
10295         LIMIT=$(get_max_pool_limit)
10296
10297         NR=$(($(default_lru_size)*20))
10298         if [[ $NR -gt $LIMIT ]]; then
10299                 log "Limit lock number by $LIMIT locks"
10300                 NR=$LIMIT
10301         fi
10302
10303         IFree=$(mdsrate_inodes_available)
10304         if [ $IFree -lt $NR ]; then
10305                 log "Limit lock number by $IFree inodes"
10306                 NR=$IFree
10307         fi
10308
10309         lru_resize_disable mdc
10310         test_mkdir -p $DIR/$tdir/disable_lru_resize
10311
10312         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10313         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10314         cancel_lru_locks mdc
10315         stime=`date +%s`
10316         PID=""
10317         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10318         PID="$PID $!"
10319         sleep 2
10320         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10321         PID="$PID $!"
10322         sleep 2
10323         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10324         PID="$PID $!"
10325         wait $PID
10326         etime=`date +%s`
10327         nolruresize_delta=$((etime-stime))
10328         log "ls -la time: $nolruresize_delta seconds"
10329         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10330         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10331
10332         lru_resize_enable mdc
10333         test_mkdir -p $DIR/$tdir/enable_lru_resize
10334
10335         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10336         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10337         cancel_lru_locks mdc
10338         stime=`date +%s`
10339         PID=""
10340         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10341         PID="$PID $!"
10342         sleep 2
10343         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10344         PID="$PID $!"
10345         sleep 2
10346         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10347         PID="$PID $!"
10348         wait $PID
10349         etime=`date +%s`
10350         lruresize_delta=$((etime-stime))
10351         log "ls -la time: $lruresize_delta seconds"
10352         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10353
10354         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10355                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10356         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10357                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10358         else
10359                 log "lru resize performs the same with no lru resize"
10360         fi
10361         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10362 }
10363 run_test 124b "lru resize (performance test) ======================="
10364
10365 test_124c() {
10366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10367         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10368                 skip_env "no lru resize on server"
10369
10370         # cache ununsed locks on client
10371         local nr=100
10372         cancel_lru_locks mdc
10373         test_mkdir $DIR/$tdir
10374         createmany -o $DIR/$tdir/f $nr ||
10375                 error "failed to create $nr files in $DIR/$tdir"
10376         ls -l $DIR/$tdir > /dev/null
10377
10378         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10379         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10380         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10381         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10382         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10383
10384         # set lru_max_age to 1 sec
10385         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10386         echo "sleep $((recalc_p * 2)) seconds..."
10387         sleep $((recalc_p * 2))
10388
10389         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10390         # restore lru_max_age
10391         $LCTL set_param -n $nsdir.lru_max_age $max_age
10392         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10393         unlinkmany $DIR/$tdir/f $nr
10394 }
10395 run_test 124c "LRUR cancel very aged locks"
10396
10397 test_125() { # 13358
10398         $LCTL get_param -n llite.*.client_type | grep -q local ||
10399                 skip "must run as local client"
10400         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10401                 skip_env "must have acl enabled"
10402         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10403
10404         test_mkdir $DIR/$tdir
10405         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10406         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10407         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10408 }
10409 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10410
10411 test_126() { # bug 12829/13455
10412         $GSS && skip_env "must run as gss disabled"
10413         $LCTL get_param -n llite.*.client_type | grep -q local ||
10414                 skip "must run as local client"
10415         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10416
10417         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10418         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10419         rm -f $DIR/$tfile
10420         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10421 }
10422 run_test 126 "check that the fsgid provided by the client is taken into account"
10423
10424 test_127a() { # bug 15521
10425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10426
10427         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10428         $LCTL set_param osc.*.stats=0
10429         FSIZE=$((2048 * 1024))
10430         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10431         cancel_lru_locks osc
10432         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10433
10434         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10435         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10436                 echo "got $COUNT $NAME"
10437                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10438                 eval $NAME=$COUNT || error "Wrong proc format"
10439
10440                 case $NAME in
10441                         read_bytes|write_bytes)
10442                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10443                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10444                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10445                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10446                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10447                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10448                                 error "sumsquare is too small: $SUMSQ"
10449                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10450                                 error "sumsquare is too big: $SUMSQ"
10451                         ;;
10452                         *) ;;
10453                 esac
10454         done < $DIR/${tfile}.tmp
10455
10456         #check that we actually got some stats
10457         [ "$read_bytes" ] || error "Missing read_bytes stats"
10458         [ "$write_bytes" ] || error "Missing write_bytes stats"
10459         [ "$read_bytes" != 0 ] || error "no read done"
10460         [ "$write_bytes" != 0 ] || error "no write done"
10461 }
10462 run_test 127a "verify the client stats are sane"
10463
10464 test_127b() { # bug LU-333
10465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10466         local name count samp unit min max sum sumsq
10467
10468         $LCTL set_param llite.*.stats=0
10469
10470         # perform 2 reads and writes so MAX is different from SUM.
10471         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10472         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10473         cancel_lru_locks osc
10474         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10475         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10476
10477         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10478         while read name count samp unit min max sum sumsq; do
10479                 echo "got $count $name"
10480                 eval $name=$count || error "Wrong proc format"
10481
10482                 case $name in
10483                 read_bytes)
10484                         [ $count -ne 2 ] && error "count is not 2: $count"
10485                         [ $min -ne $PAGE_SIZE ] &&
10486                                 error "min is not $PAGE_SIZE: $min"
10487                         [ $max -ne $PAGE_SIZE ] &&
10488                                 error "max is incorrect: $max"
10489                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10490                                 error "sum is wrong: $sum"
10491                         ;;
10492                 write_bytes)
10493                         [ $count -ne 2 ] && error "count is not 2: $count"
10494                         [ $min -ne $PAGE_SIZE ] &&
10495                                 error "min is not $PAGE_SIZE: $min"
10496                         [ $max -ne $PAGE_SIZE ] &&
10497                                 error "max is incorrect: $max"
10498                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10499                                 error "sum is wrong: $sum"
10500                         ;;
10501                 *) ;;
10502                 esac
10503         done < $TMP/$tfile.tmp
10504
10505         #check that we actually got some stats
10506         [ "$read_bytes" ] || error "Missing read_bytes stats"
10507         [ "$write_bytes" ] || error "Missing write_bytes stats"
10508         [ "$read_bytes" != 0 ] || error "no read done"
10509         [ "$write_bytes" != 0 ] || error "no write done"
10510
10511         rm -f $TMP/${tfile}.tmp
10512 }
10513 run_test 127b "verify the llite client stats are sane"
10514
10515 test_128() { # bug 15212
10516         touch $DIR/$tfile
10517         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10518                 find $DIR/$tfile
10519                 find $DIR/$tfile
10520         EOF
10521
10522         result=$(grep error $TMP/$tfile.log)
10523         rm -f $DIR/$tfile $TMP/$tfile.log
10524         [ -z "$result" ] ||
10525                 error "consecutive find's under interactive lfs failed"
10526 }
10527 run_test 128 "interactive lfs for 2 consecutive find's"
10528
10529 set_dir_limits () {
10530         local mntdev
10531         local canondev
10532         local node
10533
10534         local ldproc=/proc/fs/ldiskfs
10535         local facets=$(get_facets MDS)
10536
10537         for facet in ${facets//,/ }; do
10538                 canondev=$(ldiskfs_canon \
10539                            *.$(convert_facet2label $facet).mntdev $facet)
10540                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10541                         ldproc=/sys/fs/ldiskfs
10542                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10543                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10544         done
10545 }
10546
10547 check_mds_dmesg() {
10548         local facets=$(get_facets MDS)
10549         for facet in ${facets//,/ }; do
10550                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10551         done
10552         return 1
10553 }
10554
10555 test_129() {
10556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10557         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10558                 skip "Need MDS version with at least 2.5.56"
10559         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10560                 skip_env "ldiskfs only test"
10561         fi
10562         remote_mds_nodsh && skip "remote MDS with nodsh"
10563
10564         local ENOSPC=28
10565         local EFBIG=27
10566         local has_warning=false
10567
10568         rm -rf $DIR/$tdir
10569         mkdir -p $DIR/$tdir
10570
10571         # block size of mds1
10572         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10573         set_dir_limits $maxsize $maxsize
10574         local dirsize=$(stat -c%s "$DIR/$tdir")
10575         local nfiles=0
10576         while [[ $dirsize -le $maxsize ]]; do
10577                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10578                 rc=$?
10579                 if ! $has_warning; then
10580                         check_mds_dmesg '"is approaching"' && has_warning=true
10581                 fi
10582                 # check two errors:
10583                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10584                 # EFBIG for previous versions included in ldiskfs series
10585                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10586                         set_dir_limits 0 0
10587                         echo "return code $rc received as expected"
10588
10589                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10590                                 error_exit "create failed w/o dir size limit"
10591
10592                         check_mds_dmesg '"has reached"' ||
10593                                 error_exit "reached message should be output"
10594
10595                         [ $has_warning = "false" ] &&
10596                                 error_exit "warning message should be output"
10597
10598                         dirsize=$(stat -c%s "$DIR/$tdir")
10599
10600                         [[ $dirsize -ge $maxsize ]] && return 0
10601                         error_exit "current dir size $dirsize, " \
10602                                    "previous limit $maxsize"
10603                 elif [ $rc -ne 0 ]; then
10604                         set_dir_limits 0 0
10605                         error_exit "return $rc received instead of expected " \
10606                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10607                 fi
10608                 nfiles=$((nfiles + 1))
10609                 dirsize=$(stat -c%s "$DIR/$tdir")
10610         done
10611
10612         set_dir_limits 0 0
10613         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10614 }
10615 run_test 129 "test directory size limit ========================"
10616
10617 OLDIFS="$IFS"
10618 cleanup_130() {
10619         trap 0
10620         IFS="$OLDIFS"
10621 }
10622
10623 test_130a() {
10624         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10625         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10626
10627         trap cleanup_130 EXIT RETURN
10628
10629         local fm_file=$DIR/$tfile
10630         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10631         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10632                 error "dd failed for $fm_file"
10633
10634         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10635         filefrag -ves $fm_file
10636         RC=$?
10637         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10638                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10639         [ $RC != 0 ] && error "filefrag $fm_file failed"
10640
10641         filefrag_op=$(filefrag -ve -k $fm_file |
10642                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10643         lun=$($LFS getstripe -i $fm_file)
10644
10645         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10646         IFS=$'\n'
10647         tot_len=0
10648         for line in $filefrag_op
10649         do
10650                 frag_lun=`echo $line | cut -d: -f5`
10651                 ext_len=`echo $line | cut -d: -f4`
10652                 if (( $frag_lun != $lun )); then
10653                         cleanup_130
10654                         error "FIEMAP on 1-stripe file($fm_file) failed"
10655                         return
10656                 fi
10657                 (( tot_len += ext_len ))
10658         done
10659
10660         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10661                 cleanup_130
10662                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10663                 return
10664         fi
10665
10666         cleanup_130
10667
10668         echo "FIEMAP on single striped file succeeded"
10669 }
10670 run_test 130a "FIEMAP (1-stripe file)"
10671
10672 test_130b() {
10673         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10674
10675         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10676         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10677
10678         trap cleanup_130 EXIT RETURN
10679
10680         local fm_file=$DIR/$tfile
10681         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10682                         error "setstripe on $fm_file"
10683         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10684                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10685
10686         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10687                 error "dd failed on $fm_file"
10688
10689         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10690         filefrag_op=$(filefrag -ve -k $fm_file |
10691                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10692
10693         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10694                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10695
10696         IFS=$'\n'
10697         tot_len=0
10698         num_luns=1
10699         for line in $filefrag_op
10700         do
10701                 frag_lun=$(echo $line | cut -d: -f5 |
10702                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10703                 ext_len=$(echo $line | cut -d: -f4)
10704                 if (( $frag_lun != $last_lun )); then
10705                         if (( tot_len != 1024 )); then
10706                                 cleanup_130
10707                                 error "FIEMAP on $fm_file failed; returned " \
10708                                 "len $tot_len for OST $last_lun instead of 1024"
10709                                 return
10710                         else
10711                                 (( num_luns += 1 ))
10712                                 tot_len=0
10713                         fi
10714                 fi
10715                 (( tot_len += ext_len ))
10716                 last_lun=$frag_lun
10717         done
10718         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10719                 cleanup_130
10720                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10721                         "luns or wrong len for OST $last_lun"
10722                 return
10723         fi
10724
10725         cleanup_130
10726
10727         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10728 }
10729 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10730
10731 test_130c() {
10732         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10733
10734         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10735         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10736
10737         trap cleanup_130 EXIT RETURN
10738
10739         local fm_file=$DIR/$tfile
10740         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10741         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10742                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10743
10744         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10745                         error "dd failed on $fm_file"
10746
10747         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10748         filefrag_op=$(filefrag -ve -k $fm_file |
10749                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10750
10751         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10752                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10753
10754         IFS=$'\n'
10755         tot_len=0
10756         num_luns=1
10757         for line in $filefrag_op
10758         do
10759                 frag_lun=$(echo $line | cut -d: -f5 |
10760                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10761                 ext_len=$(echo $line | cut -d: -f4)
10762                 if (( $frag_lun != $last_lun )); then
10763                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10764                         if (( logical != 512 )); then
10765                                 cleanup_130
10766                                 error "FIEMAP on $fm_file failed; returned " \
10767                                 "logical start for lun $logical instead of 512"
10768                                 return
10769                         fi
10770                         if (( tot_len != 512 )); then
10771                                 cleanup_130
10772                                 error "FIEMAP on $fm_file failed; returned " \
10773                                 "len $tot_len for OST $last_lun instead of 1024"
10774                                 return
10775                         else
10776                                 (( num_luns += 1 ))
10777                                 tot_len=0
10778                         fi
10779                 fi
10780                 (( tot_len += ext_len ))
10781                 last_lun=$frag_lun
10782         done
10783         if (( num_luns != 2 || tot_len != 512 )); then
10784                 cleanup_130
10785                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10786                         "luns or wrong len for OST $last_lun"
10787                 return
10788         fi
10789
10790         cleanup_130
10791
10792         echo "FIEMAP on 2-stripe file with hole succeeded"
10793 }
10794 run_test 130c "FIEMAP (2-stripe file with hole)"
10795
10796 test_130d() {
10797         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10798
10799         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10800         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10801
10802         trap cleanup_130 EXIT RETURN
10803
10804         local fm_file=$DIR/$tfile
10805         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10806                         error "setstripe on $fm_file"
10807         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10808                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10809
10810         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10811         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10812                 error "dd failed on $fm_file"
10813
10814         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10815         filefrag_op=$(filefrag -ve -k $fm_file |
10816                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10817
10818         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10819                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10820
10821         IFS=$'\n'
10822         tot_len=0
10823         num_luns=1
10824         for line in $filefrag_op
10825         do
10826                 frag_lun=$(echo $line | cut -d: -f5 |
10827                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10828                 ext_len=$(echo $line | cut -d: -f4)
10829                 if (( $frag_lun != $last_lun )); then
10830                         if (( tot_len != 1024 )); then
10831                                 cleanup_130
10832                                 error "FIEMAP on $fm_file failed; returned " \
10833                                 "len $tot_len for OST $last_lun instead of 1024"
10834                                 return
10835                         else
10836                                 (( num_luns += 1 ))
10837                                 tot_len=0
10838                         fi
10839                 fi
10840                 (( tot_len += ext_len ))
10841                 last_lun=$frag_lun
10842         done
10843         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10844                 cleanup_130
10845                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10846                         "luns or wrong len for OST $last_lun"
10847                 return
10848         fi
10849
10850         cleanup_130
10851
10852         echo "FIEMAP on N-stripe file succeeded"
10853 }
10854 run_test 130d "FIEMAP (N-stripe file)"
10855
10856 test_130e() {
10857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10858
10859         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10860         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10861
10862         trap cleanup_130 EXIT RETURN
10863
10864         local fm_file=$DIR/$tfile
10865         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10866         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10867                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10868
10869         NUM_BLKS=512
10870         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10871         for ((i = 0; i < $NUM_BLKS; i++))
10872         do
10873                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10874         done
10875
10876         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10877         filefrag_op=$(filefrag -ve -k $fm_file |
10878                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10879
10880         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10881                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10882
10883         IFS=$'\n'
10884         tot_len=0
10885         num_luns=1
10886         for line in $filefrag_op
10887         do
10888                 frag_lun=$(echo $line | cut -d: -f5 |
10889                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10890                 ext_len=$(echo $line | cut -d: -f4)
10891                 if (( $frag_lun != $last_lun )); then
10892                         if (( tot_len != $EXPECTED_LEN )); then
10893                                 cleanup_130
10894                                 error "FIEMAP on $fm_file failed; returned " \
10895                                 "len $tot_len for OST $last_lun instead " \
10896                                 "of $EXPECTED_LEN"
10897                                 return
10898                         else
10899                                 (( num_luns += 1 ))
10900                                 tot_len=0
10901                         fi
10902                 fi
10903                 (( tot_len += ext_len ))
10904                 last_lun=$frag_lun
10905         done
10906         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10907                 cleanup_130
10908                 error "FIEMAP on $fm_file failed; returned wrong number " \
10909                         "of luns or wrong len for OST $last_lun"
10910                 return
10911         fi
10912
10913         cleanup_130
10914
10915         echo "FIEMAP with continuation calls succeeded"
10916 }
10917 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10918
10919 test_130f() {
10920         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10921         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10922
10923         local fm_file=$DIR/$tfile
10924         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10925                 error "multiop create with lov_delay_create on $fm_file"
10926
10927         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10928         filefrag_extents=$(filefrag -vek $fm_file |
10929                            awk '/extents? found/ { print $2 }')
10930         if [[ "$filefrag_extents" != "0" ]]; then
10931                 error "FIEMAP on $fm_file failed; " \
10932                       "returned $filefrag_extents expected 0"
10933         fi
10934
10935         rm -f $fm_file
10936 }
10937 run_test 130f "FIEMAP (unstriped file)"
10938
10939 # Test for writev/readv
10940 test_131a() {
10941         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10942                 error "writev test failed"
10943         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10944                 error "readv failed"
10945         rm -f $DIR/$tfile
10946 }
10947 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10948
10949 test_131b() {
10950         local fsize=$((524288 + 1048576 + 1572864))
10951         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10952                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10953                         error "append writev test failed"
10954
10955         ((fsize += 1572864 + 1048576))
10956         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10957                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10958                         error "append writev test failed"
10959         rm -f $DIR/$tfile
10960 }
10961 run_test 131b "test append writev"
10962
10963 test_131c() {
10964         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10965         error "NOT PASS"
10966 }
10967 run_test 131c "test read/write on file w/o objects"
10968
10969 test_131d() {
10970         rwv -f $DIR/$tfile -w -n 1 1572864
10971         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10972         if [ "$NOB" != 1572864 ]; then
10973                 error "Short read filed: read $NOB bytes instead of 1572864"
10974         fi
10975         rm -f $DIR/$tfile
10976 }
10977 run_test 131d "test short read"
10978
10979 test_131e() {
10980         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10981         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10982         error "read hitting hole failed"
10983         rm -f $DIR/$tfile
10984 }
10985 run_test 131e "test read hitting hole"
10986
10987 check_stats() {
10988         local facet=$1
10989         local op=$2
10990         local want=${3:-0}
10991         local res
10992
10993         case $facet in
10994         mds*) res=$(do_facet $facet \
10995                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10996                  ;;
10997         ost*) res=$(do_facet $facet \
10998                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10999                  ;;
11000         *) error "Wrong facet '$facet'" ;;
11001         esac
11002         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11003         # if the argument $3 is zero, it means any stat increment is ok.
11004         if [[ $want -gt 0 ]]; then
11005                 local count=$(echo $res | awk '{ print $2 }')
11006                 [[ $count -ne $want ]] &&
11007                         error "The $op counter on $facet is $count, not $want"
11008         fi
11009 }
11010
11011 test_133a() {
11012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11013         remote_ost_nodsh && skip "remote OST with nodsh"
11014         remote_mds_nodsh && skip "remote MDS with nodsh"
11015         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11016                 skip_env "MDS doesn't support rename stats"
11017
11018         local testdir=$DIR/${tdir}/stats_testdir
11019
11020         mkdir -p $DIR/${tdir}
11021
11022         # clear stats.
11023         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11024         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11025
11026         # verify mdt stats first.
11027         mkdir ${testdir} || error "mkdir failed"
11028         check_stats $SINGLEMDS "mkdir" 1
11029         touch ${testdir}/${tfile} || error "touch failed"
11030         check_stats $SINGLEMDS "open" 1
11031         check_stats $SINGLEMDS "close" 1
11032         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11033                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11034                 check_stats $SINGLEMDS "mknod" 2
11035         }
11036         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11037         check_stats $SINGLEMDS "unlink" 1
11038         rm -f ${testdir}/${tfile} || error "file remove failed"
11039         check_stats $SINGLEMDS "unlink" 2
11040
11041         # remove working dir and check mdt stats again.
11042         rmdir ${testdir} || error "rmdir failed"
11043         check_stats $SINGLEMDS "rmdir" 1
11044
11045         local testdir1=$DIR/${tdir}/stats_testdir1
11046         mkdir -p ${testdir}
11047         mkdir -p ${testdir1}
11048         touch ${testdir1}/test1
11049         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11050         check_stats $SINGLEMDS "crossdir_rename" 1
11051
11052         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11053         check_stats $SINGLEMDS "samedir_rename" 1
11054
11055         rm -rf $DIR/${tdir}
11056 }
11057 run_test 133a "Verifying MDT stats ========================================"
11058
11059 test_133b() {
11060         local res
11061
11062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11063         remote_ost_nodsh && skip "remote OST with nodsh"
11064         remote_mds_nodsh && skip "remote MDS with nodsh"
11065
11066         local testdir=$DIR/${tdir}/stats_testdir
11067
11068         mkdir -p ${testdir} || error "mkdir failed"
11069         touch ${testdir}/${tfile} || error "touch failed"
11070         cancel_lru_locks mdc
11071
11072         # clear stats.
11073         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11074         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11075
11076         # extra mdt stats verification.
11077         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11078         check_stats $SINGLEMDS "setattr" 1
11079         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11080         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11081         then            # LU-1740
11082                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11083                 check_stats $SINGLEMDS "getattr" 1
11084         fi
11085         rm -rf $DIR/${tdir}
11086
11087         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11088         # so the check below is not reliable
11089         [ $MDSCOUNT -eq 1 ] || return 0
11090
11091         # Sleep to avoid a cached response.
11092         #define OBD_STATFS_CACHE_SECONDS 1
11093         sleep 2
11094         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11095         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11096         $LFS df || error "lfs failed"
11097         check_stats $SINGLEMDS "statfs" 1
11098
11099         # check aggregated statfs (LU-10018)
11100         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11101                 return 0
11102         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11103                 return 0
11104         sleep 2
11105         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11106         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11107         df $DIR
11108         check_stats $SINGLEMDS "statfs" 1
11109
11110         # We want to check that the client didn't send OST_STATFS to
11111         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11112         # extra care is needed here.
11113         if remote_mds; then
11114                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11115                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11116
11117                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11118                 [ "$res" ] && error "OST got STATFS"
11119         fi
11120
11121         return 0
11122 }
11123 run_test 133b "Verifying extra MDT stats =================================="
11124
11125 test_133c() {
11126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11127         remote_ost_nodsh && skip "remote OST with nodsh"
11128         remote_mds_nodsh && skip "remote MDS with nodsh"
11129
11130         local testdir=$DIR/$tdir/stats_testdir
11131
11132         test_mkdir -p $testdir
11133
11134         # verify obdfilter stats.
11135         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11136         sync
11137         cancel_lru_locks osc
11138         wait_delete_completed
11139
11140         # clear stats.
11141         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11142         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11143
11144         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11145                 error "dd failed"
11146         sync
11147         cancel_lru_locks osc
11148         check_stats ost1 "write" 1
11149
11150         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11151         check_stats ost1 "read" 1
11152
11153         > $testdir/$tfile || error "truncate failed"
11154         check_stats ost1 "punch" 1
11155
11156         rm -f $testdir/$tfile || error "file remove failed"
11157         wait_delete_completed
11158         check_stats ost1 "destroy" 1
11159
11160         rm -rf $DIR/$tdir
11161 }
11162 run_test 133c "Verifying OST stats ========================================"
11163
11164 order_2() {
11165         local value=$1
11166         local orig=$value
11167         local order=1
11168
11169         while [ $value -ge 2 ]; do
11170                 order=$((order*2))
11171                 value=$((value/2))
11172         done
11173
11174         if [ $orig -gt $order ]; then
11175                 order=$((order*2))
11176         fi
11177         echo $order
11178 }
11179
11180 size_in_KMGT() {
11181     local value=$1
11182     local size=('K' 'M' 'G' 'T');
11183     local i=0
11184     local size_string=$value
11185
11186     while [ $value -ge 1024 ]; do
11187         if [ $i -gt 3 ]; then
11188             #T is the biggest unit we get here, if that is bigger,
11189             #just return XXXT
11190             size_string=${value}T
11191             break
11192         fi
11193         value=$((value >> 10))
11194         if [ $value -lt 1024 ]; then
11195             size_string=${value}${size[$i]}
11196             break
11197         fi
11198         i=$((i + 1))
11199     done
11200
11201     echo $size_string
11202 }
11203
11204 get_rename_size() {
11205         local size=$1
11206         local context=${2:-.}
11207         local sample=$(do_facet $SINGLEMDS $LCTL \
11208                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11209                 grep -A1 $context |
11210                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11211         echo $sample
11212 }
11213
11214 test_133d() {
11215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11216         remote_ost_nodsh && skip "remote OST with nodsh"
11217         remote_mds_nodsh && skip "remote MDS with nodsh"
11218         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11219                 skip_env "MDS doesn't support rename stats"
11220
11221         local testdir1=$DIR/${tdir}/stats_testdir1
11222         local testdir2=$DIR/${tdir}/stats_testdir2
11223         mkdir -p $DIR/${tdir}
11224
11225         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11226
11227         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11228         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11229
11230         createmany -o $testdir1/test 512 || error "createmany failed"
11231
11232         # check samedir rename size
11233         mv ${testdir1}/test0 ${testdir1}/test_0
11234
11235         local testdir1_size=$(ls -l $DIR/${tdir} |
11236                 awk '/stats_testdir1/ {print $5}')
11237         local testdir2_size=$(ls -l $DIR/${tdir} |
11238                 awk '/stats_testdir2/ {print $5}')
11239
11240         testdir1_size=$(order_2 $testdir1_size)
11241         testdir2_size=$(order_2 $testdir2_size)
11242
11243         testdir1_size=$(size_in_KMGT $testdir1_size)
11244         testdir2_size=$(size_in_KMGT $testdir2_size)
11245
11246         echo "source rename dir size: ${testdir1_size}"
11247         echo "target rename dir size: ${testdir2_size}"
11248
11249         local cmd="do_facet $SINGLEMDS $LCTL "
11250         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11251
11252         eval $cmd || error "$cmd failed"
11253         local samedir=$($cmd | grep 'same_dir')
11254         local same_sample=$(get_rename_size $testdir1_size)
11255         [ -z "$samedir" ] && error "samedir_rename_size count error"
11256         [[ $same_sample -eq 1 ]] ||
11257                 error "samedir_rename_size error $same_sample"
11258         echo "Check same dir rename stats success"
11259
11260         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11261
11262         # check crossdir rename size
11263         mv ${testdir1}/test_0 ${testdir2}/test_0
11264
11265         testdir1_size=$(ls -l $DIR/${tdir} |
11266                 awk '/stats_testdir1/ {print $5}')
11267         testdir2_size=$(ls -l $DIR/${tdir} |
11268                 awk '/stats_testdir2/ {print $5}')
11269
11270         testdir1_size=$(order_2 $testdir1_size)
11271         testdir2_size=$(order_2 $testdir2_size)
11272
11273         testdir1_size=$(size_in_KMGT $testdir1_size)
11274         testdir2_size=$(size_in_KMGT $testdir2_size)
11275
11276         echo "source rename dir size: ${testdir1_size}"
11277         echo "target rename dir size: ${testdir2_size}"
11278
11279         eval $cmd || error "$cmd failed"
11280         local crossdir=$($cmd | grep 'crossdir')
11281         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11282         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11283         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11284         [[ $src_sample -eq 1 ]] ||
11285                 error "crossdir_rename_size error $src_sample"
11286         [[ $tgt_sample -eq 1 ]] ||
11287                 error "crossdir_rename_size error $tgt_sample"
11288         echo "Check cross dir rename stats success"
11289         rm -rf $DIR/${tdir}
11290 }
11291 run_test 133d "Verifying rename_stats ========================================"
11292
11293 test_133e() {
11294         remote_mds_nodsh && skip "remote MDS with nodsh"
11295         remote_ost_nodsh && skip "remote OST with nodsh"
11296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11297
11298         local testdir=$DIR/${tdir}/stats_testdir
11299         local ctr f0 f1 bs=32768 count=42 sum
11300
11301         mkdir -p ${testdir} || error "mkdir failed"
11302
11303         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11304
11305         for ctr in {write,read}_bytes; do
11306                 sync
11307                 cancel_lru_locks osc
11308
11309                 do_facet ost1 $LCTL set_param -n \
11310                         "obdfilter.*.exports.clear=clear"
11311
11312                 if [ $ctr = write_bytes ]; then
11313                         f0=/dev/zero
11314                         f1=${testdir}/${tfile}
11315                 else
11316                         f0=${testdir}/${tfile}
11317                         f1=/dev/null
11318                 fi
11319
11320                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11321                         error "dd failed"
11322                 sync
11323                 cancel_lru_locks osc
11324
11325                 sum=$(do_facet ost1 $LCTL get_param \
11326                         "obdfilter.*.exports.*.stats" |
11327                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11328                                 $1 == ctr { sum += $7 }
11329                                 END { printf("%0.0f", sum) }')
11330
11331                 if ((sum != bs * count)); then
11332                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11333                 fi
11334         done
11335
11336         rm -rf $DIR/${tdir}
11337 }
11338 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11339
11340 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11341
11342 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11343 # not honor the -ignore_readdir_race option correctly. So we call
11344 # error_ignore() rather than error() in these cases. See LU-11152.
11345 error_133() {
11346         if (find --version; do_facet mds1 find --version) |
11347                 grep -q '\b4\.5\.1[1-4]\b'; then
11348                 error_ignore LU-11152 "$@"
11349         else
11350                 error "$@"
11351         fi
11352 }
11353
11354 test_133f() {
11355         # First without trusting modes.
11356         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11357         echo "proc_dirs='$proc_dirs'"
11358         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11359         find $proc_dirs -exec cat '{}' \; &> /dev/null
11360
11361         # Second verifying readability.
11362         $LCTL get_param -R '*' &> /dev/null
11363
11364         # Verifing writability with badarea_io.
11365         find $proc_dirs \
11366                 -ignore_readdir_race \
11367                 -type f \
11368                 -not -name force_lbug \
11369                 -not -name changelog_mask \
11370                 -exec badarea_io '{}' \; ||
11371                         error_133 "find $proc_dirs failed"
11372 }
11373 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11374
11375 test_133g() {
11376         remote_mds_nodsh && skip "remote MDS with nodsh"
11377         remote_ost_nodsh && skip "remote OST with nodsh"
11378
11379         # eventually, this can also be replaced with "lctl get_param -R",
11380         # but not until that option is always available on the server
11381         local facet
11382         for facet in mds1 ost1; do
11383                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11384                         skip_noexit "Too old lustre on $facet"
11385                 local facet_proc_dirs=$(do_facet $facet \
11386                                         \\\ls -d $proc_regexp 2>/dev/null)
11387                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11388                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11389                 do_facet $facet find $facet_proc_dirs \
11390                         ! -name req_history \
11391                         -exec cat '{}' \\\; &> /dev/null
11392
11393                 do_facet $facet find $facet_proc_dirs \
11394                         ! -name req_history \
11395                         -type f \
11396                         -exec cat '{}' \\\; &> /dev/null ||
11397                                 error "proc file read failed"
11398
11399                 do_facet $facet find $facet_proc_dirs \
11400                         -ignore_readdir_race \
11401                         -type f \
11402                         -not -name force_lbug \
11403                         -not -name changelog_mask \
11404                         -exec badarea_io '{}' \\\; ||
11405                                 error_133 "$facet find $facet_proc_dirs failed"
11406         done
11407
11408         # remount the FS in case writes/reads /proc break the FS
11409         cleanup || error "failed to unmount"
11410         setup || error "failed to setup"
11411         true
11412 }
11413 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11414
11415 test_133h() {
11416         remote_mds_nodsh && skip "remote MDS with nodsh"
11417         remote_ost_nodsh && skip "remote OST with nodsh"
11418         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11419                 skip "Need MDS version at least 2.9.54"
11420
11421         local facet
11422
11423         for facet in client mds1 ost1; do
11424                 local facet_proc_dirs=$(do_facet $facet \
11425                                         \\\ls -d $proc_regexp 2> /dev/null)
11426                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11427                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11428                 # Get the list of files that are missing the terminating newline
11429                 local missing=($(do_facet $facet \
11430                         find ${facet_proc_dirs} -type f \|              \
11431                                 while read F\; do                       \
11432                                         awk -v FS='\v' -v RS='\v\v'     \
11433                                         "'END { if(NR>0 &&              \
11434                                         \\\$NF !~ /.*\\\n\$/)           \
11435                                                 print FILENAME}'"       \
11436                                         '\$F'\;                         \
11437                                 done 2>/dev/null))
11438                 [ ${#missing[*]} -eq 0 ] ||
11439                         error "files do not end with newline: ${missing[*]}"
11440         done
11441 }
11442 run_test 133h "Proc files should end with newlines"
11443
11444 test_134a() {
11445         remote_mds_nodsh && skip "remote MDS with nodsh"
11446         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11447                 skip "Need MDS version at least 2.7.54"
11448
11449         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11450         cancel_lru_locks mdc
11451
11452         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11453         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11454         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11455
11456         local nr=1000
11457         createmany -o $DIR/$tdir/f $nr ||
11458                 error "failed to create $nr files in $DIR/$tdir"
11459         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11460
11461         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11462         do_facet mds1 $LCTL set_param fail_loc=0x327
11463         do_facet mds1 $LCTL set_param fail_val=500
11464         touch $DIR/$tdir/m
11465
11466         echo "sleep 10 seconds ..."
11467         sleep 10
11468         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11469
11470         do_facet mds1 $LCTL set_param fail_loc=0
11471         do_facet mds1 $LCTL set_param fail_val=0
11472         [ $lck_cnt -lt $unused ] ||
11473                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11474
11475         rm $DIR/$tdir/m
11476         unlinkmany $DIR/$tdir/f $nr
11477 }
11478 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11479
11480 test_134b() {
11481         remote_mds_nodsh && skip "remote MDS with nodsh"
11482         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11483                 skip "Need MDS version at least 2.7.54"
11484
11485         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11486         cancel_lru_locks mdc
11487
11488         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11489                         ldlm.lock_reclaim_threshold_mb)
11490         # disable reclaim temporarily
11491         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11492
11493         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11494         do_facet mds1 $LCTL set_param fail_loc=0x328
11495         do_facet mds1 $LCTL set_param fail_val=500
11496
11497         $LCTL set_param debug=+trace
11498
11499         local nr=600
11500         createmany -o $DIR/$tdir/f $nr &
11501         local create_pid=$!
11502
11503         echo "Sleep $TIMEOUT seconds ..."
11504         sleep $TIMEOUT
11505         if ! ps -p $create_pid  > /dev/null 2>&1; then
11506                 do_facet mds1 $LCTL set_param fail_loc=0
11507                 do_facet mds1 $LCTL set_param fail_val=0
11508                 do_facet mds1 $LCTL set_param \
11509                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11510                 error "createmany finished incorrectly!"
11511         fi
11512         do_facet mds1 $LCTL set_param fail_loc=0
11513         do_facet mds1 $LCTL set_param fail_val=0
11514         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11515         wait $create_pid || return 1
11516
11517         unlinkmany $DIR/$tdir/f $nr
11518 }
11519 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11520
11521 test_140() { #bug-17379
11522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11523
11524         test_mkdir $DIR/$tdir
11525         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11526         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11527
11528         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11529         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11530         local i=0
11531         while i=$((i + 1)); do
11532                 test_mkdir $i
11533                 cd $i || error "Changing to $i"
11534                 ln -s ../stat stat || error "Creating stat symlink"
11535                 # Read the symlink until ELOOP present,
11536                 # not LBUGing the system is considered success,
11537                 # we didn't overrun the stack.
11538                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11539                 if [ $ret -ne 0 ]; then
11540                         if [ $ret -eq 40 ]; then
11541                                 break  # -ELOOP
11542                         else
11543                                 error "Open stat symlink"
11544                                         return
11545                         fi
11546                 fi
11547         done
11548         i=$((i - 1))
11549         echo "The symlink depth = $i"
11550         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11551                 error "Invalid symlink depth"
11552
11553         # Test recursive symlink
11554         ln -s symlink_self symlink_self
11555         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11556         echo "open symlink_self returns $ret"
11557         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11558 }
11559 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11560
11561 test_150() {
11562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11563
11564         local TF="$TMP/$tfile"
11565
11566         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11567         cp $TF $DIR/$tfile
11568         cancel_lru_locks $OSC
11569         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11570         remount_client $MOUNT
11571         df -P $MOUNT
11572         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11573
11574         $TRUNCATE $TF 6000
11575         $TRUNCATE $DIR/$tfile 6000
11576         cancel_lru_locks $OSC
11577         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11578
11579         echo "12345" >>$TF
11580         echo "12345" >>$DIR/$tfile
11581         cancel_lru_locks $OSC
11582         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11583
11584         echo "12345" >>$TF
11585         echo "12345" >>$DIR/$tfile
11586         cancel_lru_locks $OSC
11587         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11588
11589         rm -f $TF
11590         true
11591 }
11592 run_test 150 "truncate/append tests"
11593
11594 #LU-2902 roc_hit was not able to read all values from lproc
11595 function roc_hit_init() {
11596         local list=$(comma_list $(osts_nodes))
11597         local dir=$DIR/$tdir-check
11598         local file=$dir/$tfile
11599         local BEFORE
11600         local AFTER
11601         local idx
11602
11603         test_mkdir $dir
11604         #use setstripe to do a write to every ost
11605         for i in $(seq 0 $((OSTCOUNT-1))); do
11606                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11607                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11608                 idx=$(printf %04x $i)
11609                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11610                         awk '$1 == "cache_access" {sum += $7}
11611                                 END { printf("%0.0f", sum) }')
11612
11613                 cancel_lru_locks osc
11614                 cat $file >/dev/null
11615
11616                 AFTER=$(get_osd_param $list *OST*$idx stats |
11617                         awk '$1 == "cache_access" {sum += $7}
11618                                 END { printf("%0.0f", sum) }')
11619
11620                 echo BEFORE:$BEFORE AFTER:$AFTER
11621                 if ! let "AFTER - BEFORE == 4"; then
11622                         rm -rf $dir
11623                         error "roc_hit is not safe to use"
11624                 fi
11625                 rm $file
11626         done
11627
11628         rm -rf $dir
11629 }
11630
11631 function roc_hit() {
11632         local list=$(comma_list $(osts_nodes))
11633         echo $(get_osd_param $list '' stats |
11634                 awk '$1 == "cache_hit" {sum += $7}
11635                         END { printf("%0.0f", sum) }')
11636 }
11637
11638 function set_cache() {
11639         local on=1
11640
11641         if [ "$2" == "off" ]; then
11642                 on=0;
11643         fi
11644         local list=$(comma_list $(osts_nodes))
11645         set_osd_param $list '' $1_cache_enable $on
11646
11647         cancel_lru_locks osc
11648 }
11649
11650 test_151() {
11651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11652         remote_ost_nodsh && skip "remote OST with nodsh"
11653
11654         local CPAGES=3
11655         local list=$(comma_list $(osts_nodes))
11656
11657         # check whether obdfilter is cache capable at all
11658         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11659                 skip "not cache-capable obdfilter"
11660         fi
11661
11662         # check cache is enabled on all obdfilters
11663         if get_osd_param $list '' read_cache_enable | grep 0; then
11664                 skip "oss cache is disabled"
11665         fi
11666
11667         set_osd_param $list '' writethrough_cache_enable 1
11668
11669         # check write cache is enabled on all obdfilters
11670         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11671                 skip "oss write cache is NOT enabled"
11672         fi
11673
11674         roc_hit_init
11675
11676         #define OBD_FAIL_OBD_NO_LRU  0x609
11677         do_nodes $list $LCTL set_param fail_loc=0x609
11678
11679         # pages should be in the case right after write
11680         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11681                 error "dd failed"
11682
11683         local BEFORE=$(roc_hit)
11684         cancel_lru_locks osc
11685         cat $DIR/$tfile >/dev/null
11686         local AFTER=$(roc_hit)
11687
11688         do_nodes $list $LCTL set_param fail_loc=0
11689
11690         if ! let "AFTER - BEFORE == CPAGES"; then
11691                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11692         fi
11693
11694         # the following read invalidates the cache
11695         cancel_lru_locks osc
11696         set_osd_param $list '' read_cache_enable 0
11697         cat $DIR/$tfile >/dev/null
11698
11699         # now data shouldn't be found in the cache
11700         BEFORE=$(roc_hit)
11701         cancel_lru_locks osc
11702         cat $DIR/$tfile >/dev/null
11703         AFTER=$(roc_hit)
11704         if let "AFTER - BEFORE != 0"; then
11705                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11706         fi
11707
11708         set_osd_param $list '' read_cache_enable 1
11709         rm -f $DIR/$tfile
11710 }
11711 run_test 151 "test cache on oss and controls ==============================="
11712
11713 test_152() {
11714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11715
11716         local TF="$TMP/$tfile"
11717
11718         # simulate ENOMEM during write
11719 #define OBD_FAIL_OST_NOMEM      0x226
11720         lctl set_param fail_loc=0x80000226
11721         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11722         cp $TF $DIR/$tfile
11723         sync || error "sync failed"
11724         lctl set_param fail_loc=0
11725
11726         # discard client's cache
11727         cancel_lru_locks osc
11728
11729         # simulate ENOMEM during read
11730         lctl set_param fail_loc=0x80000226
11731         cmp $TF $DIR/$tfile || error "cmp failed"
11732         lctl set_param fail_loc=0
11733
11734         rm -f $TF
11735 }
11736 run_test 152 "test read/write with enomem ============================"
11737
11738 test_153() {
11739         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11740 }
11741 run_test 153 "test if fdatasync does not crash ======================="
11742
11743 dot_lustre_fid_permission_check() {
11744         local fid=$1
11745         local ffid=$MOUNT/.lustre/fid/$fid
11746         local test_dir=$2
11747
11748         echo "stat fid $fid"
11749         stat $ffid > /dev/null || error "stat $ffid failed."
11750         echo "touch fid $fid"
11751         touch $ffid || error "touch $ffid failed."
11752         echo "write to fid $fid"
11753         cat /etc/hosts > $ffid || error "write $ffid failed."
11754         echo "read fid $fid"
11755         diff /etc/hosts $ffid || error "read $ffid failed."
11756         echo "append write to fid $fid"
11757         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11758         echo "rename fid $fid"
11759         mv $ffid $test_dir/$tfile.1 &&
11760                 error "rename $ffid to $tfile.1 should fail."
11761         touch $test_dir/$tfile.1
11762         mv $test_dir/$tfile.1 $ffid &&
11763                 error "rename $tfile.1 to $ffid should fail."
11764         rm -f $test_dir/$tfile.1
11765         echo "truncate fid $fid"
11766         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11767         echo "link fid $fid"
11768         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11769         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11770                 echo "setfacl fid $fid"
11771                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11772                 echo "getfacl fid $fid"
11773                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11774         fi
11775         echo "unlink fid $fid"
11776         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11777         echo "mknod fid $fid"
11778         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11779
11780         fid=[0xf00000400:0x1:0x0]
11781         ffid=$MOUNT/.lustre/fid/$fid
11782
11783         echo "stat non-exist fid $fid"
11784         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11785         echo "write to non-exist fid $fid"
11786         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11787         echo "link new fid $fid"
11788         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11789
11790         mkdir -p $test_dir/$tdir
11791         touch $test_dir/$tdir/$tfile
11792         fid=$($LFS path2fid $test_dir/$tdir)
11793         rc=$?
11794         [ $rc -ne 0 ] &&
11795                 error "error: could not get fid for $test_dir/$dir/$tfile."
11796
11797         ffid=$MOUNT/.lustre/fid/$fid
11798
11799         echo "ls $fid"
11800         ls $ffid > /dev/null || error "ls $ffid failed."
11801         echo "touch $fid/$tfile.1"
11802         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11803
11804         echo "touch $MOUNT/.lustre/fid/$tfile"
11805         touch $MOUNT/.lustre/fid/$tfile && \
11806                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11807
11808         echo "setxattr to $MOUNT/.lustre/fid"
11809         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11810
11811         echo "listxattr for $MOUNT/.lustre/fid"
11812         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11813
11814         echo "delxattr from $MOUNT/.lustre/fid"
11815         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11816
11817         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11818         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11819                 error "touch invalid fid should fail."
11820
11821         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11822         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11823                 error "touch non-normal fid should fail."
11824
11825         echo "rename $tdir to $MOUNT/.lustre/fid"
11826         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11827                 error "rename to $MOUNT/.lustre/fid should fail."
11828
11829         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11830         then            # LU-3547
11831                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11832                 local new_obf_mode=777
11833
11834                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11835                 chmod $new_obf_mode $DIR/.lustre/fid ||
11836                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11837
11838                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11839                 [ $obf_mode -eq $new_obf_mode ] ||
11840                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11841
11842                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11843                 chmod $old_obf_mode $DIR/.lustre/fid ||
11844                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11845         fi
11846
11847         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11848         fid=$($LFS path2fid $test_dir/$tfile-2)
11849
11850         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11851         then # LU-5424
11852                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11853                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11854                         error "create lov data thru .lustre failed"
11855         fi
11856         echo "cp /etc/passwd $test_dir/$tfile-2"
11857         cp /etc/passwd $test_dir/$tfile-2 ||
11858                 error "copy to $test_dir/$tfile-2 failed."
11859         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11860         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11861                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11862
11863         rm -rf $test_dir/tfile.lnk
11864         rm -rf $test_dir/$tfile-2
11865 }
11866
11867 test_154A() {
11868         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11869                 skip "Need MDS version at least 2.4.1"
11870
11871         local tf=$DIR/$tfile
11872         touch $tf
11873
11874         local fid=$($LFS path2fid $tf)
11875         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11876
11877         # check that we get the same pathname back
11878         local found=$($LFS fid2path $MOUNT "$fid")
11879         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11880         [ "$found" == "$tf" ] ||
11881                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11882 }
11883 run_test 154A "lfs path2fid and fid2path basic checks"
11884
11885 test_154B() {
11886         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11887                 skip "Need MDS version at least 2.4.1"
11888
11889         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11890         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11891         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11892         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11893
11894         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11895         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11896
11897         # check that we get the same pathname
11898         echo "PFID: $PFID, name: $name"
11899         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11900         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11901         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11902                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11903
11904         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11905 }
11906 run_test 154B "verify the ll_decode_linkea tool"
11907
11908 test_154a() {
11909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11910         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11911         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11912                 skip "Need MDS version at least 2.2.51"
11913         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11914
11915         cp /etc/hosts $DIR/$tfile
11916
11917         fid=$($LFS path2fid $DIR/$tfile)
11918         rc=$?
11919         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11920
11921         dot_lustre_fid_permission_check "$fid" $DIR ||
11922                 error "dot lustre permission check $fid failed"
11923
11924         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11925
11926         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11927
11928         touch $MOUNT/.lustre/file &&
11929                 error "creation is not allowed under .lustre"
11930
11931         mkdir $MOUNT/.lustre/dir &&
11932                 error "mkdir is not allowed under .lustre"
11933
11934         rm -rf $DIR/$tfile
11935 }
11936 run_test 154a "Open-by-FID"
11937
11938 test_154b() {
11939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11940         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11942         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11943                 skip "Need MDS version at least 2.2.51"
11944
11945         local remote_dir=$DIR/$tdir/remote_dir
11946         local MDTIDX=1
11947         local rc=0
11948
11949         mkdir -p $DIR/$tdir
11950         $LFS mkdir -i $MDTIDX $remote_dir ||
11951                 error "create remote directory failed"
11952
11953         cp /etc/hosts $remote_dir/$tfile
11954
11955         fid=$($LFS path2fid $remote_dir/$tfile)
11956         rc=$?
11957         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11958
11959         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11960                 error "dot lustre permission check $fid failed"
11961         rm -rf $DIR/$tdir
11962 }
11963 run_test 154b "Open-by-FID for remote directory"
11964
11965 test_154c() {
11966         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11967                 skip "Need MDS version at least 2.4.1"
11968
11969         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11970         local FID1=$($LFS path2fid $DIR/$tfile.1)
11971         local FID2=$($LFS path2fid $DIR/$tfile.2)
11972         local FID3=$($LFS path2fid $DIR/$tfile.3)
11973
11974         local N=1
11975         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11976                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11977                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11978                 local want=FID$N
11979                 [ "$FID" = "${!want}" ] ||
11980                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11981                 N=$((N + 1))
11982         done
11983
11984         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11985         do
11986                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11987                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11988                 N=$((N + 1))
11989         done
11990 }
11991 run_test 154c "lfs path2fid and fid2path multiple arguments"
11992
11993 test_154d() {
11994         remote_mds_nodsh && skip "remote MDS with nodsh"
11995         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11996                 skip "Need MDS version at least 2.5.53"
11997
11998         if remote_mds; then
11999                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12000         else
12001                 nid="0@lo"
12002         fi
12003         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12004         local fd
12005         local cmd
12006
12007         rm -f $DIR/$tfile
12008         touch $DIR/$tfile
12009
12010         local fid=$($LFS path2fid $DIR/$tfile)
12011         # Open the file
12012         fd=$(free_fd)
12013         cmd="exec $fd<$DIR/$tfile"
12014         eval $cmd
12015         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12016         echo "$fid_list" | grep "$fid"
12017         rc=$?
12018
12019         cmd="exec $fd>/dev/null"
12020         eval $cmd
12021         if [ $rc -ne 0 ]; then
12022                 error "FID $fid not found in open files list $fid_list"
12023         fi
12024 }
12025 run_test 154d "Verify open file fid"
12026
12027 test_154e()
12028 {
12029         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12030                 skip "Need MDS version at least 2.6.50"
12031
12032         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12033                 error ".lustre returned by readdir"
12034         fi
12035 }
12036 run_test 154e ".lustre is not returned by readdir"
12037
12038 test_154f() {
12039         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12040
12041         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12042         test_mkdir -p -c1 $DIR/$tdir/d
12043         # test dirs inherit from its stripe
12044         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12045         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12046         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12047         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12048         touch $DIR/f
12049
12050         # get fid of parents
12051         local FID0=$($LFS path2fid $DIR/$tdir/d)
12052         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12053         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12054         local FID3=$($LFS path2fid $DIR)
12055
12056         # check that path2fid --parents returns expected <parent_fid>/name
12057         # 1) test for a directory (single parent)
12058         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12059         [ "$parent" == "$FID0/foo1" ] ||
12060                 error "expected parent: $FID0/foo1, got: $parent"
12061
12062         # 2) test for a file with nlink > 1 (multiple parents)
12063         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12064         echo "$parent" | grep -F "$FID1/$tfile" ||
12065                 error "$FID1/$tfile not returned in parent list"
12066         echo "$parent" | grep -F "$FID2/link" ||
12067                 error "$FID2/link not returned in parent list"
12068
12069         # 3) get parent by fid
12070         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12071         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12072         echo "$parent" | grep -F "$FID1/$tfile" ||
12073                 error "$FID1/$tfile not returned in parent list (by fid)"
12074         echo "$parent" | grep -F "$FID2/link" ||
12075                 error "$FID2/link not returned in parent list (by fid)"
12076
12077         # 4) test for entry in root directory
12078         parent=$($LFS path2fid --parents $DIR/f)
12079         echo "$parent" | grep -F "$FID3/f" ||
12080                 error "$FID3/f not returned in parent list"
12081
12082         # 5) test it on root directory
12083         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12084                 error "$MOUNT should not have parents"
12085
12086         # enable xattr caching and check that linkea is correctly updated
12087         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12088         save_lustre_params client "llite.*.xattr_cache" > $save
12089         lctl set_param llite.*.xattr_cache 1
12090
12091         # 6.1) linkea update on rename
12092         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12093
12094         # get parents by fid
12095         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12096         # foo1 should no longer be returned in parent list
12097         echo "$parent" | grep -F "$FID1" &&
12098                 error "$FID1 should no longer be in parent list"
12099         # the new path should appear
12100         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12101                 error "$FID2/$tfile.moved is not in parent list"
12102
12103         # 6.2) linkea update on unlink
12104         rm -f $DIR/$tdir/d/foo2/link
12105         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12106         # foo2/link should no longer be returned in parent list
12107         echo "$parent" | grep -F "$FID2/link" &&
12108                 error "$FID2/link should no longer be in parent list"
12109         true
12110
12111         rm -f $DIR/f
12112         restore_lustre_params < $save
12113         rm -f $save
12114 }
12115 run_test 154f "get parent fids by reading link ea"
12116
12117 test_154g()
12118 {
12119         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12120         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12121            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12122                 skip "Need MDS version at least 2.6.92"
12123
12124         mkdir -p $DIR/$tdir
12125         llapi_fid_test -d $DIR/$tdir
12126 }
12127 run_test 154g "various llapi FID tests"
12128
12129 test_155_small_load() {
12130     local temp=$TMP/$tfile
12131     local file=$DIR/$tfile
12132
12133     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12134         error "dd of=$temp bs=6096 count=1 failed"
12135     cp $temp $file
12136     cancel_lru_locks $OSC
12137     cmp $temp $file || error "$temp $file differ"
12138
12139     $TRUNCATE $temp 6000
12140     $TRUNCATE $file 6000
12141     cmp $temp $file || error "$temp $file differ (truncate1)"
12142
12143     echo "12345" >>$temp
12144     echo "12345" >>$file
12145     cmp $temp $file || error "$temp $file differ (append1)"
12146
12147     echo "12345" >>$temp
12148     echo "12345" >>$file
12149     cmp $temp $file || error "$temp $file differ (append2)"
12150
12151     rm -f $temp $file
12152     true
12153 }
12154
12155 test_155_big_load() {
12156         remote_ost_nodsh && skip "remote OST with nodsh"
12157
12158         local temp=$TMP/$tfile
12159         local file=$DIR/$tfile
12160
12161         free_min_max
12162         local cache_size=$(do_facet ost$((MAXI+1)) \
12163                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12164         local large_file_size=$((cache_size * 2))
12165
12166         echo "OSS cache size: $cache_size KB"
12167         echo "Large file size: $large_file_size KB"
12168
12169         [ $MAXV -le $large_file_size ] &&
12170                 skip_env "max available OST size needs > $large_file_size KB"
12171
12172         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12173
12174         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12175                 error "dd of=$temp bs=$large_file_size count=1k failed"
12176         cp $temp $file
12177         ls -lh $temp $file
12178         cancel_lru_locks osc
12179         cmp $temp $file || error "$temp $file differ"
12180
12181         rm -f $temp $file
12182         true
12183 }
12184
12185 save_writethrough() {
12186         local facets=$(get_facets OST)
12187
12188         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12189 }
12190
12191 test_155a() {
12192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12193
12194         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12195
12196         save_writethrough $p
12197
12198         set_cache read on
12199         set_cache writethrough on
12200         test_155_small_load
12201         restore_lustre_params < $p
12202         rm -f $p
12203 }
12204 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12205
12206 test_155b() {
12207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12208
12209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12210
12211         save_writethrough $p
12212
12213         set_cache read on
12214         set_cache writethrough off
12215         test_155_small_load
12216         restore_lustre_params < $p
12217         rm -f $p
12218 }
12219 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12220
12221 test_155c() {
12222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12223
12224         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12225
12226         save_writethrough $p
12227
12228         set_cache read off
12229         set_cache writethrough on
12230         test_155_small_load
12231         restore_lustre_params < $p
12232         rm -f $p
12233 }
12234 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12235
12236 test_155d() {
12237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12238
12239         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12240
12241         save_writethrough $p
12242
12243         set_cache read off
12244         set_cache writethrough off
12245         test_155_small_load
12246         restore_lustre_params < $p
12247         rm -f $p
12248 }
12249 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12250
12251 test_155e() {
12252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12253
12254         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12255
12256         save_writethrough $p
12257
12258         set_cache read on
12259         set_cache writethrough on
12260         test_155_big_load
12261         restore_lustre_params < $p
12262         rm -f $p
12263 }
12264 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12265
12266 test_155f() {
12267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12268
12269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12270
12271         save_writethrough $p
12272
12273         set_cache read on
12274         set_cache writethrough off
12275         test_155_big_load
12276         restore_lustre_params < $p
12277         rm -f $p
12278 }
12279 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12280
12281 test_155g() {
12282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12283
12284         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12285
12286         save_writethrough $p
12287
12288         set_cache read off
12289         set_cache writethrough on
12290         test_155_big_load
12291         restore_lustre_params < $p
12292         rm -f $p
12293 }
12294 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12295
12296 test_155h() {
12297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12298
12299         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12300
12301         save_writethrough $p
12302
12303         set_cache read off
12304         set_cache writethrough off
12305         test_155_big_load
12306         restore_lustre_params < $p
12307         rm -f $p
12308 }
12309 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12310
12311 test_156() {
12312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12313         remote_ost_nodsh && skip "remote OST with nodsh"
12314         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12315                 skip "stats not implemented on old servers"
12316         [ "$ost1_FSTYPE" = "zfs" ] &&
12317                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12318
12319         local CPAGES=3
12320         local BEFORE
12321         local AFTER
12322         local file="$DIR/$tfile"
12323         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12324
12325         save_writethrough $p
12326         roc_hit_init
12327
12328         log "Turn on read and write cache"
12329         set_cache read on
12330         set_cache writethrough on
12331
12332         log "Write data and read it back."
12333         log "Read should be satisfied from the cache."
12334         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12335         BEFORE=$(roc_hit)
12336         cancel_lru_locks osc
12337         cat $file >/dev/null
12338         AFTER=$(roc_hit)
12339         if ! let "AFTER - BEFORE == CPAGES"; then
12340                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12341         else
12342                 log "cache hits:: before: $BEFORE, after: $AFTER"
12343         fi
12344
12345         log "Read again; it should be satisfied from the cache."
12346         BEFORE=$AFTER
12347         cancel_lru_locks osc
12348         cat $file >/dev/null
12349         AFTER=$(roc_hit)
12350         if ! let "AFTER - BEFORE == CPAGES"; then
12351                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12352         else
12353                 log "cache hits:: before: $BEFORE, after: $AFTER"
12354         fi
12355
12356         log "Turn off the read cache and turn on the write cache"
12357         set_cache read off
12358         set_cache writethrough on
12359
12360         log "Read again; it should be satisfied from the cache."
12361         BEFORE=$(roc_hit)
12362         cancel_lru_locks osc
12363         cat $file >/dev/null
12364         AFTER=$(roc_hit)
12365         if ! let "AFTER - BEFORE == CPAGES"; then
12366                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12367         else
12368                 log "cache hits:: before: $BEFORE, after: $AFTER"
12369         fi
12370
12371         log "Read again; it should not be satisfied from the cache."
12372         BEFORE=$AFTER
12373         cancel_lru_locks osc
12374         cat $file >/dev/null
12375         AFTER=$(roc_hit)
12376         if ! let "AFTER - BEFORE == 0"; then
12377                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12378         else
12379                 log "cache hits:: before: $BEFORE, after: $AFTER"
12380         fi
12381
12382         log "Write data and read it back."
12383         log "Read should be satisfied from the cache."
12384         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12385         BEFORE=$(roc_hit)
12386         cancel_lru_locks osc
12387         cat $file >/dev/null
12388         AFTER=$(roc_hit)
12389         if ! let "AFTER - BEFORE == CPAGES"; then
12390                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12391         else
12392                 log "cache hits:: before: $BEFORE, after: $AFTER"
12393         fi
12394
12395         log "Read again; it should not be satisfied from the cache."
12396         BEFORE=$AFTER
12397         cancel_lru_locks osc
12398         cat $file >/dev/null
12399         AFTER=$(roc_hit)
12400         if ! let "AFTER - BEFORE == 0"; then
12401                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12402         else
12403                 log "cache hits:: before: $BEFORE, after: $AFTER"
12404         fi
12405
12406         log "Turn off read and write cache"
12407         set_cache read off
12408         set_cache writethrough off
12409
12410         log "Write data and read it back"
12411         log "It should not be satisfied from the cache."
12412         rm -f $file
12413         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12414         cancel_lru_locks osc
12415         BEFORE=$(roc_hit)
12416         cat $file >/dev/null
12417         AFTER=$(roc_hit)
12418         if ! let "AFTER - BEFORE == 0"; then
12419                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12420         else
12421                 log "cache hits:: before: $BEFORE, after: $AFTER"
12422         fi
12423
12424         log "Turn on the read cache and turn off the write cache"
12425         set_cache read on
12426         set_cache writethrough off
12427
12428         log "Write data and read it back"
12429         log "It should not be satisfied from the cache."
12430         rm -f $file
12431         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12432         BEFORE=$(roc_hit)
12433         cancel_lru_locks osc
12434         cat $file >/dev/null
12435         AFTER=$(roc_hit)
12436         if ! let "AFTER - BEFORE == 0"; then
12437                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12438         else
12439                 log "cache hits:: before: $BEFORE, after: $AFTER"
12440         fi
12441
12442         log "Read again; it should be satisfied from the cache."
12443         BEFORE=$(roc_hit)
12444         cancel_lru_locks osc
12445         cat $file >/dev/null
12446         AFTER=$(roc_hit)
12447         if ! let "AFTER - BEFORE == CPAGES"; then
12448                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12449         else
12450                 log "cache hits:: before: $BEFORE, after: $AFTER"
12451         fi
12452
12453         restore_lustre_params < $p
12454         rm -f $p $file
12455 }
12456 run_test 156 "Verification of tunables"
12457
12458 test_160a() {
12459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12460         remote_mds_nodsh && skip "remote MDS with nodsh"
12461         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12462                 skip "Need MDS version at least 2.2.0"
12463
12464         changelog_register || error "changelog_register failed"
12465         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12466         changelog_users $SINGLEMDS | grep -q $cl_user ||
12467                 error "User $cl_user not found in changelog_users"
12468
12469         # change something
12470         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12471         changelog_clear 0 || error "changelog_clear failed"
12472         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12473         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12474         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12475         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12476         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12477         rm $DIR/$tdir/pics/desktop.jpg
12478
12479         changelog_dump | tail -10
12480
12481         echo "verifying changelog mask"
12482         changelog_chmask "-MKDIR"
12483         changelog_chmask "-CLOSE"
12484
12485         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12486         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12487
12488         changelog_chmask "+MKDIR"
12489         changelog_chmask "+CLOSE"
12490
12491         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12492         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12493
12494         changelog_dump | tail -10
12495         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12496         CLOSES=$(changelog_dump | grep -c "CLOSE")
12497         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12498         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12499
12500         # verify contents
12501         echo "verifying target fid"
12502         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12503         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12504         [ "$fidc" == "$fidf" ] ||
12505                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12506         echo "verifying parent fid"
12507         # The FID returned from the Changelog may be the directory shard on
12508         # a different MDT, and not the FID returned by path2fid on the parent.
12509         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12510         # since this is what will matter when recreating this file in the tree.
12511         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12512         local pathp=$($LFS fid2path $MOUNT "$fidp")
12513         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12514                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12515
12516         echo "getting records for $cl_user"
12517         changelog_users $SINGLEMDS
12518         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12519         local nclr=3
12520         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12521                 error "changelog_clear failed"
12522         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12523         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12524         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12525                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12526
12527         local min0_rec=$(changelog_users $SINGLEMDS |
12528                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12529         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12530                           awk '{ print $1; exit; }')
12531
12532         changelog_dump | tail -n 5
12533         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12534         [ $first_rec == $((min0_rec + 1)) ] ||
12535                 error "first index should be $min0_rec + 1 not $first_rec"
12536
12537         # LU-3446 changelog index reset on MDT restart
12538         local cur_rec1=$(changelog_users $SINGLEMDS |
12539                          awk '/^current.index:/ { print $NF }')
12540         changelog_clear 0 ||
12541                 error "clear all changelog records for $cl_user failed"
12542         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12543         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12544                 error "Fail to start $SINGLEMDS"
12545         local cur_rec2=$(changelog_users $SINGLEMDS |
12546                          awk '/^current.index:/ { print $NF }')
12547         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12548         [ $cur_rec1 == $cur_rec2 ] ||
12549                 error "current index should be $cur_rec1 not $cur_rec2"
12550
12551         echo "verifying users from this test are deregistered"
12552         changelog_deregister || error "changelog_deregister failed"
12553         changelog_users $SINGLEMDS | grep -q $cl_user &&
12554                 error "User '$cl_user' still in changelog_users"
12555
12556         # lctl get_param -n mdd.*.changelog_users
12557         # current index: 144
12558         # ID    index (idle seconds)
12559         # cl3   144 (2)
12560         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12561                 # this is the normal case where all users were deregistered
12562                 # make sure no new records are added when no users are present
12563                 local last_rec1=$(changelog_users $SINGLEMDS |
12564                                   awk '/^current.index:/ { print $NF }')
12565                 touch $DIR/$tdir/chloe
12566                 local last_rec2=$(changelog_users $SINGLEMDS |
12567                                   awk '/^current.index:/ { print $NF }')
12568                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12569                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12570         else
12571                 # any changelog users must be leftovers from a previous test
12572                 changelog_users $SINGLEMDS
12573                 echo "other changelog users; can't verify off"
12574         fi
12575 }
12576 run_test 160a "changelog sanity"
12577
12578 test_160b() { # LU-3587
12579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12580         remote_mds_nodsh && skip "remote MDS with nodsh"
12581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12582                 skip "Need MDS version at least 2.2.0"
12583
12584         changelog_register || error "changelog_register failed"
12585         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12586         changelog_users $SINGLEMDS | grep -q $cl_user ||
12587                 error "User '$cl_user' not found in changelog_users"
12588
12589         local longname1=$(str_repeat a 255)
12590         local longname2=$(str_repeat b 255)
12591
12592         cd $DIR
12593         echo "creating very long named file"
12594         touch $longname1 || error "create of '$longname1' failed"
12595         echo "renaming very long named file"
12596         mv $longname1 $longname2
12597
12598         changelog_dump | grep RENME | tail -n 5
12599         rm -f $longname2
12600 }
12601 run_test 160b "Verify that very long rename doesn't crash in changelog"
12602
12603 test_160c() {
12604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12605         remote_mds_nodsh && skip "remote MDS with nodsh"
12606
12607         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12608                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12609                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12610                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12611
12612         local rc=0
12613
12614         # Registration step
12615         changelog_register || error "changelog_register failed"
12616
12617         rm -rf $DIR/$tdir
12618         mkdir -p $DIR/$tdir
12619         $MCREATE $DIR/$tdir/foo_160c
12620         changelog_chmask "-TRUNC"
12621         $TRUNCATE $DIR/$tdir/foo_160c 200
12622         changelog_chmask "+TRUNC"
12623         $TRUNCATE $DIR/$tdir/foo_160c 199
12624         changelog_dump | tail -n 5
12625         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12626         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12627 }
12628 run_test 160c "verify that changelog log catch the truncate event"
12629
12630 test_160d() {
12631         remote_mds_nodsh && skip "remote MDS with nodsh"
12632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12634         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12635                 skip "Need MDS version at least 2.7.60"
12636
12637         # Registration step
12638         changelog_register || error "changelog_register failed"
12639
12640         mkdir -p $DIR/$tdir/migrate_dir
12641         changelog_clear 0 || error "changelog_clear failed"
12642
12643         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12644         changelog_dump | tail -n 5
12645         local migrates=$(changelog_dump | grep -c "MIGRT")
12646         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12647 }
12648 run_test 160d "verify that changelog log catch the migrate event"
12649
12650 test_160e() {
12651         remote_mds_nodsh && skip "remote MDS with nodsh"
12652
12653         # Create a user
12654         changelog_register || error "changelog_register failed"
12655
12656         # Delete a future user (expect fail)
12657         local MDT0=$(facet_svc $SINGLEMDS)
12658         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12659         local rc=$?
12660
12661         if [ $rc -eq 0 ]; then
12662                 error "Deleted non-existant user cl77"
12663         elif [ $rc -ne 2 ]; then
12664                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12665         fi
12666
12667         # Clear to a bad index (1 billion should be safe)
12668         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12669         rc=$?
12670
12671         if [ $rc -eq 0 ]; then
12672                 error "Successfully cleared to invalid CL index"
12673         elif [ $rc -ne 22 ]; then
12674                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12675         fi
12676 }
12677 run_test 160e "changelog negative testing (should return errors)"
12678
12679 test_160f() {
12680         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12681         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12682                 skip "Need MDS version at least 2.10.56"
12683
12684         local mdts=$(comma_list $(mdts_nodes))
12685
12686         # Create a user
12687         changelog_register || error "first changelog_register failed"
12688         changelog_register || error "second changelog_register failed"
12689         local cl_users
12690         declare -A cl_user1
12691         declare -A cl_user2
12692         local user_rec1
12693         local user_rec2
12694         local i
12695
12696         # generate some changelog records to accumulate on each MDT
12697         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12698         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12699                 error "create $DIR/$tdir/$tfile failed"
12700
12701         # check changelogs have been generated
12702         local nbcl=$(changelog_dump | wc -l)
12703         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12704
12705         for param in "changelog_max_idle_time=10" \
12706                      "changelog_gc=1" \
12707                      "changelog_min_gc_interval=2" \
12708                      "changelog_min_free_cat_entries=3"; do
12709                 local MDT0=$(facet_svc $SINGLEMDS)
12710                 local var="${param%=*}"
12711                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12712
12713                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12714                 do_nodes $mdts $LCTL set_param mdd.*.$param
12715         done
12716
12717         # force cl_user2 to be idle (1st part)
12718         sleep 9
12719
12720         # simulate changelog catalog almost full
12721         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12722         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12723
12724         for i in $(seq $MDSCOUNT); do
12725                 cl_users=(${CL_USERS[mds$i]})
12726                 cl_user1[mds$i]="${cl_users[0]}"
12727                 cl_user2[mds$i]="${cl_users[1]}"
12728
12729                 [ -n "${cl_user1[mds$i]}" ] ||
12730                         error "mds$i: no user registered"
12731                 [ -n "${cl_user2[mds$i]}" ] ||
12732                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12733
12734                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12735                 [ -n "$user_rec1" ] ||
12736                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12737                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12738                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12739                 [ -n "$user_rec2" ] ||
12740                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12741                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12742                      "$user_rec1 + 2 == $user_rec2"
12743                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12744                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12745                               "$user_rec1 + 2, but is $user_rec2"
12746                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12747                 [ -n "$user_rec2" ] ||
12748                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12749                 [ $user_rec1 == $user_rec2 ] ||
12750                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12751                               "$user_rec1, but is $user_rec2"
12752         done
12753
12754         # force cl_user2 to be idle (2nd part) and to reach
12755         # changelog_max_idle_time
12756         sleep 2
12757
12758         # generate one more changelog to trigger fail_loc
12759         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12760                 error "create $DIR/$tdir/${tfile}bis failed"
12761
12762         # ensure gc thread is done
12763         for i in $(mdts_nodes); do
12764                 wait_update $i \
12765                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12766                         error "$i: GC-thread not done"
12767         done
12768
12769         local first_rec
12770         for i in $(seq $MDSCOUNT); do
12771                 # check cl_user1 still registered
12772                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12773                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12774                 # check cl_user2 unregistered
12775                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12776                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12777
12778                 # check changelogs are present and starting at $user_rec1 + 1
12779                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12780                 [ -n "$user_rec1" ] ||
12781                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12782                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12783                             awk '{ print $1; exit; }')
12784
12785                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12786                 [ $((user_rec1 + 1)) == $first_rec ] ||
12787                         error "mds$i: first index should be $user_rec1 + 1, " \
12788                               "but is $first_rec"
12789         done
12790 }
12791 run_test 160f "changelog garbage collect (timestamped users)"
12792
12793 test_160g() {
12794         remote_mds_nodsh && skip "remote MDS with nodsh"
12795         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12796                 skip "Need MDS version at least 2.10.56"
12797
12798         local mdts=$(comma_list $(mdts_nodes))
12799
12800         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12801         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12802
12803         # Create a user
12804         changelog_register || error "first changelog_register failed"
12805         changelog_register || error "second changelog_register failed"
12806         local cl_users
12807         declare -A cl_user1
12808         declare -A cl_user2
12809         local user_rec1
12810         local user_rec2
12811         local i
12812
12813         # generate some changelog records to accumulate on each MDT
12814         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12815         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12816                 error "create $DIR/$tdir/$tfile failed"
12817
12818         # check changelogs have been generated
12819         local nbcl=$(changelog_dump | wc -l)
12820         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12821
12822         # reduce the max_idle_indexes value to make sure we exceed it
12823         max_ndx=$((nbcl / 2 - 1))
12824
12825         for param in "changelog_max_idle_indexes=$max_ndx" \
12826                      "changelog_gc=1" \
12827                      "changelog_min_gc_interval=2" \
12828                      "changelog_min_free_cat_entries=3"; do
12829                 local MDT0=$(facet_svc $SINGLEMDS)
12830                 local var="${param%=*}"
12831                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12832
12833                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12834                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12835                         error "unable to set mdd.*.$param"
12836         done
12837
12838         # simulate changelog catalog almost full
12839         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12840         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12841
12842         for i in $(seq $MDSCOUNT); do
12843                 cl_users=(${CL_USERS[mds$i]})
12844                 cl_user1[mds$i]="${cl_users[0]}"
12845                 cl_user2[mds$i]="${cl_users[1]}"
12846
12847                 [ -n "${cl_user1[mds$i]}" ] ||
12848                         error "mds$i: no user registered"
12849                 [ -n "${cl_user2[mds$i]}" ] ||
12850                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12851
12852                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12853                 [ -n "$user_rec1" ] ||
12854                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12855                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12856                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12857                 [ -n "$user_rec2" ] ||
12858                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12859                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12860                      "$user_rec1 + 2 == $user_rec2"
12861                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12862                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12863                               "$user_rec1 + 2, but is $user_rec2"
12864                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12865                 [ -n "$user_rec2" ] ||
12866                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12867                 [ $user_rec1 == $user_rec2 ] ||
12868                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12869                               "$user_rec1, but is $user_rec2"
12870         done
12871
12872         # ensure we are past the previous changelog_min_gc_interval set above
12873         sleep 2
12874
12875         # generate one more changelog to trigger fail_loc
12876         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12877                 error "create $DIR/$tdir/${tfile}bis failed"
12878
12879         # ensure gc thread is done
12880         for i in $(mdts_nodes); do
12881                 wait_update $i \
12882                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12883                         error "$i: GC-thread not done"
12884         done
12885
12886         local first_rec
12887         for i in $(seq $MDSCOUNT); do
12888                 # check cl_user1 still registered
12889                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12890                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12891                 # check cl_user2 unregistered
12892                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12893                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12894
12895                 # check changelogs are present and starting at $user_rec1 + 1
12896                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12897                 [ -n "$user_rec1" ] ||
12898                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12899                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12900                             awk '{ print $1; exit; }')
12901
12902                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12903                 [ $((user_rec1 + 1)) == $first_rec ] ||
12904                         error "mds$i: first index should be $user_rec1 + 1, " \
12905                               "but is $first_rec"
12906         done
12907 }
12908 run_test 160g "changelog garbage collect (old users)"
12909
12910 test_160h() {
12911         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12912         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12913                 skip "Need MDS version at least 2.10.56"
12914
12915         local mdts=$(comma_list $(mdts_nodes))
12916
12917         # Create a user
12918         changelog_register || error "first changelog_register failed"
12919         changelog_register || error "second changelog_register failed"
12920         local cl_users
12921         declare -A cl_user1
12922         declare -A cl_user2
12923         local user_rec1
12924         local user_rec2
12925         local i
12926
12927         # generate some changelog records to accumulate on each MDT
12928         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12929         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12930                 error "create $DIR/$tdir/$tfile failed"
12931
12932         # check changelogs have been generated
12933         local nbcl=$(changelog_dump | wc -l)
12934         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12935
12936         for param in "changelog_max_idle_time=10" \
12937                      "changelog_gc=1" \
12938                      "changelog_min_gc_interval=2"; do
12939                 local MDT0=$(facet_svc $SINGLEMDS)
12940                 local var="${param%=*}"
12941                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12942
12943                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12944                 do_nodes $mdts $LCTL set_param mdd.*.$param
12945         done
12946
12947         # force cl_user2 to be idle (1st part)
12948         sleep 9
12949
12950         for i in $(seq $MDSCOUNT); do
12951                 cl_users=(${CL_USERS[mds$i]})
12952                 cl_user1[mds$i]="${cl_users[0]}"
12953                 cl_user2[mds$i]="${cl_users[1]}"
12954
12955                 [ -n "${cl_user1[mds$i]}" ] ||
12956                         error "mds$i: no user registered"
12957                 [ -n "${cl_user2[mds$i]}" ] ||
12958                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12959
12960                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12961                 [ -n "$user_rec1" ] ||
12962                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12963                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12964                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12965                 [ -n "$user_rec2" ] ||
12966                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12967                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12968                      "$user_rec1 + 2 == $user_rec2"
12969                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12970                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12971                               "$user_rec1 + 2, but is $user_rec2"
12972                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12973                 [ -n "$user_rec2" ] ||
12974                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12975                 [ $user_rec1 == $user_rec2 ] ||
12976                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12977                               "$user_rec1, but is $user_rec2"
12978         done
12979
12980         # force cl_user2 to be idle (2nd part) and to reach
12981         # changelog_max_idle_time
12982         sleep 2
12983
12984         # force each GC-thread start and block then
12985         # one per MDT/MDD, set fail_val accordingly
12986         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12987         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12988
12989         # generate more changelogs to trigger fail_loc
12990         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12991                 error "create $DIR/$tdir/${tfile}bis failed"
12992
12993         # stop MDT to stop GC-thread, should be done in back-ground as it will
12994         # block waiting for the thread to be released and exit
12995         declare -A stop_pids
12996         for i in $(seq $MDSCOUNT); do
12997                 stop mds$i &
12998                 stop_pids[mds$i]=$!
12999         done
13000
13001         for i in $(mdts_nodes); do
13002                 local facet
13003                 local nb=0
13004                 local facets=$(facets_up_on_host $i)
13005
13006                 for facet in ${facets//,/ }; do
13007                         if [[ $facet == mds* ]]; then
13008                                 nb=$((nb + 1))
13009                         fi
13010                 done
13011                 # ensure each MDS's gc threads are still present and all in "R"
13012                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13013                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13014                         error "$i: expected $nb GC-thread"
13015                 wait_update $i \
13016                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13017                         "R" 20 ||
13018                         error "$i: GC-thread not found in R-state"
13019                 # check umounts of each MDT on MDS have reached kthread_stop()
13020                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13021                         error "$i: expected $nb umount"
13022                 wait_update $i \
13023                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13024                         error "$i: umount not found in D-state"
13025         done
13026
13027         # release all GC-threads
13028         do_nodes $mdts $LCTL set_param fail_loc=0
13029
13030         # wait for MDT stop to complete
13031         for i in $(seq $MDSCOUNT); do
13032                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13033         done
13034
13035         # XXX
13036         # may try to check if any orphan changelog records are present
13037         # via ldiskfs/zfs and llog_reader...
13038
13039         # re-start/mount MDTs
13040         for i in $(seq $MDSCOUNT); do
13041                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13042                         error "Fail to start mds$i"
13043         done
13044
13045         local first_rec
13046         for i in $(seq $MDSCOUNT); do
13047                 # check cl_user1 still registered
13048                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13049                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13050                 # check cl_user2 unregistered
13051                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13052                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13053
13054                 # check changelogs are present and starting at $user_rec1 + 1
13055                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13056                 [ -n "$user_rec1" ] ||
13057                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13058                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13059                             awk '{ print $1; exit; }')
13060
13061                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13062                 [ $((user_rec1 + 1)) == $first_rec ] ||
13063                         error "mds$i: first index should be $user_rec1 + 1, " \
13064                               "but is $first_rec"
13065         done
13066 }
13067 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13068               "during mount"
13069
13070 test_160i() {
13071
13072         local mdts=$(comma_list $(mdts_nodes))
13073
13074         changelog_register || error "first changelog_register failed"
13075
13076         # generate some changelog records to accumulate on each MDT
13077         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13078         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13079                 error "create $DIR/$tdir/$tfile failed"
13080
13081         # check changelogs have been generated
13082         local nbcl=$(changelog_dump | wc -l)
13083         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13084
13085         # simulate race between register and unregister
13086         # XXX as fail_loc is set per-MDS, with DNE configs the race
13087         # simulation will only occur for one MDT per MDS and for the
13088         # others the normal race scenario will take place
13089         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13090         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13091         do_nodes $mdts $LCTL set_param fail_val=1
13092
13093         # unregister 1st user
13094         changelog_deregister &
13095         local pid1=$!
13096         # wait some time for deregister work to reach race rdv
13097         sleep 2
13098         # register 2nd user
13099         changelog_register || error "2nd user register failed"
13100
13101         wait $pid1 || error "1st user deregister failed"
13102
13103         local i
13104         local last_rec
13105         declare -A LAST_REC
13106         for i in $(seq $MDSCOUNT); do
13107                 if changelog_users mds$i | grep "^cl"; then
13108                         # make sure new records are added with one user present
13109                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13110                                           awk '/^current.index:/ { print $NF }')
13111                 else
13112                         error "mds$i has no user registered"
13113                 fi
13114         done
13115
13116         # generate more changelog records to accumulate on each MDT
13117         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13118                 error "create $DIR/$tdir/${tfile}bis failed"
13119
13120         for i in $(seq $MDSCOUNT); do
13121                 last_rec=$(changelog_users $SINGLEMDS |
13122                            awk '/^current.index:/ { print $NF }')
13123                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13124                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13125                         error "changelogs are off on mds$i"
13126         done
13127 }
13128 run_test 160i "changelog user register/unregister race"
13129
13130 test_161a() {
13131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13132
13133         test_mkdir -c1 $DIR/$tdir
13134         cp /etc/hosts $DIR/$tdir/$tfile
13135         test_mkdir -c1 $DIR/$tdir/foo1
13136         test_mkdir -c1 $DIR/$tdir/foo2
13137         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13138         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13139         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13140         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13141         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13142         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13143                 $LFS fid2path $DIR $FID
13144                 error "bad link ea"
13145         fi
13146         # middle
13147         rm $DIR/$tdir/foo2/zachary
13148         # last
13149         rm $DIR/$tdir/foo2/thor
13150         # first
13151         rm $DIR/$tdir/$tfile
13152         # rename
13153         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13154         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13155                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13156         rm $DIR/$tdir/foo2/maggie
13157
13158         # overflow the EA
13159         local longname=$tfile.avg_len_is_thirty_two_
13160         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13161                 error_noexit 'failed to unlink many hardlinks'" EXIT
13162         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13163                 error "failed to hardlink many files"
13164         links=$($LFS fid2path $DIR $FID | wc -l)
13165         echo -n "${links}/1000 links in link EA"
13166         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13167 }
13168 run_test 161a "link ea sanity"
13169
13170 test_161b() {
13171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13172         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13173
13174         local MDTIDX=1
13175         local remote_dir=$DIR/$tdir/remote_dir
13176
13177         mkdir -p $DIR/$tdir
13178         $LFS mkdir -i $MDTIDX $remote_dir ||
13179                 error "create remote directory failed"
13180
13181         cp /etc/hosts $remote_dir/$tfile
13182         mkdir -p $remote_dir/foo1
13183         mkdir -p $remote_dir/foo2
13184         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13185         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13186         ln $remote_dir/$tfile $remote_dir/foo1/luna
13187         ln $remote_dir/$tfile $remote_dir/foo2/thor
13188
13189         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13190                      tr -d ']')
13191         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13192                 $LFS fid2path $DIR $FID
13193                 error "bad link ea"
13194         fi
13195         # middle
13196         rm $remote_dir/foo2/zachary
13197         # last
13198         rm $remote_dir/foo2/thor
13199         # first
13200         rm $remote_dir/$tfile
13201         # rename
13202         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13203         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13204         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13205                 $LFS fid2path $DIR $FID
13206                 error "bad link rename"
13207         fi
13208         rm $remote_dir/foo2/maggie
13209
13210         # overflow the EA
13211         local longname=filename_avg_len_is_thirty_two_
13212         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13213                 error "failed to hardlink many files"
13214         links=$($LFS fid2path $DIR $FID | wc -l)
13215         echo -n "${links}/1000 links in link EA"
13216         [[ ${links} -gt 60 ]] ||
13217                 error "expected at least 60 links in link EA"
13218         unlinkmany $remote_dir/foo2/$longname 1000 ||
13219         error "failed to unlink many hardlinks"
13220 }
13221 run_test 161b "link ea sanity under remote directory"
13222
13223 test_161c() {
13224         remote_mds_nodsh && skip "remote MDS with nodsh"
13225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13226         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13227                 skip "Need MDS version at least 2.1.5"
13228
13229         # define CLF_RENAME_LAST 0x0001
13230         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13231         changelog_register || error "changelog_register failed"
13232
13233         rm -rf $DIR/$tdir
13234         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13235         touch $DIR/$tdir/foo_161c
13236         touch $DIR/$tdir/bar_161c
13237         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13238         changelog_dump | grep RENME | tail -n 5
13239         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13240         changelog_clear 0 || error "changelog_clear failed"
13241         if [ x$flags != "x0x1" ]; then
13242                 error "flag $flags is not 0x1"
13243         fi
13244
13245         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13246         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13247         touch $DIR/$tdir/foo_161c
13248         touch $DIR/$tdir/bar_161c
13249         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13250         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13251         changelog_dump | grep RENME | tail -n 5
13252         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13253         changelog_clear 0 || error "changelog_clear failed"
13254         if [ x$flags != "x0x0" ]; then
13255                 error "flag $flags is not 0x0"
13256         fi
13257         echo "rename overwrite a target having nlink > 1," \
13258                 "changelog record has flags of $flags"
13259
13260         # rename doesn't overwrite a target (changelog flag 0x0)
13261         touch $DIR/$tdir/foo_161c
13262         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13263         changelog_dump | grep RENME | tail -n 5
13264         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13265         changelog_clear 0 || error "changelog_clear failed"
13266         if [ x$flags != "x0x0" ]; then
13267                 error "flag $flags is not 0x0"
13268         fi
13269         echo "rename doesn't overwrite a target," \
13270                 "changelog record has flags of $flags"
13271
13272         # define CLF_UNLINK_LAST 0x0001
13273         # unlink a file having nlink = 1 (changelog flag 0x1)
13274         rm -f $DIR/$tdir/foo2_161c
13275         changelog_dump | grep UNLNK | tail -n 5
13276         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13277         changelog_clear 0 || error "changelog_clear failed"
13278         if [ x$flags != "x0x1" ]; then
13279                 error "flag $flags is not 0x1"
13280         fi
13281         echo "unlink a file having nlink = 1," \
13282                 "changelog record has flags of $flags"
13283
13284         # unlink a file having nlink > 1 (changelog flag 0x0)
13285         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13286         rm -f $DIR/$tdir/foobar_161c
13287         changelog_dump | grep UNLNK | tail -n 5
13288         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13289         changelog_clear 0 || error "changelog_clear failed"
13290         if [ x$flags != "x0x0" ]; then
13291                 error "flag $flags is not 0x0"
13292         fi
13293         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13294 }
13295 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13296
13297 test_161d() {
13298         remote_mds_nodsh && skip "remote MDS with nodsh"
13299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13300
13301         local pid
13302         local fid
13303
13304         changelog_register || error "changelog_register failed"
13305
13306         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13307         # interfer with $MOUNT/.lustre/fid/ access
13308         mkdir $DIR/$tdir
13309         [[ $? -eq 0 ]] || error "mkdir failed"
13310
13311         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13312         $LCTL set_param fail_loc=0x8000140c
13313         # 5s pause
13314         $LCTL set_param fail_val=5
13315
13316         # create file
13317         echo foofoo > $DIR/$tdir/$tfile &
13318         pid=$!
13319
13320         # wait for create to be delayed
13321         sleep 2
13322
13323         ps -p $pid
13324         [[ $? -eq 0 ]] || error "create should be blocked"
13325
13326         local tempfile=$(mktemp)
13327         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13328         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13329         # some delay may occur during ChangeLog publishing and file read just
13330         # above, that could allow file write to happen finally
13331         [[ -s $tempfile ]] && echo "file should be empty"
13332
13333         $LCTL set_param fail_loc=0
13334
13335         wait $pid
13336         [[ $? -eq 0 ]] || error "create failed"
13337 }
13338 run_test 161d "create with concurrent .lustre/fid access"
13339
13340 check_path() {
13341         local expected="$1"
13342         shift
13343         local fid="$2"
13344
13345         local path
13346         path=$($LFS fid2path "$@")
13347         local rc=$?
13348
13349         if [ $rc -ne 0 ]; then
13350                 error "path looked up of '$expected' failed: rc=$rc"
13351         elif [ "$path" != "$expected" ]; then
13352                 error "path looked up '$path' instead of '$expected'"
13353         else
13354                 echo "FID '$fid' resolves to path '$path' as expected"
13355         fi
13356 }
13357
13358 test_162a() { # was test_162
13359         test_mkdir -p -c1 $DIR/$tdir/d2
13360         touch $DIR/$tdir/d2/$tfile
13361         touch $DIR/$tdir/d2/x1
13362         touch $DIR/$tdir/d2/x2
13363         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13364         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13365         # regular file
13366         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13367         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13368
13369         # softlink
13370         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13371         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13372         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13373
13374         # softlink to wrong file
13375         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13376         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13377         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13378
13379         # hardlink
13380         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13381         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13382         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13383         # fid2path dir/fsname should both work
13384         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13385         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13386
13387         # hardlink count: check that there are 2 links
13388         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13389         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13390
13391         # hardlink indexing: remove the first link
13392         rm $DIR/$tdir/d2/p/q/r/hlink
13393         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13394 }
13395 run_test 162a "path lookup sanity"
13396
13397 test_162b() {
13398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13400
13401         mkdir $DIR/$tdir
13402         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13403                                 error "create striped dir failed"
13404
13405         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13406                                         tail -n 1 | awk '{print $2}')
13407         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13408
13409         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13410         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13411
13412         # regular file
13413         for ((i=0;i<5;i++)); do
13414                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13415                         error "get fid for f$i failed"
13416                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13417
13418                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13419                         error "get fid for d$i failed"
13420                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13421         done
13422
13423         return 0
13424 }
13425 run_test 162b "striped directory path lookup sanity"
13426
13427 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13428 test_162c() {
13429         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13430                 skip "Need MDS version at least 2.7.51"
13431
13432         local lpath=$tdir.local
13433         local rpath=$tdir.remote
13434
13435         test_mkdir $DIR/$lpath
13436         test_mkdir $DIR/$rpath
13437
13438         for ((i = 0; i <= 101; i++)); do
13439                 lpath="$lpath/$i"
13440                 mkdir $DIR/$lpath
13441                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13442                         error "get fid for local directory $DIR/$lpath failed"
13443                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13444
13445                 rpath="$rpath/$i"
13446                 test_mkdir $DIR/$rpath
13447                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13448                         error "get fid for remote directory $DIR/$rpath failed"
13449                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13450         done
13451
13452         return 0
13453 }
13454 run_test 162c "fid2path works with paths 100 or more directories deep"
13455
13456 test_169() {
13457         # do directio so as not to populate the page cache
13458         log "creating a 10 Mb file"
13459         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13460         log "starting reads"
13461         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13462         log "truncating the file"
13463         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13464         log "killing dd"
13465         kill %+ || true # reads might have finished
13466         echo "wait until dd is finished"
13467         wait
13468         log "removing the temporary file"
13469         rm -rf $DIR/$tfile || error "tmp file removal failed"
13470 }
13471 run_test 169 "parallel read and truncate should not deadlock"
13472
13473 test_170() {
13474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13475
13476         $LCTL clear     # bug 18514
13477         $LCTL debug_daemon start $TMP/${tfile}_log_good
13478         touch $DIR/$tfile
13479         $LCTL debug_daemon stop
13480         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13481                 error "sed failed to read log_good"
13482
13483         $LCTL debug_daemon start $TMP/${tfile}_log_good
13484         rm -rf $DIR/$tfile
13485         $LCTL debug_daemon stop
13486
13487         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13488                error "lctl df log_bad failed"
13489
13490         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13491         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13492
13493         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13494         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13495
13496         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13497                 error "bad_line good_line1 good_line2 are empty"
13498
13499         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13500         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13501         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13502
13503         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13504         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13505         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13506
13507         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13508                 error "bad_line_new good_line_new are empty"
13509
13510         local expected_good=$((good_line1 + good_line2*2))
13511
13512         rm -f $TMP/${tfile}*
13513         # LU-231, short malformed line may not be counted into bad lines
13514         if [ $bad_line -ne $bad_line_new ] &&
13515                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13516                 error "expected $bad_line bad lines, but got $bad_line_new"
13517                 return 1
13518         fi
13519
13520         if [ $expected_good -ne $good_line_new ]; then
13521                 error "expected $expected_good good lines, but got $good_line_new"
13522                 return 2
13523         fi
13524         true
13525 }
13526 run_test 170 "test lctl df to handle corrupted log ====================="
13527
13528 test_171() { # bug20592
13529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13530
13531         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13532         $LCTL set_param fail_loc=0x50e
13533         $LCTL set_param fail_val=3000
13534         multiop_bg_pause $DIR/$tfile O_s || true
13535         local MULTIPID=$!
13536         kill -USR1 $MULTIPID
13537         # cause log dump
13538         sleep 3
13539         wait $MULTIPID
13540         if dmesg | grep "recursive fault"; then
13541                 error "caught a recursive fault"
13542         fi
13543         $LCTL set_param fail_loc=0
13544         true
13545 }
13546 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13547
13548 # it would be good to share it with obdfilter-survey/iokit-libecho code
13549 setup_obdecho_osc () {
13550         local rc=0
13551         local ost_nid=$1
13552         local obdfilter_name=$2
13553         echo "Creating new osc for $obdfilter_name on $ost_nid"
13554         # make sure we can find loopback nid
13555         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13556
13557         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13558                            ${obdfilter_name}_osc_UUID || rc=2; }
13559         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13560                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13561         return $rc
13562 }
13563
13564 cleanup_obdecho_osc () {
13565         local obdfilter_name=$1
13566         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13567         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13568         return 0
13569 }
13570
13571 obdecho_test() {
13572         local OBD=$1
13573         local node=$2
13574         local pages=${3:-64}
13575         local rc=0
13576         local id
13577
13578         local count=10
13579         local obd_size=$(get_obd_size $node $OBD)
13580         local page_size=$(get_page_size $node)
13581         if [[ -n "$obd_size" ]]; then
13582                 local new_count=$((obd_size / (pages * page_size / 1024)))
13583                 [[ $new_count -ge $count ]] || count=$new_count
13584         fi
13585
13586         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13587         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13588                            rc=2; }
13589         if [ $rc -eq 0 ]; then
13590             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13591             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13592         fi
13593         echo "New object id is $id"
13594         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13595                            rc=4; }
13596         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13597                            "test_brw $count w v $pages $id" || rc=4; }
13598         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13599                            rc=4; }
13600         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13601                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13602         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13603                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13604         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13605         return $rc
13606 }
13607
13608 test_180a() {
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610
13611         if ! module_loaded obdecho; then
13612                 load_module obdecho/obdecho &&
13613                         stack_trap "rmmod obdecho" EXIT ||
13614                         error "unable to load obdecho on client"
13615         fi
13616
13617         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13618         local host=$($LCTL get_param -n osc.$osc.import |
13619                      awk '/current_connection:/ { print $2 }' )
13620         local target=$($LCTL get_param -n osc.$osc.import |
13621                        awk '/target:/ { print $2 }' )
13622         target=${target%_UUID}
13623
13624         if [ -n "$target" ]; then
13625                 setup_obdecho_osc $host $target &&
13626                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13627                         { error "obdecho setup failed with $?"; return; }
13628
13629                 obdecho_test ${target}_osc client ||
13630                         error "obdecho_test failed on ${target}_osc"
13631         else
13632                 $LCTL get_param osc.$osc.import
13633                 error "there is no osc.$osc.import target"
13634         fi
13635 }
13636 run_test 180a "test obdecho on osc"
13637
13638 test_180b() {
13639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13640         remote_ost_nodsh && skip "remote OST with nodsh"
13641
13642         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13643                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13644                 error "failed to load module obdecho"
13645
13646         local target=$(do_facet ost1 $LCTL dl |
13647                        awk '/obdfilter/ { print $4; exit; }')
13648
13649         if [ -n "$target" ]; then
13650                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13651         else
13652                 do_facet ost1 $LCTL dl
13653                 error "there is no obdfilter target on ost1"
13654         fi
13655 }
13656 run_test 180b "test obdecho directly on obdfilter"
13657
13658 test_180c() { # LU-2598
13659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13660         remote_ost_nodsh && skip "remote OST with nodsh"
13661         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13662                 skip "Need MDS version at least 2.4.0"
13663
13664         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13665                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13666                 error "failed to load module obdecho"
13667
13668         local target=$(do_facet ost1 $LCTL dl |
13669                        awk '/obdfilter/ { print $4; exit; }')
13670
13671         if [ -n "$target" ]; then
13672                 local pages=16384 # 64MB bulk I/O RPC size
13673
13674                 obdecho_test "$target" ost1 "$pages" ||
13675                         error "obdecho_test with pages=$pages failed with $?"
13676         else
13677                 do_facet ost1 $LCTL dl
13678                 error "there is no obdfilter target on ost1"
13679         fi
13680 }
13681 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13682
13683 test_181() { # bug 22177
13684         test_mkdir $DIR/$tdir
13685         # create enough files to index the directory
13686         createmany -o $DIR/$tdir/foobar 4000
13687         # print attributes for debug purpose
13688         lsattr -d .
13689         # open dir
13690         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13691         MULTIPID=$!
13692         # remove the files & current working dir
13693         unlinkmany $DIR/$tdir/foobar 4000
13694         rmdir $DIR/$tdir
13695         kill -USR1 $MULTIPID
13696         wait $MULTIPID
13697         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13698         return 0
13699 }
13700 run_test 181 "Test open-unlinked dir ========================"
13701
13702 test_182() {
13703         local fcount=1000
13704         local tcount=10
13705
13706         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13707
13708         $LCTL set_param mdc.*.rpc_stats=clear
13709
13710         for (( i = 0; i < $tcount; i++ )) ; do
13711                 mkdir $DIR/$tdir/$i
13712         done
13713
13714         for (( i = 0; i < $tcount; i++ )) ; do
13715                 createmany -o $DIR/$tdir/$i/f- $fcount &
13716         done
13717         wait
13718
13719         for (( i = 0; i < $tcount; i++ )) ; do
13720                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13721         done
13722         wait
13723
13724         $LCTL get_param mdc.*.rpc_stats
13725
13726         rm -rf $DIR/$tdir
13727 }
13728 run_test 182 "Test parallel modify metadata operations ================"
13729
13730 test_183() { # LU-2275
13731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13732         remote_mds_nodsh && skip "remote MDS with nodsh"
13733         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13734                 skip "Need MDS version at least 2.3.56"
13735
13736         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13737         echo aaa > $DIR/$tdir/$tfile
13738
13739 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13740         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13741
13742         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13743         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13744
13745         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13746
13747         # Flush negative dentry cache
13748         touch $DIR/$tdir/$tfile
13749
13750         # We are not checking for any leaked references here, they'll
13751         # become evident next time we do cleanup with module unload.
13752         rm -rf $DIR/$tdir
13753 }
13754 run_test 183 "No crash or request leak in case of strange dispositions ========"
13755
13756 # test suite 184 is for LU-2016, LU-2017
13757 test_184a() {
13758         check_swap_layouts_support
13759
13760         dir0=$DIR/$tdir/$testnum
13761         test_mkdir -p -c1 $dir0
13762         ref1=/etc/passwd
13763         ref2=/etc/group
13764         file1=$dir0/f1
13765         file2=$dir0/f2
13766         $LFS setstripe -c1 $file1
13767         cp $ref1 $file1
13768         $LFS setstripe -c2 $file2
13769         cp $ref2 $file2
13770         gen1=$($LFS getstripe -g $file1)
13771         gen2=$($LFS getstripe -g $file2)
13772
13773         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13774         gen=$($LFS getstripe -g $file1)
13775         [[ $gen1 != $gen ]] ||
13776                 "Layout generation on $file1 does not change"
13777         gen=$($LFS getstripe -g $file2)
13778         [[ $gen2 != $gen ]] ||
13779                 "Layout generation on $file2 does not change"
13780
13781         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13782         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13783
13784         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13785 }
13786 run_test 184a "Basic layout swap"
13787
13788 test_184b() {
13789         check_swap_layouts_support
13790
13791         dir0=$DIR/$tdir/$testnum
13792         mkdir -p $dir0 || error "creating dir $dir0"
13793         file1=$dir0/f1
13794         file2=$dir0/f2
13795         file3=$dir0/f3
13796         dir1=$dir0/d1
13797         dir2=$dir0/d2
13798         mkdir $dir1 $dir2
13799         $LFS setstripe -c1 $file1
13800         $LFS setstripe -c2 $file2
13801         $LFS setstripe -c1 $file3
13802         chown $RUNAS_ID $file3
13803         gen1=$($LFS getstripe -g $file1)
13804         gen2=$($LFS getstripe -g $file2)
13805
13806         $LFS swap_layouts $dir1 $dir2 &&
13807                 error "swap of directories layouts should fail"
13808         $LFS swap_layouts $dir1 $file1 &&
13809                 error "swap of directory and file layouts should fail"
13810         $RUNAS $LFS swap_layouts $file1 $file2 &&
13811                 error "swap of file we cannot write should fail"
13812         $LFS swap_layouts $file1 $file3 &&
13813                 error "swap of file with different owner should fail"
13814         /bin/true # to clear error code
13815 }
13816 run_test 184b "Forbidden layout swap (will generate errors)"
13817
13818 test_184c() {
13819         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13820         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13821         check_swap_layouts_support
13822
13823         local dir0=$DIR/$tdir/$testnum
13824         mkdir -p $dir0 || error "creating dir $dir0"
13825
13826         local ref1=$dir0/ref1
13827         local ref2=$dir0/ref2
13828         local file1=$dir0/file1
13829         local file2=$dir0/file2
13830         # create a file large enough for the concurrent test
13831         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13832         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13833         echo "ref file size: ref1($(stat -c %s $ref1))," \
13834              "ref2($(stat -c %s $ref2))"
13835
13836         cp $ref2 $file2
13837         dd if=$ref1 of=$file1 bs=16k &
13838         local DD_PID=$!
13839
13840         # Make sure dd starts to copy file
13841         while [ ! -f $file1 ]; do sleep 0.1; done
13842
13843         $LFS swap_layouts $file1 $file2
13844         local rc=$?
13845         wait $DD_PID
13846         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13847         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13848
13849         # how many bytes copied before swapping layout
13850         local copied=$(stat -c %s $file2)
13851         local remaining=$(stat -c %s $ref1)
13852         remaining=$((remaining - copied))
13853         echo "Copied $copied bytes before swapping layout..."
13854
13855         cmp -n $copied $file1 $ref2 | grep differ &&
13856                 error "Content mismatch [0, $copied) of ref2 and file1"
13857         cmp -n $copied $file2 $ref1 ||
13858                 error "Content mismatch [0, $copied) of ref1 and file2"
13859         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13860                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13861
13862         # clean up
13863         rm -f $ref1 $ref2 $file1 $file2
13864 }
13865 run_test 184c "Concurrent write and layout swap"
13866
13867 test_184d() {
13868         check_swap_layouts_support
13869         [ -z "$(which getfattr 2>/dev/null)" ] &&
13870                 skip_env "no getfattr command"
13871
13872         local file1=$DIR/$tdir/$tfile-1
13873         local file2=$DIR/$tdir/$tfile-2
13874         local file3=$DIR/$tdir/$tfile-3
13875         local lovea1
13876         local lovea2
13877
13878         mkdir -p $DIR/$tdir
13879         touch $file1 || error "create $file1 failed"
13880         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13881                 error "create $file2 failed"
13882         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13883                 error "create $file3 failed"
13884         lovea1=$(get_layout_param $file1)
13885
13886         $LFS swap_layouts $file2 $file3 ||
13887                 error "swap $file2 $file3 layouts failed"
13888         $LFS swap_layouts $file1 $file2 ||
13889                 error "swap $file1 $file2 layouts failed"
13890
13891         lovea2=$(get_layout_param $file2)
13892         echo "$lovea1"
13893         echo "$lovea2"
13894         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13895
13896         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13897         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13898 }
13899 run_test 184d "allow stripeless layouts swap"
13900
13901 test_184e() {
13902         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13903                 skip "Need MDS version at least 2.6.94"
13904         check_swap_layouts_support
13905         [ -z "$(which getfattr 2>/dev/null)" ] &&
13906                 skip_env "no getfattr command"
13907
13908         local file1=$DIR/$tdir/$tfile-1
13909         local file2=$DIR/$tdir/$tfile-2
13910         local file3=$DIR/$tdir/$tfile-3
13911         local lovea
13912
13913         mkdir -p $DIR/$tdir
13914         touch $file1 || error "create $file1 failed"
13915         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13916                 error "create $file2 failed"
13917         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13918                 error "create $file3 failed"
13919
13920         $LFS swap_layouts $file1 $file2 ||
13921                 error "swap $file1 $file2 layouts failed"
13922
13923         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13924         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13925
13926         echo 123 > $file1 || error "Should be able to write into $file1"
13927
13928         $LFS swap_layouts $file1 $file3 ||
13929                 error "swap $file1 $file3 layouts failed"
13930
13931         echo 123 > $file1 || error "Should be able to write into $file1"
13932
13933         rm -rf $file1 $file2 $file3
13934 }
13935 run_test 184e "Recreate layout after stripeless layout swaps"
13936
13937 test_184f() {
13938         # Create a file with name longer than sizeof(struct stat) ==
13939         # 144 to see if we can get chars from the file name to appear
13940         # in the returned striping. Note that 'f' == 0x66.
13941         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13942
13943         mkdir -p $DIR/$tdir
13944         mcreate $DIR/$tdir/$file
13945         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13946                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13947         fi
13948 }
13949 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13950
13951 test_185() { # LU-2441
13952         # LU-3553 - no volatile file support in old servers
13953         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13954                 skip "Need MDS version at least 2.3.60"
13955
13956         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13957         touch $DIR/$tdir/spoo
13958         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13959         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13960                 error "cannot create/write a volatile file"
13961         [ "$FILESET" == "" ] &&
13962         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13963                 error "FID is still valid after close"
13964
13965         multiop_bg_pause $DIR/$tdir vVw4096_c
13966         local multi_pid=$!
13967
13968         local OLD_IFS=$IFS
13969         IFS=":"
13970         local fidv=($fid)
13971         IFS=$OLD_IFS
13972         # assume that the next FID for this client is sequential, since stdout
13973         # is unfortunately eaten by multiop_bg_pause
13974         local n=$((${fidv[1]} + 1))
13975         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13976         if [ "$FILESET" == "" ]; then
13977                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13978                         error "FID is missing before close"
13979         fi
13980         kill -USR1 $multi_pid
13981         # 1 second delay, so if mtime change we will see it
13982         sleep 1
13983         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13984         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13985 }
13986 run_test 185 "Volatile file support"
13987
13988 test_187a() {
13989         remote_mds_nodsh && skip "remote MDS with nodsh"
13990         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13991                 skip "Need MDS version at least 2.3.0"
13992
13993         local dir0=$DIR/$tdir/$testnum
13994         mkdir -p $dir0 || error "creating dir $dir0"
13995
13996         local file=$dir0/file1
13997         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13998         local dv1=$($LFS data_version $file)
13999         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14000         local dv2=$($LFS data_version $file)
14001         [[ $dv1 != $dv2 ]] ||
14002                 error "data version did not change on write $dv1 == $dv2"
14003
14004         # clean up
14005         rm -f $file1
14006 }
14007 run_test 187a "Test data version change"
14008
14009 test_187b() {
14010         remote_mds_nodsh && skip "remote MDS with nodsh"
14011         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14012                 skip "Need MDS version at least 2.3.0"
14013
14014         local dir0=$DIR/$tdir/$testnum
14015         mkdir -p $dir0 || error "creating dir $dir0"
14016
14017         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14018         [[ ${DV[0]} != ${DV[1]} ]] ||
14019                 error "data version did not change on write"\
14020                       " ${DV[0]} == ${DV[1]}"
14021
14022         # clean up
14023         rm -f $file1
14024 }
14025 run_test 187b "Test data version change on volatile file"
14026
14027 test_200() {
14028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14029         remote_mgs_nodsh && skip "remote MGS with nodsh"
14030         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14031
14032         local POOL=${POOL:-cea1}
14033         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14034         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14035         # Pool OST targets
14036         local first_ost=0
14037         local last_ost=$(($OSTCOUNT - 1))
14038         local ost_step=2
14039         local ost_list=$(seq $first_ost $ost_step $last_ost)
14040         local ost_range="$first_ost $last_ost $ost_step"
14041         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14042         local file_dir=$POOL_ROOT/file_tst
14043         local subdir=$test_path/subdir
14044         local rc=0
14045
14046         if ! combined_mgs_mds ; then
14047                 mount_mgs_client
14048         fi
14049
14050         while : ; do
14051                 # former test_200a test_200b
14052                 pool_add $POOL                          || { rc=$? ; break; }
14053                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14054                 # former test_200c test_200d
14055                 mkdir -p $test_path
14056                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14057                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14058                 mkdir -p $subdir
14059                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14060                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14061                                                         || { rc=$? ; break; }
14062                 # former test_200e test_200f
14063                 local files=$((OSTCOUNT*3))
14064                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14065                                                         || { rc=$? ; break; }
14066                 pool_create_files $POOL $file_dir $files "$ost_list" \
14067                                                         || { rc=$? ; break; }
14068                 # former test_200g test_200h
14069                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14070                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14071
14072                 # former test_201a test_201b test_201c
14073                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14074
14075                 local f=$test_path/$tfile
14076                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14077                 pool_remove $POOL $f                    || { rc=$? ; break; }
14078                 break
14079         done
14080
14081         destroy_test_pools
14082
14083         if ! combined_mgs_mds ; then
14084                 umount_mgs_client
14085         fi
14086         return $rc
14087 }
14088 run_test 200 "OST pools"
14089
14090 # usage: default_attr <count | size | offset>
14091 default_attr() {
14092         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14093 }
14094
14095 # usage: check_default_stripe_attr
14096 check_default_stripe_attr() {
14097         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14098         case $1 in
14099         --stripe-count|-c)
14100                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14101         --stripe-size|-S)
14102                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14103         --stripe-index|-i)
14104                 EXPECTED=-1;;
14105         *)
14106                 error "unknown getstripe attr '$1'"
14107         esac
14108
14109         [ $ACTUAL == $EXPECTED ] ||
14110                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14111 }
14112
14113 test_204a() {
14114         test_mkdir $DIR/$tdir
14115         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14116
14117         check_default_stripe_attr --stripe-count
14118         check_default_stripe_attr --stripe-size
14119         check_default_stripe_attr --stripe-index
14120 }
14121 run_test 204a "Print default stripe attributes"
14122
14123 test_204b() {
14124         test_mkdir $DIR/$tdir
14125         $LFS setstripe --stripe-count 1 $DIR/$tdir
14126
14127         check_default_stripe_attr --stripe-size
14128         check_default_stripe_attr --stripe-index
14129 }
14130 run_test 204b "Print default stripe size and offset"
14131
14132 test_204c() {
14133         test_mkdir $DIR/$tdir
14134         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14135
14136         check_default_stripe_attr --stripe-count
14137         check_default_stripe_attr --stripe-index
14138 }
14139 run_test 204c "Print default stripe count and offset"
14140
14141 test_204d() {
14142         test_mkdir $DIR/$tdir
14143         $LFS setstripe --stripe-index 0 $DIR/$tdir
14144
14145         check_default_stripe_attr --stripe-count
14146         check_default_stripe_attr --stripe-size
14147 }
14148 run_test 204d "Print default stripe count and size"
14149
14150 test_204e() {
14151         test_mkdir $DIR/$tdir
14152         $LFS setstripe -d $DIR/$tdir
14153
14154         check_default_stripe_attr --stripe-count --raw
14155         check_default_stripe_attr --stripe-size --raw
14156         check_default_stripe_attr --stripe-index --raw
14157 }
14158 run_test 204e "Print raw stripe attributes"
14159
14160 test_204f() {
14161         test_mkdir $DIR/$tdir
14162         $LFS setstripe --stripe-count 1 $DIR/$tdir
14163
14164         check_default_stripe_attr --stripe-size --raw
14165         check_default_stripe_attr --stripe-index --raw
14166 }
14167 run_test 204f "Print raw stripe size and offset"
14168
14169 test_204g() {
14170         test_mkdir $DIR/$tdir
14171         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14172
14173         check_default_stripe_attr --stripe-count --raw
14174         check_default_stripe_attr --stripe-index --raw
14175 }
14176 run_test 204g "Print raw stripe count and offset"
14177
14178 test_204h() {
14179         test_mkdir $DIR/$tdir
14180         $LFS setstripe --stripe-index 0 $DIR/$tdir
14181
14182         check_default_stripe_attr --stripe-count --raw
14183         check_default_stripe_attr --stripe-size --raw
14184 }
14185 run_test 204h "Print raw stripe count and size"
14186
14187 # Figure out which job scheduler is being used, if any,
14188 # or use a fake one
14189 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14190         JOBENV=SLURM_JOB_ID
14191 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14192         JOBENV=LSB_JOBID
14193 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14194         JOBENV=PBS_JOBID
14195 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14196         JOBENV=LOADL_STEP_ID
14197 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14198         JOBENV=JOB_ID
14199 else
14200         $LCTL list_param jobid_name > /dev/null 2>&1
14201         if [ $? -eq 0 ]; then
14202                 JOBENV=nodelocal
14203         else
14204                 JOBENV=FAKE_JOBID
14205         fi
14206 fi
14207 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14208
14209 verify_jobstats() {
14210         local cmd=($1)
14211         shift
14212         local facets="$@"
14213
14214 # we don't really need to clear the stats for this test to work, since each
14215 # command has a unique jobid, but it makes debugging easier if needed.
14216 #       for facet in $facets; do
14217 #               local dev=$(convert_facet2label $facet)
14218 #               # clear old jobstats
14219 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14220 #       done
14221
14222         # use a new JobID for each test, or we might see an old one
14223         [ "$JOBENV" = "FAKE_JOBID" ] &&
14224                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14225
14226         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14227
14228         [ "$JOBENV" = "nodelocal" ] && {
14229                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14230                 $LCTL set_param jobid_name=$FAKE_JOBID
14231                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14232         }
14233
14234         log "Test: ${cmd[*]}"
14235         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14236
14237         if [ $JOBENV = "FAKE_JOBID" ]; then
14238                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14239         else
14240                 ${cmd[*]}
14241         fi
14242
14243         # all files are created on OST0000
14244         for facet in $facets; do
14245                 local stats="*.$(convert_facet2label $facet).job_stats"
14246
14247                 # strip out libtool wrappers for in-tree executables
14248                 if [ $(do_facet $facet lctl get_param $stats |
14249                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14250                         do_facet $facet lctl get_param $stats
14251                         error "No jobstats for $JOBVAL found on $facet::$stats"
14252                 fi
14253         done
14254 }
14255
14256 jobstats_set() {
14257         local new_jobenv=$1
14258
14259         set_persistent_param_and_check client "jobid_var" \
14260                 "$FSNAME.sys.jobid_var" $new_jobenv
14261 }
14262
14263 test_205() { # Job stats
14264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14265         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14266                 skip "Need MDS version with at least 2.7.1"
14267         remote_mgs_nodsh && skip "remote MGS with nodsh"
14268         remote_mds_nodsh && skip "remote MDS with nodsh"
14269         remote_ost_nodsh && skip "remote OST with nodsh"
14270         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14271                 skip "Server doesn't support jobstats"
14272         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14273
14274         local old_jobenv=$($LCTL get_param -n jobid_var)
14275         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14276
14277         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14278                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14279         else
14280                 stack_trap "do_facet mgs $PERM_CMD \
14281                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14282         fi
14283         changelog_register
14284
14285         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14286                                 mdt.*.job_cleanup_interval | head -n 1)
14287         local new_interval=5
14288         do_facet $SINGLEMDS \
14289                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14290         stack_trap "do_facet $SINGLEMDS \
14291                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14292         local start=$SECONDS
14293
14294         local cmd
14295         # mkdir
14296         cmd="mkdir $DIR/$tdir"
14297         verify_jobstats "$cmd" "$SINGLEMDS"
14298         # rmdir
14299         cmd="rmdir $DIR/$tdir"
14300         verify_jobstats "$cmd" "$SINGLEMDS"
14301         # mkdir on secondary MDT
14302         if [ $MDSCOUNT -gt 1 ]; then
14303                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14304                 verify_jobstats "$cmd" "mds2"
14305         fi
14306         # mknod
14307         cmd="mknod $DIR/$tfile c 1 3"
14308         verify_jobstats "$cmd" "$SINGLEMDS"
14309         # unlink
14310         cmd="rm -f $DIR/$tfile"
14311         verify_jobstats "$cmd" "$SINGLEMDS"
14312         # create all files on OST0000 so verify_jobstats can find OST stats
14313         # open & close
14314         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14315         verify_jobstats "$cmd" "$SINGLEMDS"
14316         # setattr
14317         cmd="touch $DIR/$tfile"
14318         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14319         # write
14320         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14321         verify_jobstats "$cmd" "ost1"
14322         # read
14323         cancel_lru_locks osc
14324         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14325         verify_jobstats "$cmd" "ost1"
14326         # truncate
14327         cmd="$TRUNCATE $DIR/$tfile 0"
14328         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14329         # rename
14330         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14331         verify_jobstats "$cmd" "$SINGLEMDS"
14332         # jobstats expiry - sleep until old stats should be expired
14333         local left=$((new_interval + 5 - (SECONDS - start)))
14334         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14335                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14336                         "0" $left
14337         cmd="mkdir $DIR/$tdir.expire"
14338         verify_jobstats "$cmd" "$SINGLEMDS"
14339         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14340             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14341
14342         # Ensure that jobid are present in changelog (if supported by MDS)
14343         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14344                 changelog_dump | tail -10
14345                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14346                 [ $jobids -eq 9 ] ||
14347                         error "Wrong changelog jobid count $jobids != 9"
14348
14349                 # LU-5862
14350                 JOBENV="disable"
14351                 jobstats_set $JOBENV
14352                 touch $DIR/$tfile
14353                 changelog_dump | grep $tfile
14354                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14355                 [ $jobids -eq 0 ] ||
14356                         error "Unexpected jobids when jobid_var=$JOBENV"
14357         fi
14358
14359         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14360         JOBENV="JOBCOMPLEX"
14361         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14362
14363         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14364 }
14365 run_test 205 "Verify job stats"
14366
14367 # LU-1480, LU-1773 and LU-1657
14368 test_206() {
14369         mkdir -p $DIR/$tdir
14370         $LFS setstripe -c -1 $DIR/$tdir
14371 #define OBD_FAIL_LOV_INIT 0x1403
14372         $LCTL set_param fail_loc=0xa0001403
14373         $LCTL set_param fail_val=1
14374         touch $DIR/$tdir/$tfile || true
14375 }
14376 run_test 206 "fail lov_init_raid0() doesn't lbug"
14377
14378 test_207a() {
14379         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14380         local fsz=`stat -c %s $DIR/$tfile`
14381         cancel_lru_locks mdc
14382
14383         # do not return layout in getattr intent
14384 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14385         $LCTL set_param fail_loc=0x170
14386         local sz=`stat -c %s $DIR/$tfile`
14387
14388         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14389
14390         rm -rf $DIR/$tfile
14391 }
14392 run_test 207a "can refresh layout at glimpse"
14393
14394 test_207b() {
14395         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14396         local cksum=`md5sum $DIR/$tfile`
14397         local fsz=`stat -c %s $DIR/$tfile`
14398         cancel_lru_locks mdc
14399         cancel_lru_locks osc
14400
14401         # do not return layout in getattr intent
14402 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14403         $LCTL set_param fail_loc=0x171
14404
14405         # it will refresh layout after the file is opened but before read issues
14406         echo checksum is "$cksum"
14407         echo "$cksum" |md5sum -c --quiet || error "file differs"
14408
14409         rm -rf $DIR/$tfile
14410 }
14411 run_test 207b "can refresh layout at open"
14412
14413 test_208() {
14414         # FIXME: in this test suite, only RD lease is used. This is okay
14415         # for now as only exclusive open is supported. After generic lease
14416         # is done, this test suite should be revised. - Jinshan
14417
14418         remote_mds_nodsh && skip "remote MDS with nodsh"
14419         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14420                 skip "Need MDS version at least 2.4.52"
14421
14422         echo "==== test 1: verify get lease work"
14423         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14424
14425         echo "==== test 2: verify lease can be broken by upcoming open"
14426         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14427         local PID=$!
14428         sleep 1
14429
14430         $MULTIOP $DIR/$tfile oO_RDONLY:c
14431         kill -USR1 $PID && wait $PID || error "break lease error"
14432
14433         echo "==== test 3: verify lease can't be granted if an open already exists"
14434         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14435         local PID=$!
14436         sleep 1
14437
14438         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14439         kill -USR1 $PID && wait $PID || error "open file error"
14440
14441         echo "==== test 4: lease can sustain over recovery"
14442         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14443         PID=$!
14444         sleep 1
14445
14446         fail mds1
14447
14448         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14449
14450         echo "==== test 5: lease broken can't be regained by replay"
14451         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14452         PID=$!
14453         sleep 1
14454
14455         # open file to break lease and then recovery
14456         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14457         fail mds1
14458
14459         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14460
14461         rm -f $DIR/$tfile
14462 }
14463 run_test 208 "Exclusive open"
14464
14465 test_209() {
14466         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14467                 skip_env "must have disp_stripe"
14468
14469         touch $DIR/$tfile
14470         sync; sleep 5; sync;
14471
14472         echo 3 > /proc/sys/vm/drop_caches
14473         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14474
14475         # open/close 500 times
14476         for i in $(seq 500); do
14477                 cat $DIR/$tfile
14478         done
14479
14480         echo 3 > /proc/sys/vm/drop_caches
14481         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14482
14483         echo "before: $req_before, after: $req_after"
14484         [ $((req_after - req_before)) -ge 300 ] &&
14485                 error "open/close requests are not freed"
14486         return 0
14487 }
14488 run_test 209 "read-only open/close requests should be freed promptly"
14489
14490 test_212() {
14491         size=`date +%s`
14492         size=$((size % 8192 + 1))
14493         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14494         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14495         rm -f $DIR/f212 $DIR/f212.xyz
14496 }
14497 run_test 212 "Sendfile test ============================================"
14498
14499 test_213() {
14500         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14501         cancel_lru_locks osc
14502         lctl set_param fail_loc=0x8000040f
14503         # generate a read lock
14504         cat $DIR/$tfile > /dev/null
14505         # write to the file, it will try to cancel the above read lock.
14506         cat /etc/hosts >> $DIR/$tfile
14507 }
14508 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14509
14510 test_214() { # for bug 20133
14511         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14512         for (( i=0; i < 340; i++ )) ; do
14513                 touch $DIR/$tdir/d214c/a$i
14514         done
14515
14516         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14517         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14518         ls $DIR/d214c || error "ls $DIR/d214c failed"
14519         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14520         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14521 }
14522 run_test 214 "hash-indexed directory test - bug 20133"
14523
14524 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14525 create_lnet_proc_files() {
14526         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14527 }
14528
14529 # counterpart of create_lnet_proc_files
14530 remove_lnet_proc_files() {
14531         rm -f $TMP/lnet_$1.sys
14532 }
14533
14534 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14535 # 3rd arg as regexp for body
14536 check_lnet_proc_stats() {
14537         local l=$(cat "$TMP/lnet_$1" |wc -l)
14538         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14539
14540         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14541 }
14542
14543 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14544 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14545 # optional and can be regexp for 2nd line (lnet.routes case)
14546 check_lnet_proc_entry() {
14547         local blp=2          # blp stands for 'position of 1st line of body'
14548         [ -z "$5" ] || blp=3 # lnet.routes case
14549
14550         local l=$(cat "$TMP/lnet_$1" |wc -l)
14551         # subtracting one from $blp because the body can be empty
14552         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14553
14554         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14555                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14556
14557         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14558                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14559
14560         # bail out if any unexpected line happened
14561         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14562         [ "$?" != 0 ] || error "$2 misformatted"
14563 }
14564
14565 test_215() { # for bugs 18102, 21079, 21517
14566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14567
14568         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14569         local P='[1-9][0-9]*'           # positive numeric
14570         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14571         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14572         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14573         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14574
14575         local L1 # regexp for 1st line
14576         local L2 # regexp for 2nd line (optional)
14577         local BR # regexp for the rest (body)
14578
14579         # lnet.stats should look as 11 space-separated non-negative numerics
14580         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14581         create_lnet_proc_files "stats"
14582         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14583         remove_lnet_proc_files "stats"
14584
14585         # lnet.routes should look like this:
14586         # Routing disabled/enabled
14587         # net hops priority state router
14588         # where net is a string like tcp0, hops > 0, priority >= 0,
14589         # state is up/down,
14590         # router is a string like 192.168.1.1@tcp2
14591         L1="^Routing (disabled|enabled)$"
14592         L2="^net +hops +priority +state +router$"
14593         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14594         create_lnet_proc_files "routes"
14595         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14596         remove_lnet_proc_files "routes"
14597
14598         # lnet.routers should look like this:
14599         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14600         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14601         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14602         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14603         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14604         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14605         create_lnet_proc_files "routers"
14606         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14607         remove_lnet_proc_files "routers"
14608
14609         # lnet.peers should look like this:
14610         # nid refs state last max rtr min tx min queue
14611         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14612         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14613         # numeric (0 or >0 or <0), queue >= 0.
14614         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14615         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14616         create_lnet_proc_files "peers"
14617         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14618         remove_lnet_proc_files "peers"
14619
14620         # lnet.buffers  should look like this:
14621         # pages count credits min
14622         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14623         L1="^pages +count +credits +min$"
14624         BR="^ +$N +$N +$I +$I$"
14625         create_lnet_proc_files "buffers"
14626         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14627         remove_lnet_proc_files "buffers"
14628
14629         # lnet.nis should look like this:
14630         # nid status alive refs peer rtr max tx min
14631         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14632         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14633         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14634         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14635         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14636         create_lnet_proc_files "nis"
14637         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14638         remove_lnet_proc_files "nis"
14639
14640         # can we successfully write to lnet.stats?
14641         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14642 }
14643 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14644
14645 test_216() { # bug 20317
14646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14647         remote_ost_nodsh && skip "remote OST with nodsh"
14648
14649         local node
14650         local facets=$(get_facets OST)
14651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14652
14653         save_lustre_params client "osc.*.contention_seconds" > $p
14654         save_lustre_params $facets \
14655                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14656         save_lustre_params $facets \
14657                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14658         save_lustre_params $facets \
14659                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14660         clear_stats osc.*.osc_stats
14661
14662         # agressive lockless i/o settings
14663         do_nodes $(comma_list $(osts_nodes)) \
14664                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14665                         ldlm.namespaces.filter-*.contended_locks=0 \
14666                         ldlm.namespaces.filter-*.contention_seconds=60"
14667         lctl set_param -n osc.*.contention_seconds=60
14668
14669         $DIRECTIO write $DIR/$tfile 0 10 4096
14670         $CHECKSTAT -s 40960 $DIR/$tfile
14671
14672         # disable lockless i/o
14673         do_nodes $(comma_list $(osts_nodes)) \
14674                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14675                         ldlm.namespaces.filter-*.contended_locks=32 \
14676                         ldlm.namespaces.filter-*.contention_seconds=0"
14677         lctl set_param -n osc.*.contention_seconds=0
14678         clear_stats osc.*.osc_stats
14679
14680         dd if=/dev/zero of=$DIR/$tfile count=0
14681         $CHECKSTAT -s 0 $DIR/$tfile
14682
14683         restore_lustre_params <$p
14684         rm -f $p
14685         rm $DIR/$tfile
14686 }
14687 run_test 216 "check lockless direct write updates file size and kms correctly"
14688
14689 test_217() { # bug 22430
14690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14691
14692         local node
14693         local nid
14694
14695         for node in $(nodes_list); do
14696                 nid=$(host_nids_address $node $NETTYPE)
14697                 if [[ $nid = *-* ]] ; then
14698                         echo "lctl ping $(h2nettype $nid)"
14699                         lctl ping $(h2nettype $nid)
14700                 else
14701                         echo "skipping $node (no hyphen detected)"
14702                 fi
14703         done
14704 }
14705 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14706
14707 test_218() {
14708        # do directio so as not to populate the page cache
14709        log "creating a 10 Mb file"
14710        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14711        log "starting reads"
14712        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14713        log "truncating the file"
14714        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14715        log "killing dd"
14716        kill %+ || true # reads might have finished
14717        echo "wait until dd is finished"
14718        wait
14719        log "removing the temporary file"
14720        rm -rf $DIR/$tfile || error "tmp file removal failed"
14721 }
14722 run_test 218 "parallel read and truncate should not deadlock"
14723
14724 test_219() {
14725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14726
14727         # write one partial page
14728         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14729         # set no grant so vvp_io_commit_write will do sync write
14730         $LCTL set_param fail_loc=0x411
14731         # write a full page at the end of file
14732         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14733
14734         $LCTL set_param fail_loc=0
14735         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14736         $LCTL set_param fail_loc=0x411
14737         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14738
14739         # LU-4201
14740         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14741         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14742 }
14743 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14744
14745 test_220() { #LU-325
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747         remote_ost_nodsh && skip "remote OST with nodsh"
14748         remote_mds_nodsh && skip "remote MDS with nodsh"
14749         remote_mgs_nodsh && skip "remote MGS with nodsh"
14750
14751         local OSTIDX=0
14752
14753         # create on MDT0000 so the last_id and next_id are correct
14754         mkdir $DIR/$tdir
14755         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14756         OST=${OST%_UUID}
14757
14758         # on the mdt's osc
14759         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14760         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14761                         osc.$mdtosc_proc1.prealloc_last_id)
14762         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14763                         osc.$mdtosc_proc1.prealloc_next_id)
14764
14765         $LFS df -i
14766
14767         if ! combined_mgs_mds ; then
14768                 mount_mgs_client
14769         fi
14770
14771         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14772         #define OBD_FAIL_OST_ENOINO              0x229
14773         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14774         create_pool $FSNAME.$TESTNAME || return 1
14775         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14776
14777         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14778
14779         MDSOBJS=$((last_id - next_id))
14780         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14781
14782         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14783         echo "OST still has $count kbytes free"
14784
14785         echo "create $MDSOBJS files @next_id..."
14786         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14787
14788         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14789                         osc.$mdtosc_proc1.prealloc_last_id)
14790         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14791                         osc.$mdtosc_proc1.prealloc_next_id)
14792
14793         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14794         $LFS df -i
14795
14796         echo "cleanup..."
14797
14798         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14799         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14800
14801         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14802                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14803         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14804                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14805         echo "unlink $MDSOBJS files @$next_id..."
14806         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14807
14808         if ! combined_mgs_mds ; then
14809                 umount_mgs_client
14810         fi
14811 }
14812 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14813
14814 test_221() {
14815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14816
14817         dd if=`which date` of=$MOUNT/date oflag=sync
14818         chmod +x $MOUNT/date
14819
14820         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14821         $LCTL set_param fail_loc=0x80001401
14822
14823         $MOUNT/date > /dev/null
14824         rm -f $MOUNT/date
14825 }
14826 run_test 221 "make sure fault and truncate race to not cause OOM"
14827
14828 test_222a () {
14829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14830
14831         rm -rf $DIR/$tdir
14832         test_mkdir $DIR/$tdir
14833         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14834         createmany -o $DIR/$tdir/$tfile 10
14835         cancel_lru_locks mdc
14836         cancel_lru_locks osc
14837         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14838         $LCTL set_param fail_loc=0x31a
14839         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14840         $LCTL set_param fail_loc=0
14841         rm -r $DIR/$tdir
14842 }
14843 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14844
14845 test_222b () {
14846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14847
14848         rm -rf $DIR/$tdir
14849         test_mkdir $DIR/$tdir
14850         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14851         createmany -o $DIR/$tdir/$tfile 10
14852         cancel_lru_locks mdc
14853         cancel_lru_locks osc
14854         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14855         $LCTL set_param fail_loc=0x31a
14856         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14857         $LCTL set_param fail_loc=0
14858 }
14859 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14860
14861 test_223 () {
14862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14863
14864         rm -rf $DIR/$tdir
14865         test_mkdir $DIR/$tdir
14866         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14867         createmany -o $DIR/$tdir/$tfile 10
14868         cancel_lru_locks mdc
14869         cancel_lru_locks osc
14870         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14871         $LCTL set_param fail_loc=0x31b
14872         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14873         $LCTL set_param fail_loc=0
14874         rm -r $DIR/$tdir
14875 }
14876 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14877
14878 test_224a() { # LU-1039, MRP-303
14879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14880
14881         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14882         $LCTL set_param fail_loc=0x508
14883         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14884         $LCTL set_param fail_loc=0
14885         df $DIR
14886 }
14887 run_test 224a "Don't panic on bulk IO failure"
14888
14889 test_224b() { # LU-1039, MRP-303
14890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14891
14892         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14893         cancel_lru_locks osc
14894         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14895         $LCTL set_param fail_loc=0x515
14896         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14897         $LCTL set_param fail_loc=0
14898         df $DIR
14899 }
14900 run_test 224b "Don't panic on bulk IO failure"
14901
14902 test_224c() { # LU-6441
14903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14904         remote_mds_nodsh && skip "remote MDS with nodsh"
14905
14906         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14907         save_writethrough $p
14908         set_cache writethrough on
14909
14910         local pages_per_rpc=$($LCTL get_param \
14911                                 osc.*.max_pages_per_rpc)
14912         local at_max=$($LCTL get_param -n at_max)
14913         local timeout=$($LCTL get_param -n timeout)
14914         local test_at="at_max"
14915         local param_at="$FSNAME.sys.at_max"
14916         local test_timeout="timeout"
14917         local param_timeout="$FSNAME.sys.timeout"
14918
14919         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14920
14921         set_persistent_param_and_check client "$test_at" "$param_at" 0
14922         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14923
14924         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14925         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14926         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14927         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14928         sync
14929         do_facet ost1 "$LCTL set_param fail_loc=0"
14930
14931         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14932         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14933                 $timeout
14934
14935         $LCTL set_param -n $pages_per_rpc
14936         restore_lustre_params < $p
14937         rm -f $p
14938 }
14939 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14940
14941 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14942 test_225a () {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944         if [ -z ${MDSSURVEY} ]; then
14945                 skip_env "mds-survey not found"
14946         fi
14947         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14948                 skip "Need MDS version at least 2.2.51"
14949
14950         local mds=$(facet_host $SINGLEMDS)
14951         local target=$(do_nodes $mds 'lctl dl' |
14952                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14953
14954         local cmd1="file_count=1000 thrhi=4"
14955         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14956         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14957         local cmd="$cmd1 $cmd2 $cmd3"
14958
14959         rm -f ${TMP}/mds_survey*
14960         echo + $cmd
14961         eval $cmd || error "mds-survey with zero-stripe failed"
14962         cat ${TMP}/mds_survey*
14963         rm -f ${TMP}/mds_survey*
14964 }
14965 run_test 225a "Metadata survey sanity with zero-stripe"
14966
14967 test_225b () {
14968         if [ -z ${MDSSURVEY} ]; then
14969                 skip_env "mds-survey not found"
14970         fi
14971         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14972                 skip "Need MDS version at least 2.2.51"
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         remote_mds_nodsh && skip "remote MDS with nodsh"
14975         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14976                 skip_env "Need to mount OST to test"
14977         fi
14978
14979         local mds=$(facet_host $SINGLEMDS)
14980         local target=$(do_nodes $mds 'lctl dl' |
14981                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14982
14983         local cmd1="file_count=1000 thrhi=4"
14984         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14985         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14986         local cmd="$cmd1 $cmd2 $cmd3"
14987
14988         rm -f ${TMP}/mds_survey*
14989         echo + $cmd
14990         eval $cmd || error "mds-survey with stripe_count failed"
14991         cat ${TMP}/mds_survey*
14992         rm -f ${TMP}/mds_survey*
14993 }
14994 run_test 225b "Metadata survey sanity with stripe_count = 1"
14995
14996 mcreate_path2fid () {
14997         local mode=$1
14998         local major=$2
14999         local minor=$3
15000         local name=$4
15001         local desc=$5
15002         local path=$DIR/$tdir/$name
15003         local fid
15004         local rc
15005         local fid_path
15006
15007         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15008                 error "cannot create $desc"
15009
15010         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15011         rc=$?
15012         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15013
15014         fid_path=$($LFS fid2path $MOUNT $fid)
15015         rc=$?
15016         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15017
15018         [ "$path" == "$fid_path" ] ||
15019                 error "fid2path returned $fid_path, expected $path"
15020
15021         echo "pass with $path and $fid"
15022 }
15023
15024 test_226a () {
15025         rm -rf $DIR/$tdir
15026         mkdir -p $DIR/$tdir
15027
15028         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15029         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15030         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15031         mcreate_path2fid 0040666 0 0 dir "directory"
15032         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15033         mcreate_path2fid 0100666 0 0 file "regular file"
15034         mcreate_path2fid 0120666 0 0 link "symbolic link"
15035         mcreate_path2fid 0140666 0 0 sock "socket"
15036 }
15037 run_test 226a "call path2fid and fid2path on files of all type"
15038
15039 test_226b () {
15040         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15041
15042         local MDTIDX=1
15043
15044         rm -rf $DIR/$tdir
15045         mkdir -p $DIR/$tdir
15046         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15047                 error "create remote directory failed"
15048         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15049         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15050                                 "character special file (null)"
15051         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15052                                 "character special file (no device)"
15053         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15054         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15055                                 "block special file (loop)"
15056         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15057         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15058         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15059 }
15060 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15061
15062 # LU-1299 Executing or running ldd on a truncated executable does not
15063 # cause an out-of-memory condition.
15064 test_227() {
15065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15066         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15067
15068         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15069         chmod +x $MOUNT/date
15070
15071         $MOUNT/date > /dev/null
15072         ldd $MOUNT/date > /dev/null
15073         rm -f $MOUNT/date
15074 }
15075 run_test 227 "running truncated executable does not cause OOM"
15076
15077 # LU-1512 try to reuse idle OI blocks
15078 test_228a() {
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080         remote_mds_nodsh && skip "remote MDS with nodsh"
15081         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15082
15083         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15084         local myDIR=$DIR/$tdir
15085
15086         mkdir -p $myDIR
15087         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15088         $LCTL set_param fail_loc=0x80001002
15089         createmany -o $myDIR/t- 10000
15090         $LCTL set_param fail_loc=0
15091         # The guard is current the largest FID holder
15092         touch $myDIR/guard
15093         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15094                     tr -d '[')
15095         local IDX=$(($SEQ % 64))
15096
15097         do_facet $SINGLEMDS sync
15098         # Make sure journal flushed.
15099         sleep 6
15100         local blk1=$(do_facet $SINGLEMDS \
15101                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15102                      grep Blockcount | awk '{print $4}')
15103
15104         # Remove old files, some OI blocks will become idle.
15105         unlinkmany $myDIR/t- 10000
15106         # Create new files, idle OI blocks should be reused.
15107         createmany -o $myDIR/t- 2000
15108         do_facet $SINGLEMDS sync
15109         # Make sure journal flushed.
15110         sleep 6
15111         local blk2=$(do_facet $SINGLEMDS \
15112                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15113                      grep Blockcount | awk '{print $4}')
15114
15115         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15116 }
15117 run_test 228a "try to reuse idle OI blocks"
15118
15119 test_228b() {
15120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15121         remote_mds_nodsh && skip "remote MDS with nodsh"
15122         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15123
15124         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15125         local myDIR=$DIR/$tdir
15126
15127         mkdir -p $myDIR
15128         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15129         $LCTL set_param fail_loc=0x80001002
15130         createmany -o $myDIR/t- 10000
15131         $LCTL set_param fail_loc=0
15132         # The guard is current the largest FID holder
15133         touch $myDIR/guard
15134         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15135                     tr -d '[')
15136         local IDX=$(($SEQ % 64))
15137
15138         do_facet $SINGLEMDS sync
15139         # Make sure journal flushed.
15140         sleep 6
15141         local blk1=$(do_facet $SINGLEMDS \
15142                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15143                      grep Blockcount | awk '{print $4}')
15144
15145         # Remove old files, some OI blocks will become idle.
15146         unlinkmany $myDIR/t- 10000
15147
15148         # stop the MDT
15149         stop $SINGLEMDS || error "Fail to stop MDT."
15150         # remount the MDT
15151         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15152
15153         df $MOUNT || error "Fail to df."
15154         # Create new files, idle OI blocks should be reused.
15155         createmany -o $myDIR/t- 2000
15156         do_facet $SINGLEMDS sync
15157         # Make sure journal flushed.
15158         sleep 6
15159         local blk2=$(do_facet $SINGLEMDS \
15160                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15161                      grep Blockcount | awk '{print $4}')
15162
15163         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15164 }
15165 run_test 228b "idle OI blocks can be reused after MDT restart"
15166
15167 #LU-1881
15168 test_228c() {
15169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15170         remote_mds_nodsh && skip "remote MDS with nodsh"
15171         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15172
15173         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15174         local myDIR=$DIR/$tdir
15175
15176         mkdir -p $myDIR
15177         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15178         $LCTL set_param fail_loc=0x80001002
15179         # 20000 files can guarantee there are index nodes in the OI file
15180         createmany -o $myDIR/t- 20000
15181         $LCTL set_param fail_loc=0
15182         # The guard is current the largest FID holder
15183         touch $myDIR/guard
15184         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15185                     tr -d '[')
15186         local IDX=$(($SEQ % 64))
15187
15188         do_facet $SINGLEMDS sync
15189         # Make sure journal flushed.
15190         sleep 6
15191         local blk1=$(do_facet $SINGLEMDS \
15192                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15193                      grep Blockcount | awk '{print $4}')
15194
15195         # Remove old files, some OI blocks will become idle.
15196         unlinkmany $myDIR/t- 20000
15197         rm -f $myDIR/guard
15198         # The OI file should become empty now
15199
15200         # Create new files, idle OI blocks should be reused.
15201         createmany -o $myDIR/t- 2000
15202         do_facet $SINGLEMDS sync
15203         # Make sure journal flushed.
15204         sleep 6
15205         local blk2=$(do_facet $SINGLEMDS \
15206                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15207                      grep Blockcount | awk '{print $4}')
15208
15209         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15210 }
15211 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15212
15213 test_229() { # LU-2482, LU-3448
15214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15215         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15216         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15217                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15218
15219         rm -f $DIR/$tfile
15220
15221         # Create a file with a released layout and stripe count 2.
15222         $MULTIOP $DIR/$tfile H2c ||
15223                 error "failed to create file with released layout"
15224
15225         $LFS getstripe -v $DIR/$tfile
15226
15227         local pattern=$($LFS getstripe -L $DIR/$tfile)
15228         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15229
15230         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15231                 error "getstripe"
15232         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15233         stat $DIR/$tfile || error "failed to stat released file"
15234
15235         chown $RUNAS_ID $DIR/$tfile ||
15236                 error "chown $RUNAS_ID $DIR/$tfile failed"
15237
15238         chgrp $RUNAS_ID $DIR/$tfile ||
15239                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15240
15241         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15242         rm $DIR/$tfile || error "failed to remove released file"
15243 }
15244 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15245
15246 test_230a() {
15247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15249         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15250                 skip "Need MDS version at least 2.11.52"
15251
15252         local MDTIDX=1
15253
15254         test_mkdir $DIR/$tdir
15255         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15256         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15257         [ $mdt_idx -ne 0 ] &&
15258                 error "create local directory on wrong MDT $mdt_idx"
15259
15260         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15261                         error "create remote directory failed"
15262         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15263         [ $mdt_idx -ne $MDTIDX ] &&
15264                 error "create remote directory on wrong MDT $mdt_idx"
15265
15266         createmany -o $DIR/$tdir/test_230/t- 10 ||
15267                 error "create files on remote directory failed"
15268         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15269         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15270         rm -r $DIR/$tdir || error "unlink remote directory failed"
15271 }
15272 run_test 230a "Create remote directory and files under the remote directory"
15273
15274 test_230b() {
15275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15277         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15278                 skip "Need MDS version at least 2.11.52"
15279
15280         local MDTIDX=1
15281         local mdt_index
15282         local i
15283         local file
15284         local pid
15285         local stripe_count
15286         local migrate_dir=$DIR/$tdir/migrate_dir
15287         local other_dir=$DIR/$tdir/other_dir
15288
15289         test_mkdir $DIR/$tdir
15290         test_mkdir -i0 -c1 $migrate_dir
15291         test_mkdir -i0 -c1 $other_dir
15292         for ((i=0; i<10; i++)); do
15293                 mkdir -p $migrate_dir/dir_${i}
15294                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15295                         error "create files under remote dir failed $i"
15296         done
15297
15298         cp /etc/passwd $migrate_dir/$tfile
15299         cp /etc/passwd $other_dir/$tfile
15300         chattr +SAD $migrate_dir
15301         chattr +SAD $migrate_dir/$tfile
15302
15303         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15304         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15305         local old_dir_mode=$(stat -c%f $migrate_dir)
15306         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15307
15308         mkdir -p $migrate_dir/dir_default_stripe2
15309         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15310         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15311
15312         mkdir -p $other_dir
15313         ln $migrate_dir/$tfile $other_dir/luna
15314         ln $migrate_dir/$tfile $migrate_dir/sofia
15315         ln $other_dir/$tfile $migrate_dir/david
15316         ln -s $migrate_dir/$tfile $other_dir/zachary
15317         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15318         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15319
15320         $LFS migrate -m $MDTIDX $migrate_dir ||
15321                 error "fails on migrating remote dir to MDT1"
15322
15323         echo "migratate to MDT1, then checking.."
15324         for ((i = 0; i < 10; i++)); do
15325                 for file in $(find $migrate_dir/dir_${i}); do
15326                         mdt_index=$($LFS getstripe -m $file)
15327                         [ $mdt_index == $MDTIDX ] ||
15328                                 error "$file is not on MDT${MDTIDX}"
15329                 done
15330         done
15331
15332         # the multiple link file should still in MDT0
15333         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15334         [ $mdt_index == 0 ] ||
15335                 error "$file is not on MDT${MDTIDX}"
15336
15337         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15338         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15339                 error " expect $old_dir_flag get $new_dir_flag"
15340
15341         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15342         [ "$old_file_flag" = "$new_file_flag" ] ||
15343                 error " expect $old_file_flag get $new_file_flag"
15344
15345         local new_dir_mode=$(stat -c%f $migrate_dir)
15346         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15347                 error "expect mode $old_dir_mode get $new_dir_mode"
15348
15349         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15350         [ "$old_file_mode" = "$new_file_mode" ] ||
15351                 error "expect mode $old_file_mode get $new_file_mode"
15352
15353         diff /etc/passwd $migrate_dir/$tfile ||
15354                 error "$tfile different after migration"
15355
15356         diff /etc/passwd $other_dir/luna ||
15357                 error "luna different after migration"
15358
15359         diff /etc/passwd $migrate_dir/sofia ||
15360                 error "sofia different after migration"
15361
15362         diff /etc/passwd $migrate_dir/david ||
15363                 error "david different after migration"
15364
15365         diff /etc/passwd $other_dir/zachary ||
15366                 error "zachary different after migration"
15367
15368         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15369                 error "${tfile}_ln different after migration"
15370
15371         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15372                 error "${tfile}_ln_other different after migration"
15373
15374         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15375         [ $stripe_count = 2 ] ||
15376                 error "dir strpe_count $d != 2 after migration."
15377
15378         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15379         [ $stripe_count = 2 ] ||
15380                 error "file strpe_count $d != 2 after migration."
15381
15382         #migrate back to MDT0
15383         MDTIDX=0
15384
15385         $LFS migrate -m $MDTIDX $migrate_dir ||
15386                 error "fails on migrating remote dir to MDT0"
15387
15388         echo "migrate back to MDT0, checking.."
15389         for file in $(find $migrate_dir); do
15390                 mdt_index=$($LFS getstripe -m $file)
15391                 [ $mdt_index == $MDTIDX ] ||
15392                         error "$file is not on MDT${MDTIDX}"
15393         done
15394
15395         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15396         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15397                 error " expect $old_dir_flag get $new_dir_flag"
15398
15399         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15400         [ "$old_file_flag" = "$new_file_flag" ] ||
15401                 error " expect $old_file_flag get $new_file_flag"
15402
15403         local new_dir_mode=$(stat -c%f $migrate_dir)
15404         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15405                 error "expect mode $old_dir_mode get $new_dir_mode"
15406
15407         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15408         [ "$old_file_mode" = "$new_file_mode" ] ||
15409                 error "expect mode $old_file_mode get $new_file_mode"
15410
15411         diff /etc/passwd ${migrate_dir}/$tfile ||
15412                 error "$tfile different after migration"
15413
15414         diff /etc/passwd ${other_dir}/luna ||
15415                 error "luna different after migration"
15416
15417         diff /etc/passwd ${migrate_dir}/sofia ||
15418                 error "sofia different after migration"
15419
15420         diff /etc/passwd ${other_dir}/zachary ||
15421                 error "zachary different after migration"
15422
15423         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15424                 error "${tfile}_ln different after migration"
15425
15426         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15427                 error "${tfile}_ln_other different after migration"
15428
15429         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15430         [ $stripe_count = 2 ] ||
15431                 error "dir strpe_count $d != 2 after migration."
15432
15433         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15434         [ $stripe_count = 2 ] ||
15435                 error "file strpe_count $d != 2 after migration."
15436
15437         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15438 }
15439 run_test 230b "migrate directory"
15440
15441 test_230c() {
15442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15444         remote_mds_nodsh && skip "remote MDS with nodsh"
15445         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15446                 skip "Need MDS version at least 2.11.52"
15447
15448         local MDTIDX=1
15449         local total=3
15450         local mdt_index
15451         local file
15452         local migrate_dir=$DIR/$tdir/migrate_dir
15453
15454         #If migrating directory fails in the middle, all entries of
15455         #the directory is still accessiable.
15456         test_mkdir $DIR/$tdir
15457         test_mkdir -i0 -c1 $migrate_dir
15458         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15459         stat $migrate_dir
15460         createmany -o $migrate_dir/f $total ||
15461                 error "create files under ${migrate_dir} failed"
15462
15463         # fail after migrating top dir, and this will fail only once, so the
15464         # first sub file migration will fail (currently f3), others succeed.
15465         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15466         do_facet mds1 lctl set_param fail_loc=0x1801
15467         local t=$(ls $migrate_dir | wc -l)
15468         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15469                 error "migrate should fail"
15470         local u=$(ls $migrate_dir | wc -l)
15471         [ "$u" == "$t" ] || error "$u != $t during migration"
15472
15473         # add new dir/file should succeed
15474         mkdir $migrate_dir/dir ||
15475                 error "mkdir failed under migrating directory"
15476         touch $migrate_dir/file ||
15477                 error "create file failed under migrating directory"
15478
15479         # add file with existing name should fail
15480         for file in $migrate_dir/f*; do
15481                 stat $file > /dev/null || error "stat $file failed"
15482                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15483                         error "open(O_CREAT|O_EXCL) $file should fail"
15484                 $MULTIOP $file m && error "create $file should fail"
15485                 touch $DIR/$tdir/remote_dir/$tfile ||
15486                         error "touch $tfile failed"
15487                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15488                         error "link $file should fail"
15489                 mdt_index=$($LFS getstripe -m $file)
15490                 if [ $mdt_index == 0 ]; then
15491                         # file failed to migrate is not allowed to rename to
15492                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15493                                 error "rename to $file should fail"
15494                 else
15495                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15496                                 error "rename to $file failed"
15497                 fi
15498                 echo hello >> $file || error "write $file failed"
15499         done
15500
15501         # resume migration with different options should fail
15502         $LFS migrate -m 0 $migrate_dir &&
15503                 error "migrate -m 0 $migrate_dir should fail"
15504
15505         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15506                 error "migrate -c 2 $migrate_dir should fail"
15507
15508         # resume migration should succeed
15509         $LFS migrate -m $MDTIDX $migrate_dir ||
15510                 error "migrate $migrate_dir failed"
15511
15512         echo "Finish migration, then checking.."
15513         for file in $(find $migrate_dir); do
15514                 mdt_index=$($LFS getstripe -m $file)
15515                 [ $mdt_index == $MDTIDX ] ||
15516                         error "$file is not on MDT${MDTIDX}"
15517         done
15518
15519         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15520 }
15521 run_test 230c "check directory accessiblity if migration failed"
15522
15523 test_230d() {
15524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15526         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15527                 skip "Need MDS version at least 2.11.52"
15528         # LU-11235
15529         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15530
15531         local migrate_dir=$DIR/$tdir/migrate_dir
15532         local old_index
15533         local new_index
15534         local old_count
15535         local new_count
15536         local new_hash
15537         local mdt_index
15538         local i
15539         local j
15540
15541         old_index=$((RANDOM % MDSCOUNT))
15542         old_count=$((MDSCOUNT - old_index))
15543         new_index=$((RANDOM % MDSCOUNT))
15544         new_count=$((MDSCOUNT - new_index))
15545         new_hash="all_char"
15546
15547         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15548         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15549
15550         test_mkdir $DIR/$tdir
15551         test_mkdir -i $old_index -c $old_count $migrate_dir
15552
15553         for ((i=0; i<100; i++)); do
15554                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15555                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15556                         error "create files under remote dir failed $i"
15557         done
15558
15559         echo -n "Migrate from MDT$old_index "
15560         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15561         echo -n "to MDT$new_index"
15562         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15563         echo
15564
15565         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15566         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15567                 error "migrate remote dir error"
15568
15569         echo "Finish migration, then checking.."
15570         for file in $(find $migrate_dir); do
15571                 mdt_index=$($LFS getstripe -m $file)
15572                 if [ $mdt_index -lt $new_index ] ||
15573                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15574                         error "$file is on MDT$mdt_index"
15575                 fi
15576         done
15577
15578         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15579 }
15580 run_test 230d "check migrate big directory"
15581
15582 test_230e() {
15583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15585         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15586                 skip "Need MDS version at least 2.11.52"
15587
15588         local i
15589         local j
15590         local a_fid
15591         local b_fid
15592
15593         mkdir -p $DIR/$tdir
15594         mkdir $DIR/$tdir/migrate_dir
15595         mkdir $DIR/$tdir/other_dir
15596         touch $DIR/$tdir/migrate_dir/a
15597         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15598         ls $DIR/$tdir/other_dir
15599
15600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15601                 error "migrate dir fails"
15602
15603         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15604         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15605
15606         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15607         [ $mdt_index == 0 ] || error "a is not on MDT0"
15608
15609         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15610                 error "migrate dir fails"
15611
15612         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15613         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15614
15615         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15616         [ $mdt_index == 1 ] || error "a is not on MDT1"
15617
15618         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15619         [ $mdt_index == 1 ] || error "b is not on MDT1"
15620
15621         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15622         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15623
15624         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15625
15626         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15627 }
15628 run_test 230e "migrate mulitple local link files"
15629
15630 test_230f() {
15631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15632         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15633         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15634                 skip "Need MDS version at least 2.11.52"
15635
15636         local a_fid
15637         local ln_fid
15638
15639         mkdir -p $DIR/$tdir
15640         mkdir $DIR/$tdir/migrate_dir
15641         $LFS mkdir -i1 $DIR/$tdir/other_dir
15642         touch $DIR/$tdir/migrate_dir/a
15643         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15644         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15645         ls $DIR/$tdir/other_dir
15646
15647         # a should be migrated to MDT1, since no other links on MDT0
15648         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15649                 error "#1 migrate dir fails"
15650         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15651         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15652         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15653         [ $mdt_index == 1 ] || error "a is not on MDT1"
15654
15655         # a should stay on MDT1, because it is a mulitple link file
15656         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15657                 error "#2 migrate dir fails"
15658         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15659         [ $mdt_index == 1 ] || error "a is not on MDT1"
15660
15661         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15662                 error "#3 migrate dir fails"
15663
15664         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15665         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15666         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15667
15668         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15669         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15670
15671         # a should be migrated to MDT0, since no other links on MDT1
15672         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15673                 error "#4 migrate dir fails"
15674         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15675         [ $mdt_index == 0 ] || error "a is not on MDT0"
15676
15677         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15678 }
15679 run_test 230f "migrate mulitple remote link files"
15680
15681 test_230g() {
15682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15684         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15685                 skip "Need MDS version at least 2.11.52"
15686
15687         mkdir -p $DIR/$tdir/migrate_dir
15688
15689         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15690                 error "migrating dir to non-exist MDT succeeds"
15691         true
15692 }
15693 run_test 230g "migrate dir to non-exist MDT"
15694
15695 test_230h() {
15696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15698         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15699                 skip "Need MDS version at least 2.11.52"
15700
15701         local mdt_index
15702
15703         mkdir -p $DIR/$tdir/migrate_dir
15704
15705         $LFS migrate -m1 $DIR &&
15706                 error "migrating mountpoint1 should fail"
15707
15708         $LFS migrate -m1 $DIR/$tdir/.. &&
15709                 error "migrating mountpoint2 should fail"
15710
15711         # same as mv
15712         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15713                 error "migrating $tdir/migrate_dir/.. should fail"
15714
15715         true
15716 }
15717 run_test 230h "migrate .. and root"
15718
15719 test_230i() {
15720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15721         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15722         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15723                 skip "Need MDS version at least 2.11.52"
15724
15725         mkdir -p $DIR/$tdir/migrate_dir
15726
15727         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15728                 error "migration fails with a tailing slash"
15729
15730         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15731                 error "migration fails with two tailing slashes"
15732 }
15733 run_test 230i "lfs migrate -m tolerates trailing slashes"
15734
15735 test_230j() {
15736         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15737         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15738                 skip "Need MDS version at least 2.11.52"
15739
15740         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15741         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15742                 error "create $tfile failed"
15743         cat /etc/passwd > $DIR/$tdir/$tfile
15744
15745         $LFS migrate -m 1 $DIR/$tdir
15746
15747         cmp /etc/passwd $DIR/$tdir/$tfile ||
15748                 error "DoM file mismatch after migration"
15749 }
15750 run_test 230j "DoM file data not changed after dir migration"
15751
15752 test_230k() {
15753         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15754         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15755                 skip "Need MDS version at least 2.11.56"
15756
15757         local total=20
15758         local files_on_starting_mdt=0
15759
15760         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15761         $LFS getdirstripe $DIR/$tdir
15762         for i in $(seq $total); do
15763                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15764                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15765                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15766         done
15767
15768         echo "$files_on_starting_mdt files on MDT0"
15769
15770         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15771         $LFS getdirstripe $DIR/$tdir
15772
15773         files_on_starting_mdt=0
15774         for i in $(seq $total); do
15775                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15776                         error "file $tfile.$i mismatch after migration"
15777                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15778                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15779         done
15780
15781         echo "$files_on_starting_mdt files on MDT1 after migration"
15782         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15783
15784         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15785         $LFS getdirstripe $DIR/$tdir
15786
15787         files_on_starting_mdt=0
15788         for i in $(seq $total); do
15789                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15790                         error "file $tfile.$i mismatch after 2nd migration"
15791                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15792                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15793         done
15794
15795         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15796         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15797
15798         true
15799 }
15800 run_test 230k "file data not changed after dir migration"
15801
15802 test_230l() {
15803         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15804         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15805                 skip "Need MDS version at least 2.11.56"
15806
15807         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15808         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15809                 error "create files under remote dir failed $i"
15810         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15811 }
15812 run_test 230l "readdir between MDTs won't crash"
15813
15814 test_231a()
15815 {
15816         # For simplicity this test assumes that max_pages_per_rpc
15817         # is the same across all OSCs
15818         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15819         local bulk_size=$((max_pages * PAGE_SIZE))
15820         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15821                                        head -n 1)
15822
15823         mkdir -p $DIR/$tdir
15824         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15825                 error "failed to set stripe with -S ${brw_size}M option"
15826
15827         # clear the OSC stats
15828         $LCTL set_param osc.*.stats=0 &>/dev/null
15829         stop_writeback
15830
15831         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15832         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15833                 oflag=direct &>/dev/null || error "dd failed"
15834
15835         sync; sleep 1; sync # just to be safe
15836         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15837         if [ x$nrpcs != "x1" ]; then
15838                 $LCTL get_param osc.*.stats
15839                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15840         fi
15841
15842         start_writeback
15843         # Drop the OSC cache, otherwise we will read from it
15844         cancel_lru_locks osc
15845
15846         # clear the OSC stats
15847         $LCTL set_param osc.*.stats=0 &>/dev/null
15848
15849         # Client reads $bulk_size.
15850         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15851                 iflag=direct &>/dev/null || error "dd failed"
15852
15853         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15854         if [ x$nrpcs != "x1" ]; then
15855                 $LCTL get_param osc.*.stats
15856                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15857         fi
15858 }
15859 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15860
15861 test_231b() {
15862         mkdir -p $DIR/$tdir
15863         local i
15864         for i in {0..1023}; do
15865                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15866                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15867                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15868         done
15869         sync
15870 }
15871 run_test 231b "must not assert on fully utilized OST request buffer"
15872
15873 test_232a() {
15874         mkdir -p $DIR/$tdir
15875         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15876
15877         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15878         do_facet ost1 $LCTL set_param fail_loc=0x31c
15879
15880         # ignore dd failure
15881         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15882
15883         do_facet ost1 $LCTL set_param fail_loc=0
15884         umount_client $MOUNT || error "umount failed"
15885         mount_client $MOUNT || error "mount failed"
15886         stop ost1 || error "cannot stop ost1"
15887         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15888 }
15889 run_test 232a "failed lock should not block umount"
15890
15891 test_232b() {
15892         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15893                 skip "Need MDS version at least 2.10.58"
15894
15895         mkdir -p $DIR/$tdir
15896         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15897         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15898         sync
15899         cancel_lru_locks osc
15900
15901         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15902         do_facet ost1 $LCTL set_param fail_loc=0x31c
15903
15904         # ignore failure
15905         $LFS data_version $DIR/$tdir/$tfile || true
15906
15907         do_facet ost1 $LCTL set_param fail_loc=0
15908         umount_client $MOUNT || error "umount failed"
15909         mount_client $MOUNT || error "mount failed"
15910         stop ost1 || error "cannot stop ost1"
15911         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15912 }
15913 run_test 232b "failed data version lock should not block umount"
15914
15915 test_233a() {
15916         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15917                 skip "Need MDS version at least 2.3.64"
15918         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15919
15920         local fid=$($LFS path2fid $MOUNT)
15921
15922         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15923                 error "cannot access $MOUNT using its FID '$fid'"
15924 }
15925 run_test 233a "checking that OBF of the FS root succeeds"
15926
15927 test_233b() {
15928         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15929                 skip "Need MDS version at least 2.5.90"
15930         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15931
15932         local fid=$($LFS path2fid $MOUNT/.lustre)
15933
15934         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15935                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15936
15937         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15938         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15939                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15940 }
15941 run_test 233b "checking that OBF of the FS .lustre succeeds"
15942
15943 test_234() {
15944         local p="$TMP/sanityN-$TESTNAME.parameters"
15945         save_lustre_params client "llite.*.xattr_cache" > $p
15946         lctl set_param llite.*.xattr_cache 1 ||
15947                 skip_env "xattr cache is not supported"
15948
15949         mkdir -p $DIR/$tdir || error "mkdir failed"
15950         touch $DIR/$tdir/$tfile || error "touch failed"
15951         # OBD_FAIL_LLITE_XATTR_ENOMEM
15952         $LCTL set_param fail_loc=0x1405
15953         getfattr -n user.attr $DIR/$tdir/$tfile &&
15954                 error "getfattr should have failed with ENOMEM"
15955         $LCTL set_param fail_loc=0x0
15956         rm -rf $DIR/$tdir
15957
15958         restore_lustre_params < $p
15959         rm -f $p
15960 }
15961 run_test 234 "xattr cache should not crash on ENOMEM"
15962
15963 test_235() {
15964         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15965                 skip "Need MDS version at least 2.4.52"
15966
15967         flock_deadlock $DIR/$tfile
15968         local RC=$?
15969         case $RC in
15970                 0)
15971                 ;;
15972                 124) error "process hangs on a deadlock"
15973                 ;;
15974                 *) error "error executing flock_deadlock $DIR/$tfile"
15975                 ;;
15976         esac
15977 }
15978 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15979
15980 #LU-2935
15981 test_236() {
15982         check_swap_layouts_support
15983
15984         local ref1=/etc/passwd
15985         local ref2=/etc/group
15986         local file1=$DIR/$tdir/f1
15987         local file2=$DIR/$tdir/f2
15988
15989         test_mkdir -c1 $DIR/$tdir
15990         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15991         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15992         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15993         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15994         local fd=$(free_fd)
15995         local cmd="exec $fd<>$file2"
15996         eval $cmd
15997         rm $file2
15998         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15999                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16000         cmd="exec $fd>&-"
16001         eval $cmd
16002         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16003
16004         #cleanup
16005         rm -rf $DIR/$tdir
16006 }
16007 run_test 236 "Layout swap on open unlinked file"
16008
16009 # LU-4659 linkea consistency
16010 test_238() {
16011         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16012                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16013                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16014                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16015
16016         touch $DIR/$tfile
16017         ln $DIR/$tfile $DIR/$tfile.lnk
16018         touch $DIR/$tfile.new
16019         mv $DIR/$tfile.new $DIR/$tfile
16020         local fid1=$($LFS path2fid $DIR/$tfile)
16021         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16022         local path1=$($LFS fid2path $FSNAME "$fid1")
16023         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16024         local path2=$($LFS fid2path $FSNAME "$fid2")
16025         [ $tfile.lnk == $path2 ] ||
16026                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16027         rm -f $DIR/$tfile*
16028 }
16029 run_test 238 "Verify linkea consistency"
16030
16031 test_239A() { # was test_239
16032         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16033                 skip "Need MDS version at least 2.5.60"
16034
16035         local list=$(comma_list $(mdts_nodes))
16036
16037         mkdir -p $DIR/$tdir
16038         createmany -o $DIR/$tdir/f- 5000
16039         unlinkmany $DIR/$tdir/f- 5000
16040         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16041                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16042         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16043                         osp.*MDT*.sync_in_flight" | calc_sum)
16044         [ "$changes" -eq 0 ] || error "$changes not synced"
16045 }
16046 run_test 239A "osp_sync test"
16047
16048 test_239a() { #LU-5297
16049         remote_mds_nodsh && skip "remote MDS with nodsh"
16050
16051         touch $DIR/$tfile
16052         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16053         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16054         chgrp $RUNAS_GID $DIR/$tfile
16055         wait_delete_completed
16056 }
16057 run_test 239a "process invalid osp sync record correctly"
16058
16059 test_239b() { #LU-5297
16060         remote_mds_nodsh && skip "remote MDS with nodsh"
16061
16062         touch $DIR/$tfile1
16063         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16064         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16065         chgrp $RUNAS_GID $DIR/$tfile1
16066         wait_delete_completed
16067         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16068         touch $DIR/$tfile2
16069         chgrp $RUNAS_GID $DIR/$tfile2
16070         wait_delete_completed
16071 }
16072 run_test 239b "process osp sync record with ENOMEM error correctly"
16073
16074 test_240() {
16075         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16076         remote_mds_nodsh && skip "remote MDS with nodsh"
16077
16078         mkdir -p $DIR/$tdir
16079
16080         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16081                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16082         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16083                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16084
16085         umount_client $MOUNT || error "umount failed"
16086         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16087         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16088         mount_client $MOUNT || error "failed to mount client"
16089
16090         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16091         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16092 }
16093 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16094
16095 test_241_bio() {
16096         local count=$1
16097         local bsize=$2
16098
16099         for LOOP in $(seq $count); do
16100                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16101                 cancel_lru_locks $OSC || true
16102         done
16103 }
16104
16105 test_241_dio() {
16106         local count=$1
16107         local bsize=$2
16108
16109         for LOOP in $(seq $1); do
16110                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16111                         2>/dev/null
16112         done
16113 }
16114
16115 test_241a() { # was test_241
16116         local bsize=$PAGE_SIZE
16117
16118         (( bsize < 40960 )) && bsize=40960
16119         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16120         ls -la $DIR/$tfile
16121         cancel_lru_locks $OSC
16122         test_241_bio 1000 $bsize &
16123         PID=$!
16124         test_241_dio 1000 $bsize
16125         wait $PID
16126 }
16127 run_test 241a "bio vs dio"
16128
16129 test_241b() {
16130         local bsize=$PAGE_SIZE
16131
16132         (( bsize < 40960 )) && bsize=40960
16133         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16134         ls -la $DIR/$tfile
16135         test_241_dio 1000 $bsize &
16136         PID=$!
16137         test_241_dio 1000 $bsize
16138         wait $PID
16139 }
16140 run_test 241b "dio vs dio"
16141
16142 test_242() {
16143         remote_mds_nodsh && skip "remote MDS with nodsh"
16144
16145         mkdir -p $DIR/$tdir
16146         touch $DIR/$tdir/$tfile
16147
16148         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16149         do_facet mds1 lctl set_param fail_loc=0x105
16150         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16151
16152         do_facet mds1 lctl set_param fail_loc=0
16153         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16154 }
16155 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16156
16157 test_243()
16158 {
16159         test_mkdir $DIR/$tdir
16160         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16161 }
16162 run_test 243 "various group lock tests"
16163
16164 test_244()
16165 {
16166         test_mkdir $DIR/$tdir
16167         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16168         sendfile_grouplock $DIR/$tdir/$tfile || \
16169                 error "sendfile+grouplock failed"
16170         rm -rf $DIR/$tdir
16171 }
16172 run_test 244 "sendfile with group lock tests"
16173
16174 test_245() {
16175         local flagname="multi_mod_rpcs"
16176         local connect_data_name="max_mod_rpcs"
16177         local out
16178
16179         # check if multiple modify RPCs flag is set
16180         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16181                 grep "connect_flags:")
16182         echo "$out"
16183
16184         echo "$out" | grep -qw $flagname
16185         if [ $? -ne 0 ]; then
16186                 echo "connect flag $flagname is not set"
16187                 return
16188         fi
16189
16190         # check if multiple modify RPCs data is set
16191         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16192         echo "$out"
16193
16194         echo "$out" | grep -qw $connect_data_name ||
16195                 error "import should have connect data $connect_data_name"
16196 }
16197 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16198
16199 test_246() { # LU-7371
16200         remote_ost_nodsh && skip "remote OST with nodsh"
16201         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16202                 skip "Need OST version >= 2.7.62"
16203
16204         do_facet ost1 $LCTL set_param fail_val=4095
16205 #define OBD_FAIL_OST_READ_SIZE          0x234
16206         do_facet ost1 $LCTL set_param fail_loc=0x234
16207         $LFS setstripe $DIR/$tfile -i 0 -c 1
16208         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16209         cancel_lru_locks $FSNAME-OST0000
16210         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16211 }
16212 run_test 246 "Read file of size 4095 should return right length"
16213
16214 cleanup_247() {
16215         local submount=$1
16216
16217         trap 0
16218         umount_client $submount
16219         rmdir $submount
16220 }
16221
16222 test_247a() {
16223         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16224                 grep -q subtree ||
16225                 skip_env "Fileset feature is not supported"
16226
16227         local submount=${MOUNT}_$tdir
16228
16229         mkdir $MOUNT/$tdir
16230         mkdir -p $submount || error "mkdir $submount failed"
16231         FILESET="$FILESET/$tdir" mount_client $submount ||
16232                 error "mount $submount failed"
16233         trap "cleanup_247 $submount" EXIT
16234         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16235         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16236                 error "read $MOUNT/$tdir/$tfile failed"
16237         cleanup_247 $submount
16238 }
16239 run_test 247a "mount subdir as fileset"
16240
16241 test_247b() {
16242         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16243                 skip_env "Fileset feature is not supported"
16244
16245         local submount=${MOUNT}_$tdir
16246
16247         rm -rf $MOUNT/$tdir
16248         mkdir -p $submount || error "mkdir $submount failed"
16249         SKIP_FILESET=1
16250         FILESET="$FILESET/$tdir" mount_client $submount &&
16251                 error "mount $submount should fail"
16252         rmdir $submount
16253 }
16254 run_test 247b "mount subdir that dose not exist"
16255
16256 test_247c() {
16257         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16258                 skip_env "Fileset feature is not supported"
16259
16260         local submount=${MOUNT}_$tdir
16261
16262         mkdir -p $MOUNT/$tdir/dir1
16263         mkdir -p $submount || error "mkdir $submount failed"
16264         trap "cleanup_247 $submount" EXIT
16265         FILESET="$FILESET/$tdir" mount_client $submount ||
16266                 error "mount $submount failed"
16267         local fid=$($LFS path2fid $MOUNT/)
16268         $LFS fid2path $submount $fid && error "fid2path should fail"
16269         cleanup_247 $submount
16270 }
16271 run_test 247c "running fid2path outside root"
16272
16273 test_247d() {
16274         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16275                 skip "Fileset feature is not supported"
16276
16277         local submount=${MOUNT}_$tdir
16278
16279         mkdir -p $MOUNT/$tdir/dir1
16280         mkdir -p $submount || error "mkdir $submount failed"
16281         FILESET="$FILESET/$tdir" mount_client $submount ||
16282                 error "mount $submount failed"
16283         trap "cleanup_247 $submount" EXIT
16284         local fid=$($LFS path2fid $submount/dir1)
16285         $LFS fid2path $submount $fid || error "fid2path should succeed"
16286         cleanup_247 $submount
16287 }
16288 run_test 247d "running fid2path inside root"
16289
16290 # LU-8037
16291 test_247e() {
16292         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16293                 grep -q subtree ||
16294                 skip "Fileset feature is not supported"
16295
16296         local submount=${MOUNT}_$tdir
16297
16298         mkdir $MOUNT/$tdir
16299         mkdir -p $submount || error "mkdir $submount failed"
16300         FILESET="$FILESET/.." mount_client $submount &&
16301                 error "mount $submount should fail"
16302         rmdir $submount
16303 }
16304 run_test 247e "mount .. as fileset"
16305
16306 test_248() {
16307         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16308         [ -z "$fast_read_sav" ] && skip "no fast read support"
16309
16310         # create a large file for fast read verification
16311         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16312
16313         # make sure the file is created correctly
16314         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16315                 { rm -f $DIR/$tfile; skip "file creation error"; }
16316
16317         echo "Test 1: verify that fast read is 4 times faster on cache read"
16318
16319         # small read with fast read enabled
16320         $LCTL set_param -n llite.*.fast_read=1
16321         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16322                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16323                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16324         # small read with fast read disabled
16325         $LCTL set_param -n llite.*.fast_read=0
16326         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16327                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16328                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16329
16330         # verify that fast read is 4 times faster for cache read
16331         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16332                 error_not_in_vm "fast read was not 4 times faster: " \
16333                            "$t_fast vs $t_slow"
16334
16335         echo "Test 2: verify the performance between big and small read"
16336         $LCTL set_param -n llite.*.fast_read=1
16337
16338         # 1k non-cache read
16339         cancel_lru_locks osc
16340         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16341                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16342                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16343
16344         # 1M non-cache read
16345         cancel_lru_locks osc
16346         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16347                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16348                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16349
16350         # verify that big IO is not 4 times faster than small IO
16351         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16352                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16353
16354         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16355         rm -f $DIR/$tfile
16356 }
16357 run_test 248 "fast read verification"
16358
16359 test_249() { # LU-7890
16360         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16361                 skip "Need at least version 2.8.54"
16362
16363         rm -f $DIR/$tfile
16364         $LFS setstripe -c 1 $DIR/$tfile
16365         # Offset 2T == 4k * 512M
16366         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16367                 error "dd to 2T offset failed"
16368 }
16369 run_test 249 "Write above 2T file size"
16370
16371 test_250() {
16372         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16373          && skip "no 16TB file size limit on ZFS"
16374
16375         $LFS setstripe -c 1 $DIR/$tfile
16376         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16377         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16378         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16379         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16380                 conv=notrunc,fsync && error "append succeeded"
16381         return 0
16382 }
16383 run_test 250 "Write above 16T limit"
16384
16385 test_251() {
16386         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16387
16388         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16389         #Skip once - writing the first stripe will succeed
16390         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16391         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16392                 error "short write happened"
16393
16394         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16395         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16396                 error "short read happened"
16397
16398         rm -f $DIR/$tfile
16399 }
16400 run_test 251 "Handling short read and write correctly"
16401
16402 test_252() {
16403         remote_mds_nodsh && skip "remote MDS with nodsh"
16404         remote_ost_nodsh && skip "remote OST with nodsh"
16405         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16406                 skip_env "ldiskfs only test"
16407         fi
16408
16409         local tgt
16410         local dev
16411         local out
16412         local uuid
16413         local num
16414         local gen
16415
16416         # check lr_reader on OST0000
16417         tgt=ost1
16418         dev=$(facet_device $tgt)
16419         out=$(do_facet $tgt $LR_READER $dev)
16420         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16421         echo "$out"
16422         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16423         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16424                 error "Invalid uuid returned by $LR_READER on target $tgt"
16425         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16426
16427         # check lr_reader -c on MDT0000
16428         tgt=mds1
16429         dev=$(facet_device $tgt)
16430         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16431                 skip "$LR_READER does not support additional options"
16432         fi
16433         out=$(do_facet $tgt $LR_READER -c $dev)
16434         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16435         echo "$out"
16436         num=$(echo "$out" | grep -c "mdtlov")
16437         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16438                 error "Invalid number of mdtlov clients returned by $LR_READER"
16439         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16440
16441         # check lr_reader -cr on MDT0000
16442         out=$(do_facet $tgt $LR_READER -cr $dev)
16443         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16444         echo "$out"
16445         echo "$out" | grep -q "^reply_data:$" ||
16446                 error "$LR_READER should have returned 'reply_data' section"
16447         num=$(echo "$out" | grep -c "client_generation")
16448         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16449 }
16450 run_test 252 "check lr_reader tool"
16451
16452 test_253_fill_ost() {
16453         local size_mb #how many MB should we write to pass watermark
16454         local lwm=$3  #low watermark
16455         local free_10mb #10% of free space
16456
16457         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16458         size_mb=$((free_kb / 1024 - lwm))
16459         free_10mb=$((free_kb / 10240))
16460         #If 10% of free space cross low watermark use it
16461         if (( free_10mb > size_mb )); then
16462                 size_mb=$free_10mb
16463         else
16464                 #At least we need to store 1.1 of difference between
16465                 #free space and low watermark
16466                 size_mb=$((size_mb + size_mb / 10))
16467         fi
16468         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16469                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16470                          oflag=append conv=notrunc
16471         fi
16472
16473         sleep_maxage
16474
16475         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16476         echo "OST still has $((free_kb / 1024)) mbytes free"
16477 }
16478
16479 test_253() {
16480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16481         remote_mds_nodsh && skip "remote MDS with nodsh"
16482         remote_mgs_nodsh && skip "remote MGS with nodsh"
16483
16484         local ostidx=0
16485         local rc=0
16486
16487         local ost_name=$($LFS osts |
16488                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16489         # on the mdt's osc
16490         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16491         do_facet $SINGLEMDS $LCTL get_param -n \
16492                 osp.$mdtosc_proc1.reserved_mb_high ||
16493                 skip  "remote MDS does not support reserved_mb_high"
16494
16495         rm -rf $DIR/$tdir
16496         wait_mds_ost_sync
16497         wait_delete_completed
16498         mkdir $DIR/$tdir
16499
16500         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16501                         osp.$mdtosc_proc1.reserved_mb_high)
16502         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16503                         osp.$mdtosc_proc1.reserved_mb_low)
16504         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16505
16506         if ! combined_mgs_mds ; then
16507                 mount_mgs_client
16508         fi
16509         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16510         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16511                 error "Adding $ost_name to pool failed"
16512
16513         # Wait for client to see a OST at pool
16514         wait_update $HOSTNAME "$LCTL get_param -n
16515                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16516                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16517                 error "Client can not see the pool"
16518         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16519                 error "Setstripe failed"
16520
16521         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16522         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16523         echo "OST still has $((blocks/1024)) mbytes free"
16524
16525         local new_lwm=$((blocks/1024-10))
16526         do_facet $SINGLEMDS $LCTL set_param \
16527                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16528         do_facet $SINGLEMDS $LCTL set_param \
16529                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16530
16531         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16532
16533         #First enospc could execute orphan deletion so repeat.
16534         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16535
16536         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16537                         osp.$mdtosc_proc1.prealloc_status)
16538         echo "prealloc_status $oa_status"
16539
16540         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16541                 error "File creation should fail"
16542         #object allocation was stopped, but we still able to append files
16543         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16544                 error "Append failed"
16545         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16546
16547         wait_delete_completed
16548
16549         sleep_maxage
16550
16551         for i in $(seq 10 12); do
16552                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16553                         error "File creation failed after rm";
16554         done
16555
16556         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16557                         osp.$mdtosc_proc1.prealloc_status)
16558         echo "prealloc_status $oa_status"
16559
16560         if (( oa_status != 0 )); then
16561                 error "Object allocation still disable after rm"
16562         fi
16563         do_facet $SINGLEMDS $LCTL set_param \
16564                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16565         do_facet $SINGLEMDS $LCTL set_param \
16566                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16567
16568
16569         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16570                 error "Remove $ost_name from pool failed"
16571         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16572                 error "Pool destroy fialed"
16573
16574         if ! combined_mgs_mds ; then
16575                 umount_mgs_client
16576         fi
16577 }
16578 run_test 253 "Check object allocation limit"
16579
16580 test_254() {
16581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16582         remote_mds_nodsh && skip "remote MDS with nodsh"
16583         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16584                 skip "MDS does not support changelog_size"
16585
16586         local cl_user
16587         local MDT0=$(facet_svc $SINGLEMDS)
16588
16589         changelog_register || error "changelog_register failed"
16590
16591         changelog_clear 0 || error "changelog_clear failed"
16592
16593         local size1=$(do_facet $SINGLEMDS \
16594                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16595         echo "Changelog size $size1"
16596
16597         rm -rf $DIR/$tdir
16598         $LFS mkdir -i 0 $DIR/$tdir
16599         # change something
16600         mkdir -p $DIR/$tdir/pics/2008/zachy
16601         touch $DIR/$tdir/pics/2008/zachy/timestamp
16602         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16603         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16604         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16605         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16606         rm $DIR/$tdir/pics/desktop.jpg
16607
16608         local size2=$(do_facet $SINGLEMDS \
16609                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16610         echo "Changelog size after work $size2"
16611
16612         (( $size2 > $size1 )) ||
16613                 error "new Changelog size=$size2 less than old size=$size1"
16614 }
16615 run_test 254 "Check changelog size"
16616
16617 ladvise_no_type()
16618 {
16619         local type=$1
16620         local file=$2
16621
16622         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16623                 awk -F: '{print $2}' | grep $type > /dev/null
16624         if [ $? -ne 0 ]; then
16625                 return 0
16626         fi
16627         return 1
16628 }
16629
16630 ladvise_no_ioctl()
16631 {
16632         local file=$1
16633
16634         lfs ladvise -a willread $file > /dev/null 2>&1
16635         if [ $? -eq 0 ]; then
16636                 return 1
16637         fi
16638
16639         lfs ladvise -a willread $file 2>&1 |
16640                 grep "Inappropriate ioctl for device" > /dev/null
16641         if [ $? -eq 0 ]; then
16642                 return 0
16643         fi
16644         return 1
16645 }
16646
16647 percent() {
16648         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16649 }
16650
16651 # run a random read IO workload
16652 # usage: random_read_iops <filename> <filesize> <iosize>
16653 random_read_iops() {
16654         local file=$1
16655         local fsize=$2
16656         local iosize=${3:-4096}
16657
16658         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16659                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16660 }
16661
16662 drop_file_oss_cache() {
16663         local file="$1"
16664         local nodes="$2"
16665
16666         $LFS ladvise -a dontneed $file 2>/dev/null ||
16667                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16668 }
16669
16670 ladvise_willread_performance()
16671 {
16672         local repeat=10
16673         local average_origin=0
16674         local average_cache=0
16675         local average_ladvise=0
16676
16677         for ((i = 1; i <= $repeat; i++)); do
16678                 echo "Iter $i/$repeat: reading without willread hint"
16679                 cancel_lru_locks osc
16680                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16681                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16682                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16683                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16684
16685                 cancel_lru_locks osc
16686                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16687                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16688                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16689
16690                 cancel_lru_locks osc
16691                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16692                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16693                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16694                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16695                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16696         done
16697         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16698         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16699         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16700
16701         speedup_cache=$(percent $average_cache $average_origin)
16702         speedup_ladvise=$(percent $average_ladvise $average_origin)
16703
16704         echo "Average uncached read: $average_origin"
16705         echo "Average speedup with OSS cached read: " \
16706                 "$average_cache = +$speedup_cache%"
16707         echo "Average speedup with ladvise willread: " \
16708                 "$average_ladvise = +$speedup_ladvise%"
16709
16710         local lowest_speedup=20
16711         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16712                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16713                         "got $average_cache%. Skipping ladvise willread check."
16714                 return 0
16715         fi
16716
16717         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16718         # it is still good to run until then to exercise 'ladvise willread'
16719         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16720                 [ "$ost1_FSTYPE" = "zfs" ] &&
16721                 echo "osd-zfs does not support dontneed or drop_caches" &&
16722                 return 0
16723
16724         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16725         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16726                 error_not_in_vm "Speedup with willread is less than " \
16727                         "$lowest_speedup%, got $average_ladvise%"
16728 }
16729
16730 test_255a() {
16731         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16732                 skip "lustre < 2.8.54 does not support ladvise "
16733         remote_ost_nodsh && skip "remote OST with nodsh"
16734
16735         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16736
16737         ladvise_no_type willread $DIR/$tfile &&
16738                 skip "willread ladvise is not supported"
16739
16740         ladvise_no_ioctl $DIR/$tfile &&
16741                 skip "ladvise ioctl is not supported"
16742
16743         local size_mb=100
16744         local size=$((size_mb * 1048576))
16745         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16746                 error "dd to $DIR/$tfile failed"
16747
16748         lfs ladvise -a willread $DIR/$tfile ||
16749                 error "Ladvise failed with no range argument"
16750
16751         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16752                 error "Ladvise failed with no -l or -e argument"
16753
16754         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16755                 error "Ladvise failed with only -e argument"
16756
16757         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16758                 error "Ladvise failed with only -l argument"
16759
16760         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16761                 error "End offset should not be smaller than start offset"
16762
16763         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16764                 error "End offset should not be equal to start offset"
16765
16766         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16767                 error "Ladvise failed with overflowing -s argument"
16768
16769         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16770                 error "Ladvise failed with overflowing -e argument"
16771
16772         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16773                 error "Ladvise failed with overflowing -l argument"
16774
16775         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16776                 error "Ladvise succeeded with conflicting -l and -e arguments"
16777
16778         echo "Synchronous ladvise should wait"
16779         local delay=4
16780 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16781         do_nodes $(comma_list $(osts_nodes)) \
16782                 $LCTL set_param fail_val=$delay fail_loc=0x237
16783
16784         local start_ts=$SECONDS
16785         lfs ladvise -a willread $DIR/$tfile ||
16786                 error "Ladvise failed with no range argument"
16787         local end_ts=$SECONDS
16788         local inteval_ts=$((end_ts - start_ts))
16789
16790         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16791                 error "Synchronous advice didn't wait reply"
16792         fi
16793
16794         echo "Asynchronous ladvise shouldn't wait"
16795         local start_ts=$SECONDS
16796         lfs ladvise -a willread -b $DIR/$tfile ||
16797                 error "Ladvise failed with no range argument"
16798         local end_ts=$SECONDS
16799         local inteval_ts=$((end_ts - start_ts))
16800
16801         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16802                 error "Asynchronous advice blocked"
16803         fi
16804
16805         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16806         ladvise_willread_performance
16807 }
16808 run_test 255a "check 'lfs ladvise -a willread'"
16809
16810 facet_meminfo() {
16811         local facet=$1
16812         local info=$2
16813
16814         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16815 }
16816
16817 test_255b() {
16818         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16819                 skip "lustre < 2.8.54 does not support ladvise "
16820         remote_ost_nodsh && skip "remote OST with nodsh"
16821
16822         lfs setstripe -c 1 -i 0 $DIR/$tfile
16823
16824         ladvise_no_type dontneed $DIR/$tfile &&
16825                 skip "dontneed ladvise is not supported"
16826
16827         ladvise_no_ioctl $DIR/$tfile &&
16828                 skip "ladvise ioctl is not supported"
16829
16830         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16831                 [ "$ost1_FSTYPE" = "zfs" ] &&
16832                 skip "zfs-osd does not support 'ladvise dontneed'"
16833
16834         local size_mb=100
16835         local size=$((size_mb * 1048576))
16836         # In order to prevent disturbance of other processes, only check 3/4
16837         # of the memory usage
16838         local kibibytes=$((size_mb * 1024 * 3 / 4))
16839
16840         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16841                 error "dd to $DIR/$tfile failed"
16842
16843         #force write to complete before dropping OST cache & checking memory
16844         sync
16845
16846         local total=$(facet_meminfo ost1 MemTotal)
16847         echo "Total memory: $total KiB"
16848
16849         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16850         local before_read=$(facet_meminfo ost1 Cached)
16851         echo "Cache used before read: $before_read KiB"
16852
16853         lfs ladvise -a willread $DIR/$tfile ||
16854                 error "Ladvise willread failed"
16855         local after_read=$(facet_meminfo ost1 Cached)
16856         echo "Cache used after read: $after_read KiB"
16857
16858         lfs ladvise -a dontneed $DIR/$tfile ||
16859                 error "Ladvise dontneed again failed"
16860         local no_read=$(facet_meminfo ost1 Cached)
16861         echo "Cache used after dontneed ladvise: $no_read KiB"
16862
16863         if [ $total -lt $((before_read + kibibytes)) ]; then
16864                 echo "Memory is too small, abort checking"
16865                 return 0
16866         fi
16867
16868         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16869                 error "Ladvise willread should use more memory" \
16870                         "than $kibibytes KiB"
16871         fi
16872
16873         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16874                 error "Ladvise dontneed should release more memory" \
16875                         "than $kibibytes KiB"
16876         fi
16877 }
16878 run_test 255b "check 'lfs ladvise -a dontneed'"
16879
16880 test_255c() {
16881         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16882                 skip "lustre < 2.10.53 does not support lockahead"
16883
16884         local count
16885         local new_count
16886         local difference
16887         local i
16888         local rc
16889
16890         test_mkdir -p $DIR/$tdir
16891         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16892
16893         #test 10 returns only success/failure
16894         i=10
16895         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16896         rc=$?
16897         if [ $rc -eq 255 ]; then
16898                 error "Ladvise test${i} failed, ${rc}"
16899         fi
16900
16901         #test 11 counts lock enqueue requests, all others count new locks
16902         i=11
16903         count=$(do_facet ost1 \
16904                 $LCTL get_param -n ost.OSS.ost.stats)
16905         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16906
16907         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16908         rc=$?
16909         if [ $rc -eq 255 ]; then
16910                 error "Ladvise test${i} failed, ${rc}"
16911         fi
16912
16913         new_count=$(do_facet ost1 \
16914                 $LCTL get_param -n ost.OSS.ost.stats)
16915         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16916                    awk '{ print $2 }')
16917
16918         difference="$((new_count - count))"
16919         if [ $difference -ne $rc ]; then
16920                 error "Ladvise test${i}, bad enqueue count, returned " \
16921                       "${rc}, actual ${difference}"
16922         fi
16923
16924         for i in $(seq 12 21); do
16925                 # If we do not do this, we run the risk of having too many
16926                 # locks and starting lock cancellation while we are checking
16927                 # lock counts.
16928                 cancel_lru_locks osc
16929
16930                 count=$($LCTL get_param -n \
16931                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16932
16933                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16934                 rc=$?
16935                 if [ $rc -eq 255 ]; then
16936                         error "Ladvise test ${i} failed, ${rc}"
16937                 fi
16938
16939                 new_count=$($LCTL get_param -n \
16940                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16941                 difference="$((new_count - count))"
16942
16943                 # Test 15 output is divided by 100 to map down to valid return
16944                 if [ $i -eq 15 ]; then
16945                         rc="$((rc * 100))"
16946                 fi
16947
16948                 if [ $difference -ne $rc ]; then
16949                         error "Ladvise test ${i}, bad lock count, returned " \
16950                               "${rc}, actual ${difference}"
16951                 fi
16952         done
16953
16954         #test 22 returns only success/failure
16955         i=22
16956         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16957         rc=$?
16958         if [ $rc -eq 255 ]; then
16959                 error "Ladvise test${i} failed, ${rc}"
16960         fi
16961 }
16962 run_test 255c "suite of ladvise lockahead tests"
16963
16964 test_256() {
16965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16966         remote_mds_nodsh && skip "remote MDS with nodsh"
16967         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16968         changelog_users $SINGLEMDS | grep "^cl" &&
16969                 skip "active changelog user"
16970
16971         local cl_user
16972         local cat_sl
16973         local mdt_dev
16974
16975         mdt_dev=$(mdsdevname 1)
16976         echo $mdt_dev
16977
16978         changelog_register || error "changelog_register failed"
16979
16980         rm -rf $DIR/$tdir
16981         mkdir -p $DIR/$tdir
16982
16983         changelog_clear 0 || error "changelog_clear failed"
16984
16985         # change something
16986         touch $DIR/$tdir/{1..10}
16987
16988         # stop the MDT
16989         stop $SINGLEMDS || error "Fail to stop MDT"
16990
16991         # remount the MDT
16992
16993         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16994
16995         #after mount new plainllog is used
16996         touch $DIR/$tdir/{11..19}
16997         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16998         cat_sl=$(do_facet $SINGLEMDS "sync; \
16999                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17000                  llog_reader $tmpfile | grep -c type=1064553b")
17001         do_facet $SINGLEMDS llog_reader $tmpfile
17002
17003         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17004
17005         changelog_clear 0 || error "changelog_clear failed"
17006
17007         cat_sl=$(do_facet $SINGLEMDS "sync; \
17008                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17009                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17010
17011         if (( cat_sl == 2 )); then
17012                 error "Empty plain llog was not deleted from changelog catalog"
17013         elif (( cat_sl != 1 )); then
17014                 error "Active plain llog shouldn't be deleted from catalog"
17015         fi
17016 }
17017 run_test 256 "Check llog delete for empty and not full state"
17018
17019 test_257() {
17020         remote_mds_nodsh && skip "remote MDS with nodsh"
17021         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17022                 skip "Need MDS version at least 2.8.55"
17023
17024         test_mkdir $DIR/$tdir
17025
17026         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17027                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17028         stat $DIR/$tdir
17029
17030 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17031         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17032         local facet=mds$((mdtidx + 1))
17033         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17034         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17035
17036         stop $facet || error "stop MDS failed"
17037         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17038                 error "start MDS fail"
17039         wait_recovery_complete $facet
17040 }
17041 run_test 257 "xattr locks are not lost"
17042
17043 # Verify we take the i_mutex when security requires it
17044 test_258a() {
17045 #define OBD_FAIL_IMUTEX_SEC 0x141c
17046         $LCTL set_param fail_loc=0x141c
17047         touch $DIR/$tfile
17048         chmod u+s $DIR/$tfile
17049         chmod a+rwx $DIR/$tfile
17050         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17051         RC=$?
17052         if [ $RC -ne 0 ]; then
17053                 error "error, failed to take i_mutex, rc=$?"
17054         fi
17055         rm -f $DIR/$tfile
17056 }
17057 run_test 258a
17058
17059 # Verify we do NOT take the i_mutex in the normal case
17060 test_258b() {
17061 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17062         $LCTL set_param fail_loc=0x141d
17063         touch $DIR/$tfile
17064         chmod a+rwx $DIR
17065         chmod a+rw $DIR/$tfile
17066         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17067         RC=$?
17068         if [ $RC -ne 0 ]; then
17069                 error "error, took i_mutex unnecessarily, rc=$?"
17070         fi
17071         rm -f $DIR/$tfile
17072
17073 }
17074 run_test 258b "verify i_mutex security behavior"
17075
17076 test_259() {
17077         local file=$DIR/$tfile
17078         local before
17079         local after
17080
17081         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17082
17083         stack_trap "rm -f $file" EXIT
17084
17085         wait_delete_completed
17086         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17087         echo "before: $before"
17088
17089         $LFS setstripe -i 0 -c 1 $file
17090         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17091         sync_all_data
17092         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17093         echo "after write: $after"
17094
17095 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17096         do_facet ost1 $LCTL set_param fail_loc=0x2301
17097         $TRUNCATE $file 0
17098         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17099         echo "after truncate: $after"
17100
17101         stop ost1
17102         do_facet ost1 $LCTL set_param fail_loc=0
17103         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17104         sleep 2
17105         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17106         echo "after restart: $after"
17107         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17108                 error "missing truncate?"
17109
17110         return 0
17111 }
17112 run_test 259 "crash at delayed truncate"
17113
17114 test_260() {
17115 #define OBD_FAIL_MDC_CLOSE               0x806
17116         $LCTL set_param fail_loc=0x80000806
17117         touch $DIR/$tfile
17118
17119 }
17120 run_test 260 "Check mdc_close fail"
17121
17122 ### Data-on-MDT sanity tests ###
17123 test_270a() {
17124         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17125                 skip "Need MDS version at least 2.10.55 for DoM"
17126
17127         # create DoM file
17128         local dom=$DIR/$tdir/dom_file
17129         local tmp=$DIR/$tdir/tmp_file
17130
17131         mkdir -p $DIR/$tdir
17132
17133         # basic checks for DoM component creation
17134         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17135                 error "Can set MDT layout to non-first entry"
17136
17137         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17138                 error "Can define multiple entries as MDT layout"
17139
17140         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17141
17142         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17143         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17144         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17145
17146         local mdtidx=$($LFS getstripe -m $dom)
17147         local mdtname=MDT$(printf %04x $mdtidx)
17148         local facet=mds$((mdtidx + 1))
17149         local space_check=1
17150
17151         # Skip free space checks with ZFS
17152         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17153
17154         # write
17155         sync
17156         local size_tmp=$((65536 * 3))
17157         local mdtfree1=$(do_facet $facet \
17158                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17159
17160         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17161         # check also direct IO along write
17162         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17163         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17164         sync
17165         cmp $tmp $dom || error "file data is different"
17166         [ $(stat -c%s $dom) == $size_tmp ] ||
17167                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17168         if [ $space_check == 1 ]; then
17169                 local mdtfree2=$(do_facet $facet \
17170                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17171
17172                 # increase in usage from by $size_tmp
17173                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17174                         error "MDT free space wrong after write: " \
17175                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17176         fi
17177
17178         # truncate
17179         local size_dom=10000
17180
17181         $TRUNCATE $dom $size_dom
17182         [ $(stat -c%s $dom) == $size_dom ] ||
17183                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17184         if [ $space_check == 1 ]; then
17185                 mdtfree1=$(do_facet $facet \
17186                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17187                 # decrease in usage from $size_tmp to new $size_dom
17188                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17189                   $(((size_tmp - size_dom) / 1024)) ] ||
17190                         error "MDT free space is wrong after truncate: " \
17191                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17192         fi
17193
17194         # append
17195         cat $tmp >> $dom
17196         sync
17197         size_dom=$((size_dom + size_tmp))
17198         [ $(stat -c%s $dom) == $size_dom ] ||
17199                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17200         if [ $space_check == 1 ]; then
17201                 mdtfree2=$(do_facet $facet \
17202                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17203                 # increase in usage by $size_tmp from previous
17204                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17205                         error "MDT free space is wrong after append: " \
17206                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17207         fi
17208
17209         # delete
17210         rm $dom
17211         if [ $space_check == 1 ]; then
17212                 mdtfree1=$(do_facet $facet \
17213                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17214                 # decrease in usage by $size_dom from previous
17215                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17216                         error "MDT free space is wrong after removal: " \
17217                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17218         fi
17219
17220         # combined striping
17221         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17222                 error "Can't create DoM + OST striping"
17223
17224         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17225         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17226         # check also direct IO along write
17227         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17228         sync
17229         cmp $tmp $dom || error "file data is different"
17230         [ $(stat -c%s $dom) == $size_tmp ] ||
17231                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17232         rm $dom $tmp
17233
17234         return 0
17235 }
17236 run_test 270a "DoM: basic functionality tests"
17237
17238 test_270b() {
17239         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17240                 skip "Need MDS version at least 2.10.55"
17241
17242         local dom=$DIR/$tdir/dom_file
17243         local max_size=1048576
17244
17245         mkdir -p $DIR/$tdir
17246         $LFS setstripe -E $max_size -L mdt $dom
17247
17248         # truncate over the limit
17249         $TRUNCATE $dom $(($max_size + 1)) &&
17250                 error "successful truncate over the maximum size"
17251         # write over the limit
17252         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17253                 error "successful write over the maximum size"
17254         # append over the limit
17255         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17256         echo "12345" >> $dom && error "successful append over the maximum size"
17257         rm $dom
17258
17259         return 0
17260 }
17261 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17262
17263 test_270c() {
17264         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17265                 skip "Need MDS version at least 2.10.55"
17266
17267         mkdir -p $DIR/$tdir
17268         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17269
17270         # check files inherit DoM EA
17271         touch $DIR/$tdir/first
17272         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17273                 error "bad pattern"
17274         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17275                 error "bad stripe count"
17276         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17277                 error "bad stripe size"
17278
17279         # check directory inherits DoM EA and uses it as default
17280         mkdir $DIR/$tdir/subdir
17281         touch $DIR/$tdir/subdir/second
17282         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17283                 error "bad pattern in sub-directory"
17284         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17285                 error "bad stripe count in sub-directory"
17286         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17287                 error "bad stripe size in sub-directory"
17288         return 0
17289 }
17290 run_test 270c "DoM: DoM EA inheritance tests"
17291
17292 test_270d() {
17293         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17294                 skip "Need MDS version at least 2.10.55"
17295
17296         mkdir -p $DIR/$tdir
17297         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17298
17299         # inherit default DoM striping
17300         mkdir $DIR/$tdir/subdir
17301         touch $DIR/$tdir/subdir/f1
17302
17303         # change default directory striping
17304         $LFS setstripe -c 1 $DIR/$tdir/subdir
17305         touch $DIR/$tdir/subdir/f2
17306         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17307                 error "wrong default striping in file 2"
17308         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17309                 error "bad pattern in file 2"
17310         return 0
17311 }
17312 run_test 270d "DoM: change striping from DoM to RAID0"
17313
17314 test_270e() {
17315         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17316                 skip "Need MDS version at least 2.10.55"
17317
17318         mkdir -p $DIR/$tdir/dom
17319         mkdir -p $DIR/$tdir/norm
17320         DOMFILES=20
17321         NORMFILES=10
17322         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17323         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17324
17325         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17326         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17327
17328         # find DoM files by layout
17329         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17330         [ $NUM -eq  $DOMFILES ] ||
17331                 error "lfs find -L: found $NUM, expected $DOMFILES"
17332         echo "Test 1: lfs find 20 DOM files by layout: OK"
17333
17334         # there should be 1 dir with default DOM striping
17335         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17336         [ $NUM -eq  1 ] ||
17337                 error "lfs find -L: found $NUM, expected 1 dir"
17338         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17339
17340         # find DoM files by stripe size
17341         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17342         [ $NUM -eq  $DOMFILES ] ||
17343                 error "lfs find -S: found $NUM, expected $DOMFILES"
17344         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17345
17346         # find files by stripe offset except DoM files
17347         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17348         [ $NUM -eq  $NORMFILES ] ||
17349                 error "lfs find -i: found $NUM, expected $NORMFILES"
17350         echo "Test 5: lfs find no DOM files by stripe index: OK"
17351         return 0
17352 }
17353 run_test 270e "DoM: lfs find with DoM files test"
17354
17355 test_270f() {
17356         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17357                 skip "Need MDS version at least 2.10.55"
17358
17359         local mdtname=${FSNAME}-MDT0000-mdtlov
17360         local dom=$DIR/$tdir/dom_file
17361         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17362                                                 lod.$mdtname.dom_stripesize)
17363         local dom_limit=131072
17364
17365         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17366         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17367                                                 lod.$mdtname.dom_stripesize)
17368         [ ${dom_limit} -eq ${dom_current} ] ||
17369                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17370
17371         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17372         $LFS setstripe -d $DIR/$tdir
17373         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17374                 error "Can't set directory default striping"
17375
17376         # exceed maximum stripe size
17377         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17378                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17379         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17380                 error "Able to create DoM component size more than LOD limit"
17381
17382         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17383         dom_current=$(do_facet mds1 $LCTL get_param -n \
17384                                                 lod.$mdtname.dom_stripesize)
17385         [ 0 -eq ${dom_current} ] ||
17386                 error "Can't set zero DoM stripe limit"
17387         rm $dom
17388
17389         # attempt to create DoM file on server with disabled DoM should
17390         # remove DoM entry from layout and be succeed
17391         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17392                 error "Can't create DoM file (DoM is disabled)"
17393         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17394                 error "File has DoM component while DoM is disabled"
17395         rm $dom
17396
17397         # attempt to create DoM file with only DoM stripe should return error
17398         $LFS setstripe -E $dom_limit -L mdt $dom &&
17399                 error "Able to create DoM-only file while DoM is disabled"
17400
17401         # too low values to be aligned with smallest stripe size 64K
17402         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17403         dom_current=$(do_facet mds1 $LCTL get_param -n \
17404                                                 lod.$mdtname.dom_stripesize)
17405         [ 30000 -eq ${dom_current} ] &&
17406                 error "Can set too small DoM stripe limit"
17407
17408         # 64K is a minimal stripe size in Lustre, expect limit of that size
17409         [ 65536 -eq ${dom_current} ] ||
17410                 error "Limit is not set to 64K but ${dom_current}"
17411
17412         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17413         dom_current=$(do_facet mds1 $LCTL get_param -n \
17414                                                 lod.$mdtname.dom_stripesize)
17415         echo $dom_current
17416         [ 2147483648 -eq ${dom_current} ] &&
17417                 error "Can set too large DoM stripe limit"
17418
17419         do_facet mds1 $LCTL set_param -n \
17420                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17421         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17422                 error "Can't create DoM component size after limit change"
17423         do_facet mds1 $LCTL set_param -n \
17424                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17425         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17426                 error "Can't create DoM file after limit decrease"
17427         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17428                 error "Can create big DoM component after limit decrease"
17429         touch ${dom}_def ||
17430                 error "Can't create file with old default layout"
17431
17432         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17433         return 0
17434 }
17435 run_test 270f "DoM: maximum DoM stripe size checks"
17436
17437 test_271a() {
17438         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17439                 skip "Need MDS version at least 2.10.55"
17440
17441         local dom=$DIR/$tdir/dom
17442
17443         mkdir -p $DIR/$tdir
17444
17445         $LFS setstripe -E 1024K -L mdt $dom
17446
17447         lctl set_param -n mdc.*.stats=clear
17448         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17449         cat $dom > /dev/null
17450         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17451         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17452         ls $dom
17453         rm -f $dom
17454 }
17455 run_test 271a "DoM: data is cached for read after write"
17456
17457 test_271b() {
17458         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17459                 skip "Need MDS version at least 2.10.55"
17460
17461         local dom=$DIR/$tdir/dom
17462
17463         mkdir -p $DIR/$tdir
17464
17465         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17466
17467         lctl set_param -n mdc.*.stats=clear
17468         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17469         cancel_lru_locks mdc
17470         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17471         # second stat to check size is cached on client
17472         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17473         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17474         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17475         rm -f $dom
17476 }
17477 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17478
17479 test_271ba() {
17480         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17481                 skip "Need MDS version at least 2.10.55"
17482
17483         local dom=$DIR/$tdir/dom
17484
17485         mkdir -p $DIR/$tdir
17486
17487         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17488
17489         lctl set_param -n mdc.*.stats=clear
17490         lctl set_param -n osc.*.stats=clear
17491         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17492         cancel_lru_locks mdc
17493         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17494         # second stat to check size is cached on client
17495         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17496         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17497         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17498         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17499         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17500         rm -f $dom
17501 }
17502 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17503
17504
17505 get_mdc_stats() {
17506         local mdtidx=$1
17507         local param=$2
17508         local mdt=MDT$(printf %04x $mdtidx)
17509
17510         if [ -z $param ]; then
17511                 lctl get_param -n mdc.*$mdt*.stats
17512         else
17513                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17514         fi
17515 }
17516
17517 test_271c() {
17518         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17519                 skip "Need MDS version at least 2.10.55"
17520
17521         local dom=$DIR/$tdir/dom
17522
17523         mkdir -p $DIR/$tdir
17524
17525         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17526
17527         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17528         local facet=mds$((mdtidx + 1))
17529
17530         cancel_lru_locks mdc
17531         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17532         createmany -o $dom 1000
17533         lctl set_param -n mdc.*.stats=clear
17534         smalliomany -w $dom 1000 200
17535         get_mdc_stats $mdtidx
17536         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17537         # Each file has 1 open, 1 IO enqueues, total 2000
17538         # but now we have also +1 getxattr for security.capability, total 3000
17539         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17540         unlinkmany $dom 1000
17541
17542         cancel_lru_locks mdc
17543         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17544         createmany -o $dom 1000
17545         lctl set_param -n mdc.*.stats=clear
17546         smalliomany -w $dom 1000 200
17547         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17548         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17549         # for OPEN and IO lock.
17550         [ $((enq - enq_2)) -ge 1000 ] ||
17551                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17552         unlinkmany $dom 1000
17553         return 0
17554 }
17555 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17556
17557 cleanup_271def_tests() {
17558         trap 0
17559         rm -f $1
17560 }
17561
17562 test_271d() {
17563         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17564                 skip "Need MDS version at least 2.10.57"
17565
17566         local dom=$DIR/$tdir/dom
17567         local tmp=$TMP/$tfile
17568         trap "cleanup_271def_tests $tmp" EXIT
17569
17570         mkdir -p $DIR/$tdir
17571
17572         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17573
17574         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17575
17576         cancel_lru_locks mdc
17577         dd if=/dev/urandom of=$tmp bs=1000 count=1
17578         dd if=$tmp of=$dom bs=1000 count=1
17579         cancel_lru_locks mdc
17580
17581         cat /etc/hosts >> $tmp
17582         lctl set_param -n mdc.*.stats=clear
17583
17584         # append data to the same file it should update local page
17585         echo "Append to the same page"
17586         cat /etc/hosts >> $dom
17587         local num=$(get_mdc_stats $mdtidx ost_read)
17588         local ra=$(get_mdc_stats $mdtidx req_active)
17589         local rw=$(get_mdc_stats $mdtidx req_waittime)
17590
17591         [ -z $num ] || error "$num READ RPC occured"
17592         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17593         echo "... DONE"
17594
17595         # compare content
17596         cmp $tmp $dom || error "file miscompare"
17597
17598         cancel_lru_locks mdc
17599         lctl set_param -n mdc.*.stats=clear
17600
17601         echo "Open and read file"
17602         cat $dom > /dev/null
17603         local num=$(get_mdc_stats $mdtidx ost_read)
17604         local ra=$(get_mdc_stats $mdtidx req_active)
17605         local rw=$(get_mdc_stats $mdtidx req_waittime)
17606
17607         [ -z $num ] || error "$num READ RPC occured"
17608         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17609         echo "... DONE"
17610
17611         # compare content
17612         cmp $tmp $dom || error "file miscompare"
17613
17614         return 0
17615 }
17616 run_test 271d "DoM: read on open (1K file in reply buffer)"
17617
17618 test_271f() {
17619         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17620                 skip "Need MDS version at least 2.10.57"
17621
17622         local dom=$DIR/$tdir/dom
17623         local tmp=$TMP/$tfile
17624         trap "cleanup_271def_tests $tmp" EXIT
17625
17626         mkdir -p $DIR/$tdir
17627
17628         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17629
17630         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17631
17632         cancel_lru_locks mdc
17633         dd if=/dev/urandom of=$tmp bs=200000 count=1
17634         dd if=$tmp of=$dom bs=200000 count=1
17635         cancel_lru_locks mdc
17636         cat /etc/hosts >> $tmp
17637         lctl set_param -n mdc.*.stats=clear
17638
17639         echo "Append to the same page"
17640         cat /etc/hosts >> $dom
17641         local num=$(get_mdc_stats $mdtidx ost_read)
17642         local ra=$(get_mdc_stats $mdtidx req_active)
17643         local rw=$(get_mdc_stats $mdtidx req_waittime)
17644
17645         [ -z $num ] || error "$num READ RPC occured"
17646         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17647         echo "... DONE"
17648
17649         # compare content
17650         cmp $tmp $dom || error "file miscompare"
17651
17652         cancel_lru_locks mdc
17653         lctl set_param -n mdc.*.stats=clear
17654
17655         echo "Open and read file"
17656         cat $dom > /dev/null
17657         local num=$(get_mdc_stats $mdtidx ost_read)
17658         local ra=$(get_mdc_stats $mdtidx req_active)
17659         local rw=$(get_mdc_stats $mdtidx req_waittime)
17660
17661         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17662         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17663         echo "... DONE"
17664
17665         # compare content
17666         cmp $tmp $dom || error "file miscompare"
17667
17668         return 0
17669 }
17670 run_test 271f "DoM: read on open (200K file and read tail)"
17671
17672 test_272a() {
17673         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17674                 skip "Need MDS version at least 2.11.50"
17675
17676         local dom=$DIR/$tdir/dom
17677         mkdir -p $DIR/$tdir
17678
17679         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17680         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17681                 error "failed to write data into $dom"
17682         local old_md5=$(md5sum $dom)
17683
17684         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17685                 error "failed to migrate to the same DoM component"
17686
17687         local new_md5=$(md5sum $dom)
17688
17689         [ "$old_md5" == "$new_md5" ] ||
17690                 error "md5sum differ: $old_md5, $new_md5"
17691
17692         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17693                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17694 }
17695 run_test 272a "DoM migration: new layout with the same DOM component"
17696
17697 test_272b() {
17698         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17699                 skip "Need MDS version at least 2.11.50"
17700
17701         local dom=$DIR/$tdir/dom
17702         mkdir -p $DIR/$tdir
17703         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17704
17705         local mdtidx=$($LFS getstripe -m $dom)
17706         local mdtname=MDT$(printf %04x $mdtidx)
17707         local facet=mds$((mdtidx + 1))
17708
17709         local mdtfree1=$(do_facet $facet \
17710                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17711         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17712                 error "failed to write data into $dom"
17713         local old_md5=$(md5sum $dom)
17714         cancel_lru_locks mdc
17715         local mdtfree1=$(do_facet $facet \
17716                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17717
17718         $LFS migrate -c2 $dom ||
17719                 error "failed to migrate to the new composite layout"
17720         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17721                 error "MDT stripe was not removed"
17722
17723         cancel_lru_locks mdc
17724         local new_md5=$(md5sum $dom)
17725         [ "$old_md5" != "$new_md5" ] &&
17726                 error "$old_md5 != $new_md5"
17727
17728         # Skip free space checks with ZFS
17729         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17730                 local mdtfree2=$(do_facet $facet \
17731                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17732                 [ $mdtfree2 -gt $mdtfree1 ] ||
17733                         error "MDT space is not freed after migration"
17734         fi
17735         return 0
17736 }
17737 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17738
17739 test_272c() {
17740         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17741                 skip "Need MDS version at least 2.11.50"
17742
17743         local dom=$DIR/$tdir/$tfile
17744         mkdir -p $DIR/$tdir
17745         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17746
17747         local mdtidx=$($LFS getstripe -m $dom)
17748         local mdtname=MDT$(printf %04x $mdtidx)
17749         local facet=mds$((mdtidx + 1))
17750
17751         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17752                 error "failed to write data into $dom"
17753         local old_md5=$(md5sum $dom)
17754         cancel_lru_locks mdc
17755         local mdtfree1=$(do_facet $facet \
17756                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17757
17758         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17759                 error "failed to migrate to the new composite layout"
17760         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17761                 error "MDT stripe was not removed"
17762
17763         cancel_lru_locks mdc
17764         local new_md5=$(md5sum $dom)
17765         [ "$old_md5" != "$new_md5" ] &&
17766                 error "$old_md5 != $new_md5"
17767
17768         # Skip free space checks with ZFS
17769         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17770                 local mdtfree2=$(do_facet $facet \
17771                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17772                 [ $mdtfree2 -gt $mdtfree1 ] ||
17773                         error "MDS space is not freed after migration"
17774         fi
17775         return 0
17776 }
17777 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17778
17779 test_273a() {
17780         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17781                 skip "Need MDS version at least 2.11.50"
17782
17783         # Layout swap cannot be done if either file has DOM component,
17784         # this will never be supported, migration should be used instead
17785
17786         local dom=$DIR/$tdir/$tfile
17787         mkdir -p $DIR/$tdir
17788
17789         $LFS setstripe -c2 ${dom}_plain
17790         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17791         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17792                 error "can swap layout with DoM component"
17793         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17794                 error "can swap layout with DoM component"
17795
17796         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17797         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17798                 error "can swap layout with DoM component"
17799         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17800                 error "can swap layout with DoM component"
17801         return 0
17802 }
17803 run_test 273a "DoM: layout swapping should fail with DOM"
17804
17805 test_275() {
17806         remote_ost_nodsh && skip "remote OST with nodsh"
17807         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17808                 skip "Need OST version >= 2.10.57"
17809
17810         local file=$DIR/$tfile
17811         local oss
17812
17813         oss=$(comma_list $(osts_nodes))
17814
17815         dd if=/dev/urandom of=$file bs=1M count=2 ||
17816                 error "failed to create a file"
17817         cancel_lru_locks osc
17818
17819         #lock 1
17820         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17821                 error "failed to read a file"
17822
17823 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17824         $LCTL set_param fail_loc=0x8000031f
17825
17826         cancel_lru_locks osc &
17827         sleep 1
17828
17829 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17830         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17831         #IO takes another lock, but matches the PENDING one
17832         #and places it to the IO RPC
17833         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17834                 error "failed to read a file with PENDING lock"
17835 }
17836 run_test 275 "Read on a canceled duplicate lock"
17837
17838 test_276() {
17839         remote_ost_nodsh && skip "remote OST with nodsh"
17840         local pid
17841
17842         do_facet ost1 "(while true; do \
17843                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17844                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17845         pid=$!
17846
17847         for LOOP in $(seq 20); do
17848                 stop ost1
17849                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17850         done
17851         kill -9 $pid
17852         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17853                 rm $TMP/sanity_276_pid"
17854 }
17855 run_test 276 "Race between mount and obd_statfs"
17856
17857 cleanup_test_300() {
17858         trap 0
17859         umask $SAVE_UMASK
17860 }
17861 test_striped_dir() {
17862         local mdt_index=$1
17863         local stripe_count
17864         local stripe_index
17865
17866         mkdir -p $DIR/$tdir
17867
17868         SAVE_UMASK=$(umask)
17869         trap cleanup_test_300 RETURN EXIT
17870
17871         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17872                                                 $DIR/$tdir/striped_dir ||
17873                 error "set striped dir error"
17874
17875         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17876         [ "$mode" = "755" ] || error "expect 755 got $mode"
17877
17878         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17879                 error "getdirstripe failed"
17880         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17881         if [ "$stripe_count" != "2" ]; then
17882                 error "1:stripe_count is $stripe_count, expect 2"
17883         fi
17884         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17885         if [ "$stripe_count" != "2" ]; then
17886                 error "2:stripe_count is $stripe_count, expect 2"
17887         fi
17888
17889         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17890         if [ "$stripe_index" != "$mdt_index" ]; then
17891                 error "stripe_index is $stripe_index, expect $mdt_index"
17892         fi
17893
17894         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17895                 error "nlink error after create striped dir"
17896
17897         mkdir $DIR/$tdir/striped_dir/a
17898         mkdir $DIR/$tdir/striped_dir/b
17899
17900         stat $DIR/$tdir/striped_dir/a ||
17901                 error "create dir under striped dir failed"
17902         stat $DIR/$tdir/striped_dir/b ||
17903                 error "create dir under striped dir failed"
17904
17905         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17906                 error "nlink error after mkdir"
17907
17908         rmdir $DIR/$tdir/striped_dir/a
17909         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17910                 error "nlink error after rmdir"
17911
17912         rmdir $DIR/$tdir/striped_dir/b
17913         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17914                 error "nlink error after rmdir"
17915
17916         chattr +i $DIR/$tdir/striped_dir
17917         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17918                 error "immutable flags not working under striped dir!"
17919         chattr -i $DIR/$tdir/striped_dir
17920
17921         rmdir $DIR/$tdir/striped_dir ||
17922                 error "rmdir striped dir error"
17923
17924         cleanup_test_300
17925
17926         true
17927 }
17928
17929 test_300a() {
17930         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17931                 skip "skipped for lustre < 2.7.0"
17932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17934
17935         test_striped_dir 0 || error "failed on striped dir on MDT0"
17936         test_striped_dir 1 || error "failed on striped dir on MDT0"
17937 }
17938 run_test 300a "basic striped dir sanity test"
17939
17940 test_300b() {
17941         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17942                 skip "skipped for lustre < 2.7.0"
17943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17945
17946         local i
17947         local mtime1
17948         local mtime2
17949         local mtime3
17950
17951         test_mkdir $DIR/$tdir || error "mkdir fail"
17952         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17953                 error "set striped dir error"
17954         for i in {0..9}; do
17955                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17956                 sleep 1
17957                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17958                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17959                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17960                 sleep 1
17961                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17962                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17963                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17964         done
17965         true
17966 }
17967 run_test 300b "check ctime/mtime for striped dir"
17968
17969 test_300c() {
17970         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17971                 skip "skipped for lustre < 2.7.0"
17972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17974
17975         local file_count
17976
17977         mkdir -p $DIR/$tdir
17978         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17979                 error "set striped dir error"
17980
17981         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17982                 error "chown striped dir failed"
17983
17984         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17985                 error "create 5k files failed"
17986
17987         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17988
17989         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17990
17991         rm -rf $DIR/$tdir
17992 }
17993 run_test 300c "chown && check ls under striped directory"
17994
17995 test_300d() {
17996         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17997                 skip "skipped for lustre < 2.7.0"
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18000
18001         local stripe_count
18002         local file
18003
18004         mkdir -p $DIR/$tdir
18005         $LFS setstripe -c 2 $DIR/$tdir
18006
18007         #local striped directory
18008         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18009                 error "set striped dir error"
18010         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18011                 error "create 10 files failed"
18012
18013         #remote striped directory
18014         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18015                 error "set striped dir error"
18016         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18017                 error "create 10 files failed"
18018
18019         for file in $(find $DIR/$tdir); do
18020                 stripe_count=$($LFS getstripe -c $file)
18021                 [ $stripe_count -eq 2 ] ||
18022                         error "wrong stripe $stripe_count for $file"
18023         done
18024
18025         rm -rf $DIR/$tdir
18026 }
18027 run_test 300d "check default stripe under striped directory"
18028
18029 test_300e() {
18030         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18031                 skip "Need MDS version at least 2.7.55"
18032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18034
18035         local stripe_count
18036         local file
18037
18038         mkdir -p $DIR/$tdir
18039
18040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18041                 error "set striped dir error"
18042
18043         touch $DIR/$tdir/striped_dir/a
18044         touch $DIR/$tdir/striped_dir/b
18045         touch $DIR/$tdir/striped_dir/c
18046
18047         mkdir $DIR/$tdir/striped_dir/dir_a
18048         mkdir $DIR/$tdir/striped_dir/dir_b
18049         mkdir $DIR/$tdir/striped_dir/dir_c
18050
18051         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18052                 error "set striped adir under striped dir error"
18053
18054         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18055                 error "set striped bdir under striped dir error"
18056
18057         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18058                 error "set striped cdir under striped dir error"
18059
18060         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18061                 error "rename dir under striped dir fails"
18062
18063         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18064                 error "rename dir under different stripes fails"
18065
18066         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18067                 error "rename file under striped dir should succeed"
18068
18069         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18070                 error "rename dir under striped dir should succeed"
18071
18072         rm -rf $DIR/$tdir
18073 }
18074 run_test 300e "check rename under striped directory"
18075
18076 test_300f() {
18077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18078         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18079         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18080                 skip "Need MDS version at least 2.7.55"
18081
18082         local stripe_count
18083         local file
18084
18085         rm -rf $DIR/$tdir
18086         mkdir -p $DIR/$tdir
18087
18088         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18089                 error "set striped dir error"
18090
18091         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18092                 error "set striped dir error"
18093
18094         touch $DIR/$tdir/striped_dir/a
18095         mkdir $DIR/$tdir/striped_dir/dir_a
18096         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18097                 error "create striped dir under striped dir fails"
18098
18099         touch $DIR/$tdir/striped_dir1/b
18100         mkdir $DIR/$tdir/striped_dir1/dir_b
18101         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18102                 error "create striped dir under striped dir fails"
18103
18104         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18105                 error "rename dir under different striped dir should fail"
18106
18107         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18108                 error "rename striped dir under diff striped dir should fail"
18109
18110         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18111                 error "rename file under diff striped dirs fails"
18112
18113         rm -rf $DIR/$tdir
18114 }
18115 run_test 300f "check rename cross striped directory"
18116
18117 test_300_check_default_striped_dir()
18118 {
18119         local dirname=$1
18120         local default_count=$2
18121         local default_index=$3
18122         local stripe_count
18123         local stripe_index
18124         local dir_stripe_index
18125         local dir
18126
18127         echo "checking $dirname $default_count $default_index"
18128         $LFS setdirstripe -D -c $default_count -i $default_index \
18129                                 -t all_char $DIR/$tdir/$dirname ||
18130                 error "set default stripe on striped dir error"
18131         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18132         [ $stripe_count -eq $default_count ] ||
18133                 error "expect $default_count get $stripe_count for $dirname"
18134
18135         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18136         [ $stripe_index -eq $default_index ] ||
18137                 error "expect $default_index get $stripe_index for $dirname"
18138
18139         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18140                                                 error "create dirs failed"
18141
18142         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18143         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18144         for dir in $(find $DIR/$tdir/$dirname/*); do
18145                 stripe_count=$($LFS getdirstripe -c $dir)
18146                 [ $stripe_count -eq $default_count ] ||
18147                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18148                 error "stripe count $default_count != $stripe_count for $dir"
18149
18150                 stripe_index=$($LFS getdirstripe -i $dir)
18151                 [ $default_index -eq -1 ] ||
18152                         [ $stripe_index -eq $default_index ] ||
18153                         error "$stripe_index != $default_index for $dir"
18154
18155                 #check default stripe
18156                 stripe_count=$($LFS getdirstripe -D -c $dir)
18157                 [ $stripe_count -eq $default_count ] ||
18158                 error "default count $default_count != $stripe_count for $dir"
18159
18160                 stripe_index=$($LFS getdirstripe -D -i $dir)
18161                 [ $stripe_index -eq $default_index ] ||
18162                 error "default index $default_index != $stripe_index for $dir"
18163         done
18164         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18165 }
18166
18167 test_300g() {
18168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18169         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18170                 skip "Need MDS version at least 2.7.55"
18171
18172         local dir
18173         local stripe_count
18174         local stripe_index
18175
18176         mkdir $DIR/$tdir
18177         mkdir $DIR/$tdir/normal_dir
18178
18179         #Checking when client cache stripe index
18180         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18181         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18182                 error "create striped_dir failed"
18183
18184         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18185                 error "create dir0 fails"
18186         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18187         [ $stripe_index -eq 0 ] ||
18188                 error "dir0 expect index 0 got $stripe_index"
18189
18190         mkdir $DIR/$tdir/striped_dir/dir1 ||
18191                 error "create dir1 fails"
18192         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18193         [ $stripe_index -eq 1 ] ||
18194                 error "dir1 expect index 1 got $stripe_index"
18195
18196         #check default stripe count/stripe index
18197         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18198         test_300_check_default_striped_dir normal_dir 1 0
18199         test_300_check_default_striped_dir normal_dir 2 1
18200         test_300_check_default_striped_dir normal_dir 2 -1
18201
18202         #delete default stripe information
18203         echo "delete default stripeEA"
18204         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18205                 error "set default stripe on striped dir error"
18206
18207         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18208         for dir in $(find $DIR/$tdir/normal_dir/*); do
18209                 stripe_count=$($LFS getdirstripe -c $dir)
18210                 [ $stripe_count -eq 0 ] ||
18211                         error "expect 1 get $stripe_count for $dir"
18212                 stripe_index=$($LFS getdirstripe -i $dir)
18213                 [ $stripe_index -eq 0 ] ||
18214                         error "expect 0 get $stripe_index for $dir"
18215         done
18216 }
18217 run_test 300g "check default striped directory for normal directory"
18218
18219 test_300h() {
18220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18221         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18222                 skip "Need MDS version at least 2.7.55"
18223
18224         local dir
18225         local stripe_count
18226
18227         mkdir $DIR/$tdir
18228         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18229                 error "set striped dir error"
18230
18231         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18232         test_300_check_default_striped_dir striped_dir 1 0
18233         test_300_check_default_striped_dir striped_dir 2 1
18234         test_300_check_default_striped_dir striped_dir 2 -1
18235
18236         #delete default stripe information
18237         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18238                 error "set default stripe on striped dir error"
18239
18240         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18241         for dir in $(find $DIR/$tdir/striped_dir/*); do
18242                 stripe_count=$($LFS getdirstripe -c $dir)
18243                 [ $stripe_count -eq 0 ] ||
18244                         error "expect 1 get $stripe_count for $dir"
18245         done
18246 }
18247 run_test 300h "check default striped directory for striped directory"
18248
18249 test_300i() {
18250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18252         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18253                 skip "Need MDS version at least 2.7.55"
18254
18255         local stripe_count
18256         local file
18257
18258         mkdir $DIR/$tdir
18259
18260         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18261                 error "set striped dir error"
18262
18263         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18264                 error "create files under striped dir failed"
18265
18266         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18267                 error "set striped hashdir error"
18268
18269         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18270                 error "create dir0 under hash dir failed"
18271         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18272                 error "create dir1 under hash dir failed"
18273
18274         # unfortunately, we need to umount to clear dir layout cache for now
18275         # once we fully implement dir layout, we can drop this
18276         umount_client $MOUNT || error "umount failed"
18277         mount_client $MOUNT || error "mount failed"
18278
18279         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18280         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18281         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18282
18283         #set the stripe to be unknown hash type
18284         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18285         $LCTL set_param fail_loc=0x1901
18286         for ((i = 0; i < 10; i++)); do
18287                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18288                         error "stat f-$i failed"
18289                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18290         done
18291
18292         touch $DIR/$tdir/striped_dir/f0 &&
18293                 error "create under striped dir with unknown hash should fail"
18294
18295         $LCTL set_param fail_loc=0
18296
18297         umount_client $MOUNT || error "umount failed"
18298         mount_client $MOUNT || error "mount failed"
18299
18300         return 0
18301 }
18302 run_test 300i "client handle unknown hash type striped directory"
18303
18304 test_300j() {
18305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18308                 skip "Need MDS version at least 2.7.55"
18309
18310         local stripe_count
18311         local file
18312
18313         mkdir $DIR/$tdir
18314
18315         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18316         $LCTL set_param fail_loc=0x1702
18317         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18318                 error "set striped dir error"
18319
18320         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18321                 error "create files under striped dir failed"
18322
18323         $LCTL set_param fail_loc=0
18324
18325         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18326
18327         return 0
18328 }
18329 run_test 300j "test large update record"
18330
18331 test_300k() {
18332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18334         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18335                 skip "Need MDS version at least 2.7.55"
18336
18337         # this test needs a huge transaction
18338         local kb
18339         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18340         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18341
18342         local stripe_count
18343         local file
18344
18345         mkdir $DIR/$tdir
18346
18347         #define OBD_FAIL_LARGE_STRIPE   0x1703
18348         $LCTL set_param fail_loc=0x1703
18349         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18350                 error "set striped dir error"
18351         $LCTL set_param fail_loc=0
18352
18353         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18354                 error "getstripeddir fails"
18355         rm -rf $DIR/$tdir/striped_dir ||
18356                 error "unlink striped dir fails"
18357
18358         return 0
18359 }
18360 run_test 300k "test large striped directory"
18361
18362 test_300l() {
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18365         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18366                 skip "Need MDS version at least 2.7.55"
18367
18368         local stripe_index
18369
18370         test_mkdir -p $DIR/$tdir/striped_dir
18371         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18372                         error "chown $RUNAS_ID failed"
18373         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18374                 error "set default striped dir failed"
18375
18376         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18377         $LCTL set_param fail_loc=0x80000158
18378         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18379
18380         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18381         [ $stripe_index -eq 1 ] ||
18382                 error "expect 1 get $stripe_index for $dir"
18383 }
18384 run_test 300l "non-root user to create dir under striped dir with stale layout"
18385
18386 test_300m() {
18387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18388         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18389         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18390                 skip "Need MDS version at least 2.7.55"
18391
18392         mkdir -p $DIR/$tdir/striped_dir
18393         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18394                 error "set default stripes dir error"
18395
18396         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18397
18398         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18399         [ $stripe_count -eq 0 ] ||
18400                         error "expect 0 get $stripe_count for a"
18401
18402         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18403                 error "set default stripes dir error"
18404
18405         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18406
18407         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18408         [ $stripe_count -eq 0 ] ||
18409                         error "expect 0 get $stripe_count for b"
18410
18411         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18412                 error "set default stripes dir error"
18413
18414         mkdir $DIR/$tdir/striped_dir/c &&
18415                 error "default stripe_index is invalid, mkdir c should fails"
18416
18417         rm -rf $DIR/$tdir || error "rmdir fails"
18418 }
18419 run_test 300m "setstriped directory on single MDT FS"
18420
18421 cleanup_300n() {
18422         local list=$(comma_list $(mdts_nodes))
18423
18424         trap 0
18425         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18426 }
18427
18428 test_300n() {
18429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18431         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18432                 skip "Need MDS version at least 2.7.55"
18433         remote_mds_nodsh && skip "remote MDS with nodsh"
18434
18435         local stripe_index
18436         local list=$(comma_list $(mdts_nodes))
18437
18438         trap cleanup_300n RETURN EXIT
18439         mkdir -p $DIR/$tdir
18440         chmod 777 $DIR/$tdir
18441         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18442                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18443                 error "create striped dir succeeds with gid=0"
18444
18445         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18446         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18447                 error "create striped dir fails with gid=-1"
18448
18449         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18450         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18451                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18452                 error "set default striped dir succeeds with gid=0"
18453
18454
18455         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18456         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18457                 error "set default striped dir fails with gid=-1"
18458
18459
18460         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18461         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18462                                         error "create test_dir fails"
18463         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18464                                         error "create test_dir1 fails"
18465         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18466                                         error "create test_dir2 fails"
18467         cleanup_300n
18468 }
18469 run_test 300n "non-root user to create dir under striped dir with default EA"
18470
18471 test_300o() {
18472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18474         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18475                 skip "Need MDS version at least 2.7.55"
18476
18477         local numfree1
18478         local numfree2
18479
18480         mkdir -p $DIR/$tdir
18481
18482         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18483         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18484         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18485                 skip "not enough free inodes $numfree1 $numfree2"
18486         fi
18487
18488         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18489         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18490         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18491                 skip "not enough free space $numfree1 $numfree2"
18492         fi
18493
18494         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18495                 error "setdirstripe fails"
18496
18497         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18498                 error "create dirs fails"
18499
18500         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18501         ls $DIR/$tdir/striped_dir > /dev/null ||
18502                 error "ls striped dir fails"
18503         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18504                 error "unlink big striped dir fails"
18505 }
18506 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18507
18508 test_300p() {
18509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18511         remote_mds_nodsh && skip "remote MDS with nodsh"
18512
18513         mkdir -p $DIR/$tdir
18514
18515         #define OBD_FAIL_OUT_ENOSPC     0x1704
18516         do_facet mds2 lctl set_param fail_loc=0x80001704
18517         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18518                  && error "create striped directory should fail"
18519
18520         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18521
18522         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18523         true
18524 }
18525 run_test 300p "create striped directory without space"
18526
18527 test_300q() {
18528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18530
18531         local fd=$(free_fd)
18532         local cmd="exec $fd<$tdir"
18533         cd $DIR
18534         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18535         eval $cmd
18536         cmd="exec $fd<&-"
18537         trap "eval $cmd" EXIT
18538         cd $tdir || error "cd $tdir fails"
18539         rmdir  ../$tdir || error "rmdir $tdir fails"
18540         mkdir local_dir && error "create dir succeeds"
18541         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18542         eval $cmd
18543         return 0
18544 }
18545 run_test 300q "create remote directory under orphan directory"
18546
18547 test_300r() {
18548         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18549                 skip "Need MDS version at least 2.7.55" && return
18550         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18551
18552         mkdir $DIR/$tdir
18553
18554         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18555                 error "set striped dir error"
18556
18557         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18558                 error "getstripeddir fails"
18559
18560         local stripe_count
18561         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18562                       awk '/lmv_stripe_count:/ { print $2 }')
18563
18564         [ $MDSCOUNT -ne $stripe_count ] &&
18565                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18566
18567         rm -rf $DIR/$tdir/striped_dir ||
18568                 error "unlink striped dir fails"
18569 }
18570 run_test 300r "test -1 striped directory"
18571
18572 prepare_remote_file() {
18573         mkdir $DIR/$tdir/src_dir ||
18574                 error "create remote source failed"
18575
18576         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18577                  error "cp to remote source failed"
18578         touch $DIR/$tdir/src_dir/a
18579
18580         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18581                 error "create remote target dir failed"
18582
18583         touch $DIR/$tdir/tgt_dir/b
18584
18585         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18586                 error "rename dir cross MDT failed!"
18587
18588         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18589                 error "src_child still exists after rename"
18590
18591         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18592                 error "missing file(a) after rename"
18593
18594         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18595                 error "diff after rename"
18596 }
18597
18598 test_310a() {
18599         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18601
18602         local remote_file=$DIR/$tdir/tgt_dir/b
18603
18604         mkdir -p $DIR/$tdir
18605
18606         prepare_remote_file || error "prepare remote file failed"
18607
18608         #open-unlink file
18609         $OPENUNLINK $remote_file $remote_file ||
18610                 error "openunlink $remote_file failed"
18611         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18612 }
18613 run_test 310a "open unlink remote file"
18614
18615 test_310b() {
18616         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18618
18619         local remote_file=$DIR/$tdir/tgt_dir/b
18620
18621         mkdir -p $DIR/$tdir
18622
18623         prepare_remote_file || error "prepare remote file failed"
18624
18625         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18626         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18627         $CHECKSTAT -t file $remote_file || error "check file failed"
18628 }
18629 run_test 310b "unlink remote file with multiple links while open"
18630
18631 test_310c() {
18632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18633         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18634
18635         local remote_file=$DIR/$tdir/tgt_dir/b
18636
18637         mkdir -p $DIR/$tdir
18638
18639         prepare_remote_file || error "prepare remote file failed"
18640
18641         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18642         multiop_bg_pause $remote_file O_uc ||
18643                         error "mulitop failed for remote file"
18644         MULTIPID=$!
18645         $MULTIOP $DIR/$tfile Ouc
18646         kill -USR1 $MULTIPID
18647         wait $MULTIPID
18648 }
18649 run_test 310c "open-unlink remote file with multiple links"
18650
18651 #LU-4825
18652 test_311() {
18653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18654         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18655         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18656                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18657         remote_mds_nodsh && skip "remote MDS with nodsh"
18658
18659         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18660         local mdts=$(comma_list $(mdts_nodes))
18661
18662         mkdir -p $DIR/$tdir
18663         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18664         createmany -o $DIR/$tdir/$tfile. 1000
18665
18666         # statfs data is not real time, let's just calculate it
18667         old_iused=$((old_iused + 1000))
18668
18669         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18670                         osp.*OST0000*MDT0000.create_count")
18671         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18672                                 osp.*OST0000*MDT0000.max_create_count")
18673         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18674
18675         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18676         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18677         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18678
18679         unlinkmany $DIR/$tdir/$tfile. 1000
18680
18681         do_nodes $mdts "$LCTL set_param -n \
18682                         osp.*OST0000*.max_create_count=$max_count"
18683         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18684                 do_nodes $mdts "$LCTL set_param -n \
18685                                 osp.*OST0000*.create_count=$count"
18686         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18687                         grep "=0" && error "create_count is zero"
18688
18689         local new_iused
18690         for i in $(seq 120); do
18691                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18692                 # system may be too busy to destroy all objs in time, use
18693                 # a somewhat small value to not fail autotest
18694                 [ $((old_iused - new_iused)) -gt 400 ] && break
18695                 sleep 1
18696         done
18697
18698         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18699         [ $((old_iused - new_iused)) -gt 400 ] ||
18700                 error "objs not destroyed after unlink"
18701 }
18702 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18703
18704 zfs_oid_to_objid()
18705 {
18706         local ost=$1
18707         local objid=$2
18708
18709         local vdevdir=$(dirname $(facet_vdevice $ost))
18710         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18711         local zfs_zapid=$(do_facet $ost $cmd |
18712                           grep -w "/O/0/d$((objid%32))" -C 5 |
18713                           awk '/Object/{getline; print $1}')
18714         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18715                           awk "/$objid = /"'{printf $3}')
18716
18717         echo $zfs_objid
18718 }
18719
18720 zfs_object_blksz() {
18721         local ost=$1
18722         local objid=$2
18723
18724         local vdevdir=$(dirname $(facet_vdevice $ost))
18725         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18726         local blksz=$(do_facet $ost $cmd $objid |
18727                       awk '/dblk/{getline; printf $4}')
18728
18729         case "${blksz: -1}" in
18730                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18731                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18732                 *) ;;
18733         esac
18734
18735         echo $blksz
18736 }
18737
18738 test_312() { # LU-4856
18739         remote_ost_nodsh && skip "remote OST with nodsh"
18740         [ "$ost1_FSTYPE" = "zfs" ] ||
18741                 skip_env "the test only applies to zfs"
18742
18743         local max_blksz=$(do_facet ost1 \
18744                           $ZFS get -p recordsize $(facet_device ost1) |
18745                           awk '!/VALUE/{print $3}')
18746
18747         # to make life a little bit easier
18748         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18749         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18750
18751         local tf=$DIR/$tdir/$tfile
18752         touch $tf
18753         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18754
18755         # Get ZFS object id
18756         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18757         # block size change by sequential overwrite
18758         local bs
18759
18760         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18761                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18762
18763                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18764                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18765         done
18766         rm -f $tf
18767
18768         # block size change by sequential append write
18769         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18770         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18771         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18772         local count
18773
18774         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18775                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18776                         oflag=sync conv=notrunc
18777
18778                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18779                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18780                         error "blksz error, actual $blksz, " \
18781                                 "expected: 2 * $count * $PAGE_SIZE"
18782         done
18783         rm -f $tf
18784
18785         # random write
18786         touch $tf
18787         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18788         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18789
18790         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18791         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18792         [ $blksz -eq $PAGE_SIZE ] ||
18793                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18794
18795         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18796         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18797         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18798
18799         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18800         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18801         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18802 }
18803 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18804
18805 test_313() {
18806         remote_ost_nodsh && skip "remote OST with nodsh"
18807
18808         local file=$DIR/$tfile
18809
18810         rm -f $file
18811         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18812
18813         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18814         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18815         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18816                 error "write should failed"
18817         do_facet ost1 "$LCTL set_param fail_loc=0"
18818         rm -f $file
18819 }
18820 run_test 313 "io should fail after last_rcvd update fail"
18821
18822 test_314() {
18823         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18824
18825         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18826         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18827         rm -f $DIR/$tfile
18828         wait_delete_completed
18829         do_facet ost1 "$LCTL set_param fail_loc=0"
18830 }
18831 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18832
18833 test_315() { # LU-618
18834         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18835
18836         local file=$DIR/$tfile
18837         rm -f $file
18838
18839         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18840                 error "multiop file write failed"
18841         $MULTIOP $file oO_RDONLY:r4063232_c &
18842         PID=$!
18843
18844         sleep 2
18845
18846         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18847         kill -USR1 $PID
18848
18849         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18850         rm -f $file
18851 }
18852 run_test 315 "read should be accounted"
18853
18854 test_316() {
18855         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18856         large_xattr_enabled || skip_env "ea_inode feature disabled"
18857
18858         rm -rf $DIR/$tdir/d
18859         mkdir -p $DIR/$tdir/d
18860         chown nobody $DIR/$tdir/d
18861         touch $DIR/$tdir/d/file
18862
18863         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18864 }
18865 run_test 316 "lfs mv"
18866
18867 test_317() {
18868         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18869                 skip "Need MDS version at least 2.11.53"
18870         local trunc_sz
18871         local grant_blk_size
18872
18873         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18874                 skip "LU-10370: no implementation for ZFS" && return
18875         fi
18876
18877         stack_trap "rm -f $DIR/$tfile" EXIT
18878         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18879                         awk '/grant_block_size:/ { print $2; exit; }')
18880         #
18881         # Create File of size 5M. Truncate it to below size's and verify
18882         # blocks count.
18883         #
18884         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18885                 error "Create file : $DIR/$tfile"
18886
18887         for trunc_sz in 2097152 4097 4000 509 0; do
18888                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18889                         error "truncate $tfile to $trunc_sz failed"
18890                 local sz=$(stat --format=%s $DIR/$tfile)
18891                 local blk=$(stat --format=%b $DIR/$tfile)
18892                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18893                                      grant_blk_size) * 8))
18894
18895                 if [[ $blk -ne $trunc_blk ]]; then
18896                         $(which stat) $DIR/$tfile
18897                         error "Expected Block $trunc_blk got $blk for $tfile"
18898                 fi
18899
18900                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18901                         error "Expected Size $trunc_sz got $sz for $tfile"
18902         done
18903
18904         #
18905         # sparse file test
18906         # Create file with a hole and write actual two blocks. Block count
18907         # must be 16.
18908         #
18909         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18910                 conv=fsync || error "Create file : $DIR/$tfile"
18911
18912         # Calculate the final truncate size.
18913         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18914
18915         #
18916         # truncate to size $trunc_sz bytes. Strip the last block
18917         # The block count must drop to 8
18918         #
18919         $TRUNCATE $DIR/$tfile $trunc_sz ||
18920                 error "truncate $tfile to $trunc_sz failed"
18921
18922         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18923         sz=$(stat --format=%s $DIR/$tfile)
18924         blk=$(stat --format=%b $DIR/$tfile)
18925
18926         if [[ $blk -ne $trunc_bsz ]]; then
18927                 $(which stat) $DIR/$tfile
18928                 error "Expected Block $trunc_bsz got $blk for $tfile"
18929         fi
18930
18931         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18932                 error "Expected Size $trunc_sz got $sz for $tfile"
18933 }
18934 run_test 317 "Verify blocks get correctly update after truncate"
18935
18936 test_319() {
18937         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18938
18939         local before=$(date +%s)
18940         local evict
18941         local mdir=$DIR/$tdir
18942         local file=$mdir/xxx
18943
18944         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18945         touch $file
18946
18947 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18948         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18949         $LFS mv -m1 $file &
18950
18951         sleep 1
18952         dd if=$file of=/dev/null
18953         wait
18954         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18955           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18956
18957         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18958 }
18959 run_test 319 "lost lease lock on migrate error"
18960
18961 test_fake_rw() {
18962         local read_write=$1
18963         if [ "$read_write" = "write" ]; then
18964                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18965         elif [ "$read_write" = "read" ]; then
18966                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18967         else
18968                 error "argument error"
18969         fi
18970
18971         # turn off debug for performance testing
18972         local saved_debug=$($LCTL get_param -n debug)
18973         $LCTL set_param debug=0
18974
18975         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18976
18977         # get ost1 size - lustre-OST0000
18978         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18979         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18980         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18981
18982         if [ "$read_write" = "read" ]; then
18983                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18984         fi
18985
18986         local start_time=$(date +%s.%N)
18987         $dd_cmd bs=1M count=$blocks oflag=sync ||
18988                 error "real dd $read_write error"
18989         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18990
18991         if [ "$read_write" = "write" ]; then
18992                 rm -f $DIR/$tfile
18993         fi
18994
18995         # define OBD_FAIL_OST_FAKE_RW           0x238
18996         do_facet ost1 $LCTL set_param fail_loc=0x238
18997
18998         local start_time=$(date +%s.%N)
18999         $dd_cmd bs=1M count=$blocks oflag=sync ||
19000                 error "fake dd $read_write error"
19001         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19002
19003         if [ "$read_write" = "write" ]; then
19004                 # verify file size
19005                 cancel_lru_locks osc
19006                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19007                         error "$tfile size not $blocks MB"
19008         fi
19009         do_facet ost1 $LCTL set_param fail_loc=0
19010
19011         echo "fake $read_write $duration_fake vs. normal $read_write" \
19012                 "$duration in seconds"
19013         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19014                 error_not_in_vm "fake write is slower"
19015
19016         $LCTL set_param -n debug="$saved_debug"
19017         rm -f $DIR/$tfile
19018 }
19019 test_399a() { # LU-7655 for OST fake write
19020         remote_ost_nodsh && skip "remote OST with nodsh"
19021
19022         test_fake_rw write
19023 }
19024 run_test 399a "fake write should not be slower than normal write"
19025
19026 test_399b() { # LU-8726 for OST fake read
19027         remote_ost_nodsh && skip "remote OST with nodsh"
19028         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19029                 skip_env "ldiskfs only test"
19030         fi
19031
19032         test_fake_rw read
19033 }
19034 run_test 399b "fake read should not be slower than normal read"
19035
19036 test_400a() { # LU-1606, was conf-sanity test_74
19037         if ! which $CC > /dev/null 2>&1; then
19038                 skip_env "$CC is not installed"
19039         fi
19040
19041         local extra_flags=''
19042         local out=$TMP/$tfile
19043         local prefix=/usr/include/lustre
19044         local prog
19045
19046         if ! [[ -d $prefix ]]; then
19047                 # Assume we're running in tree and fixup the include path.
19048                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19049                 extra_flags+=" -L$LUSTRE/utils/.lib"
19050         fi
19051
19052         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19053                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19054                         error "client api broken"
19055         done
19056         rm -f $out
19057 }
19058 run_test 400a "Lustre client api program can compile and link"
19059
19060 test_400b() { # LU-1606, LU-5011
19061         local header
19062         local out=$TMP/$tfile
19063         local prefix=/usr/include/linux/lustre
19064
19065         # We use a hard coded prefix so that this test will not fail
19066         # when run in tree. There are headers in lustre/include/lustre/
19067         # that are not packaged (like lustre_idl.h) and have more
19068         # complicated include dependencies (like config.h and lnet/types.h).
19069         # Since this test about correct packaging we just skip them when
19070         # they don't exist (see below) rather than try to fixup cppflags.
19071
19072         if ! which $CC > /dev/null 2>&1; then
19073                 skip_env "$CC is not installed"
19074         fi
19075
19076         for header in $prefix/*.h; do
19077                 if ! [[ -f "$header" ]]; then
19078                         continue
19079                 fi
19080
19081                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19082                         continue # lustre_ioctl.h is internal header
19083                 fi
19084
19085                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19086                         error "cannot compile '$header'"
19087         done
19088         rm -f $out
19089 }
19090 run_test 400b "packaged headers can be compiled"
19091
19092 test_401a() { #LU-7437
19093         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19094         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19095
19096         #count the number of parameters by "list_param -R"
19097         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19098         #count the number of parameters by listing proc files
19099         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19100         echo "proc_dirs='$proc_dirs'"
19101         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19102         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19103                       sort -u | wc -l)
19104
19105         [ $params -eq $procs ] ||
19106                 error "found $params parameters vs. $procs proc files"
19107
19108         # test the list_param -D option only returns directories
19109         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19110         #count the number of parameters by listing proc directories
19111         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19112                 sort -u | wc -l)
19113
19114         [ $params -eq $procs ] ||
19115                 error "found $params parameters vs. $procs proc files"
19116 }
19117 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19118
19119 test_401b() {
19120         local save=$($LCTL get_param -n jobid_var)
19121         local tmp=testing
19122
19123         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19124                 error "no error returned when setting bad parameters"
19125
19126         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19127         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19128
19129         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19130         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19131         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19132 }
19133 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19134
19135 test_401c() {
19136         local jobid_var_old=$($LCTL get_param -n jobid_var)
19137         local jobid_var_new
19138
19139         $LCTL set_param jobid_var= &&
19140                 error "no error returned for 'set_param a='"
19141
19142         jobid_var_new=$($LCTL get_param -n jobid_var)
19143         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19144                 error "jobid_var was changed by setting without value"
19145
19146         $LCTL set_param jobid_var &&
19147                 error "no error returned for 'set_param a'"
19148
19149         jobid_var_new=$($LCTL get_param -n jobid_var)
19150         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19151                 error "jobid_var was changed by setting without value"
19152 }
19153 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19154
19155 test_401d() {
19156         local jobid_var_old=$($LCTL get_param -n jobid_var)
19157         local jobid_var_new
19158         local new_value="foo=bar"
19159
19160         $LCTL set_param jobid_var=$new_value ||
19161                 error "'set_param a=b' did not accept a value containing '='"
19162
19163         jobid_var_new=$($LCTL get_param -n jobid_var)
19164         [[ "$jobid_var_new" == "$new_value" ]] ||
19165                 error "'set_param a=b' failed on a value containing '='"
19166
19167         # Reset the jobid_var to test the other format
19168         $LCTL set_param jobid_var=$jobid_var_old
19169         jobid_var_new=$($LCTL get_param -n jobid_var)
19170         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19171                 error "failed to reset jobid_var"
19172
19173         $LCTL set_param jobid_var $new_value ||
19174                 error "'set_param a b' did not accept a value containing '='"
19175
19176         jobid_var_new=$($LCTL get_param -n jobid_var)
19177         [[ "$jobid_var_new" == "$new_value" ]] ||
19178                 error "'set_param a b' failed on a value containing '='"
19179
19180         $LCTL set_param jobid_var $jobid_var_old
19181         jobid_var_new=$($LCTL get_param -n jobid_var)
19182         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19183                 error "failed to reset jobid_var"
19184 }
19185 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19186
19187 test_402() {
19188         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19189         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19190                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19191         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19192                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19193                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19194         remote_mds_nodsh && skip "remote MDS with nodsh"
19195
19196         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19197 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19198         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19199         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19200                 echo "Touch failed - OK"
19201 }
19202 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19203
19204 test_403() {
19205         local file1=$DIR/$tfile.1
19206         local file2=$DIR/$tfile.2
19207         local tfile=$TMP/$tfile
19208
19209         rm -f $file1 $file2 $tfile
19210
19211         touch $file1
19212         ln $file1 $file2
19213
19214         # 30 sec OBD_TIMEOUT in ll_getattr()
19215         # right before populating st_nlink
19216         $LCTL set_param fail_loc=0x80001409
19217         stat -c %h $file1 > $tfile &
19218
19219         # create an alias, drop all locks and reclaim the dentry
19220         < $file2
19221         cancel_lru_locks mdc
19222         cancel_lru_locks osc
19223         sysctl -w vm.drop_caches=2
19224
19225         wait
19226
19227         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19228
19229         rm -f $tfile $file1 $file2
19230 }
19231 run_test 403 "i_nlink should not drop to zero due to aliasing"
19232
19233 test_404() { # LU-6601
19234         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19235                 skip "Need server version newer than 2.8.52"
19236         remote_mds_nodsh && skip "remote MDS with nodsh"
19237
19238         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19239                 awk '/osp .*-osc-MDT/ { print $4}')
19240
19241         local osp
19242         for osp in $mosps; do
19243                 echo "Deactivate: " $osp
19244                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19245                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19246                         awk -vp=$osp '$4 == p { print $2 }')
19247                 [ $stat = IN ] || {
19248                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19249                         error "deactivate error"
19250                 }
19251                 echo "Activate: " $osp
19252                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19253                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19254                         awk -vp=$osp '$4 == p { print $2 }')
19255                 [ $stat = UP ] || {
19256                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19257                         error "activate error"
19258                 }
19259         done
19260 }
19261 run_test 404 "validate manual {de}activated works properly for OSPs"
19262
19263 test_405() {
19264         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19265         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19266                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19267                         skip "Layout swap lock is not supported"
19268
19269         check_swap_layouts_support
19270
19271         test_mkdir $DIR/$tdir
19272         swap_lock_test -d $DIR/$tdir ||
19273                 error "One layout swap locked test failed"
19274 }
19275 run_test 405 "Various layout swap lock tests"
19276
19277 test_406() {
19278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19279         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19280         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19282         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19283                 skip "Need MDS version at least 2.8.50"
19284
19285         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19286         local test_pool=$TESTNAME
19287
19288         if ! combined_mgs_mds ; then
19289                 mount_mgs_client
19290         fi
19291         pool_add $test_pool || error "pool_add failed"
19292         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19293                 error "pool_add_targets failed"
19294
19295         save_layout_restore_at_exit $MOUNT
19296
19297         # parent set default stripe count only, child will stripe from both
19298         # parent and fs default
19299         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19300                 error "setstripe $MOUNT failed"
19301         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19302         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19303         for i in $(seq 10); do
19304                 local f=$DIR/$tdir/$tfile.$i
19305                 touch $f || error "touch failed"
19306                 local count=$($LFS getstripe -c $f)
19307                 [ $count -eq $OSTCOUNT ] ||
19308                         error "$f stripe count $count != $OSTCOUNT"
19309                 local offset=$($LFS getstripe -i $f)
19310                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19311                 local size=$($LFS getstripe -S $f)
19312                 [ $size -eq $((def_stripe_size * 2)) ] ||
19313                         error "$f stripe size $size != $((def_stripe_size * 2))"
19314                 local pool=$($LFS getstripe -p $f)
19315                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19316         done
19317
19318         # change fs default striping, delete parent default striping, now child
19319         # will stripe from new fs default striping only
19320         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19321                 error "change $MOUNT default stripe failed"
19322         $LFS setstripe -c 0 $DIR/$tdir ||
19323                 error "delete $tdir default stripe failed"
19324         for i in $(seq 11 20); do
19325                 local f=$DIR/$tdir/$tfile.$i
19326                 touch $f || error "touch $f failed"
19327                 local count=$($LFS getstripe -c $f)
19328                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19329                 local offset=$($LFS getstripe -i $f)
19330                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19331                 local size=$($LFS getstripe -S $f)
19332                 [ $size -eq $def_stripe_size ] ||
19333                         error "$f stripe size $size != $def_stripe_size"
19334                 local pool=$($LFS getstripe -p $f)
19335                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19336         done
19337
19338         unlinkmany $DIR/$tdir/$tfile. 1 20
19339
19340         local f=$DIR/$tdir/$tfile
19341         pool_remove_all_targets $test_pool $f
19342         pool_remove $test_pool $f
19343
19344         if ! combined_mgs_mds ; then
19345                 umount_mgs_client
19346         fi
19347 }
19348 run_test 406 "DNE support fs default striping"
19349
19350 test_407() {
19351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19352         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19353                 skip "Need MDS version at least 2.8.55"
19354         remote_mds_nodsh && skip "remote MDS with nodsh"
19355
19356         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19357                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19358         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19359                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19360         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19361
19362         #define OBD_FAIL_DT_TXN_STOP    0x2019
19363         for idx in $(seq $MDSCOUNT); do
19364                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19365         done
19366         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19367         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19368                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19369         true
19370 }
19371 run_test 407 "transaction fail should cause operation fail"
19372
19373 test_408() {
19374         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19375
19376         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19377         lctl set_param fail_loc=0x8000040a
19378         # let ll_prepare_partial_page() fail
19379         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19380
19381         rm -f $DIR/$tfile
19382
19383         # create at least 100 unused inodes so that
19384         # shrink_icache_memory(0) should not return 0
19385         touch $DIR/$tfile-{0..100}
19386         rm -f $DIR/$tfile-{0..100}
19387         sync
19388
19389         echo 2 > /proc/sys/vm/drop_caches
19390 }
19391 run_test 408 "drop_caches should not hang due to page leaks"
19392
19393 test_409()
19394 {
19395         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19396
19397         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19398         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19399         touch $DIR/$tdir/guard || error "(2) Fail to create"
19400
19401         local PREFIX=$(str_repeat 'A' 128)
19402         echo "Create 1K hard links start at $(date)"
19403         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19404                 error "(3) Fail to hard link"
19405
19406         echo "Links count should be right although linkEA overflow"
19407         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19408         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19409         [ $linkcount -eq 1001 ] ||
19410                 error "(5) Unexpected hard links count: $linkcount"
19411
19412         echo "List all links start at $(date)"
19413         ls -l $DIR/$tdir/foo > /dev/null ||
19414                 error "(6) Fail to list $DIR/$tdir/foo"
19415
19416         echo "Unlink hard links start at $(date)"
19417         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19418                 error "(7) Fail to unlink"
19419         echo "Unlink hard links finished at $(date)"
19420 }
19421 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19422
19423 test_410()
19424 {
19425         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19426                 skip "Need client version at least 2.9.59"
19427
19428         # Create a file, and stat it from the kernel
19429         local testfile=$DIR/$tfile
19430         touch $testfile
19431
19432         local run_id=$RANDOM
19433         local my_ino=$(stat --format "%i" $testfile)
19434
19435         # Try to insert the module. This will always fail as the
19436         # module is designed to not be inserted.
19437         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19438             &> /dev/null
19439
19440         # Anything but success is a test failure
19441         dmesg | grep -q \
19442             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19443             error "no inode match"
19444 }
19445 run_test 410 "Test inode number returned from kernel thread"
19446
19447 cleanup_test411_cgroup() {
19448         trap 0
19449         rmdir "$1"
19450 }
19451
19452 test_411() {
19453         local cg_basedir=/sys/fs/cgroup/memory
19454         # LU-9966
19455         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19456                 skip "no setup for cgroup"
19457
19458         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19459                 error "test file creation failed"
19460         cancel_lru_locks osc
19461
19462         # Create a very small memory cgroup to force a slab allocation error
19463         local cgdir=$cg_basedir/osc_slab_alloc
19464         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19465         trap "cleanup_test411_cgroup $cgdir" EXIT
19466         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19467         echo 1M > $cgdir/memory.limit_in_bytes
19468
19469         # Should not LBUG, just be killed by oom-killer
19470         # dd will return 0 even allocation failure in some environment.
19471         # So don't check return value
19472         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19473         cleanup_test411_cgroup $cgdir
19474
19475         return 0
19476 }
19477 run_test 411 "Slab allocation error with cgroup does not LBUG"
19478
19479 test_412() {
19480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19481         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19482                 skip "Need server version at least 2.10.55"
19483         fi
19484
19485         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19486                 error "mkdir failed"
19487         $LFS getdirstripe $DIR/$tdir
19488         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19489         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19490                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19491         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19492         [ $stripe_count -eq 2 ] ||
19493                 error "expect 2 get $stripe_count"
19494 }
19495 run_test 412 "mkdir on specific MDTs"
19496
19497 test_413() {
19498         [ $MDSCOUNT -lt 2 ] &&
19499                 skip "We need at least 2 MDTs for this test"
19500
19501         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19502                 skip "Need server version at least 2.10.55"
19503         fi
19504
19505         mkdir $DIR/$tdir || error "mkdir failed"
19506
19507         # find MDT that is the most full
19508         local max=$($LFS df | grep MDT |
19509                 awk 'BEGIN { a=0 }
19510                         { sub("%", "", $5)
19511                           if (0+$5 >= a)
19512                           {
19513                                 a = $5
19514                                 b = $6
19515                           }
19516                         }
19517                      END { split(b, c, ":")
19518                            sub("]", "", c[2])
19519                            print c[2]
19520                          }')
19521
19522         for i in $(seq $((MDSCOUNT - 1))); do
19523                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19524                         error "mkdir d$i failed"
19525                 $LFS getdirstripe $DIR/$tdir/d$i
19526                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19527                 [ $stripe_index -ne $max ] ||
19528                         error "don't expect $max"
19529         done
19530 }
19531 run_test 413 "mkdir on less full MDTs"
19532
19533 test_414() {
19534 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19535         $LCTL set_param fail_loc=0x80000521
19536         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19537         rm -f $DIR/$tfile
19538 }
19539 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19540
19541 test_415() {
19542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19543         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19544                 skip "Need server version at least 2.11.52"
19545
19546         # LU-11102
19547         local total
19548         local setattr_pid
19549         local start_time
19550         local end_time
19551         local duration
19552
19553         total=500
19554         # this test may be slow on ZFS
19555         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19556
19557         # though this test is designed for striped directory, let's test normal
19558         # directory too since lock is always saved as CoS lock.
19559         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19560         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19561
19562         (
19563                 while true; do
19564                         touch $DIR/$tdir
19565                 done
19566         ) &
19567         setattr_pid=$!
19568
19569         start_time=$(date +%s)
19570         for i in $(seq $total); do
19571                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19572                         > /dev/null
19573         done
19574         end_time=$(date +%s)
19575         duration=$((end_time - start_time))
19576
19577         kill -9 $setattr_pid
19578
19579         echo "rename $total files took $duration sec"
19580         [ $duration -lt 100 ] || error "rename took $duration sec"
19581 }
19582 run_test 415 "lock revoke is not missing"
19583
19584 test_416() {
19585         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19586                 skip "Need server version at least 2.11.55"
19587
19588         # define OBD_FAIL_OSD_TXN_START    0x19a
19589         do_facet mds1 lctl set_param fail_loc=0x19a
19590
19591         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19592
19593         true
19594 }
19595 run_test 416 "transaction start failure won't cause system hung"
19596
19597 cleanup_417() {
19598         trap 0
19599         do_nodes $(comma_list $(mdts_nodes)) \
19600                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19601         do_nodes $(comma_list $(mdts_nodes)) \
19602                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19603         do_nodes $(comma_list $(mdts_nodes)) \
19604                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19605 }
19606
19607 test_417() {
19608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19609         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19610                 skip "Need MDS version at least 2.11.56"
19611
19612         trap cleanup_417 RETURN EXIT
19613
19614         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19615         do_nodes $(comma_list $(mdts_nodes)) \
19616                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19617         $LFS migrate -m 0 $DIR/$tdir.1 &&
19618                 error "migrate dir $tdir.1 should fail"
19619
19620         do_nodes $(comma_list $(mdts_nodes)) \
19621                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19622         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19623                 error "create remote dir $tdir.2 should fail"
19624
19625         do_nodes $(comma_list $(mdts_nodes)) \
19626                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19627         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19628                 error "create striped dir $tdir.3 should fail"
19629         true
19630 }
19631 run_test 417 "disable remote dir, striped dir and dir migration"
19632
19633 # Checks that the outputs of df [-i] and lfs df [-i] match
19634 #
19635 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19636 check_lfs_df() {
19637         local dir=$2
19638         local inodes
19639         local df_out
19640         local lfs_df_out
19641         local count
19642         local passed=false
19643
19644         # blocks or inodes
19645         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19646
19647         for count in {1..100}; do
19648                 cancel_lru_locks
19649                 sync; sleep 0.2
19650
19651                 # read the lines of interest
19652                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19653                         error "df $inodes $dir | tail -n +2 failed"
19654                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19655                         error "lfs df $inodes $dir | grep summary: failed"
19656
19657                 # skip first substrings of each output as they are different
19658                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19659                 # compare the two outputs
19660                 passed=true
19661                 for i in {1..5}; do
19662                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19663                 done
19664                 $passed && break
19665         done
19666
19667         if ! $passed; then
19668                 df -P $inodes $dir
19669                 echo
19670                 lfs df $inodes $dir
19671                 error "df and lfs df $1 output mismatch: "      \
19672                       "df ${inodes}: ${df_out[*]}, "            \
19673                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19674         fi
19675 }
19676
19677 test_418() {
19678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19679
19680         local dir=$DIR/$tdir
19681         local numfiles=$((RANDOM % 4096 + 2))
19682         local numblocks=$((RANDOM % 256 + 1))
19683
19684         wait_delete_completed
19685         test_mkdir $dir
19686
19687         # check block output
19688         check_lfs_df blocks $dir
19689         # check inode output
19690         check_lfs_df inodes $dir
19691
19692         # create a single file and retest
19693         echo "Creating a single file and testing"
19694         createmany -o $dir/$tfile- 1 &>/dev/null ||
19695                 error "creating 1 file in $dir failed"
19696         check_lfs_df blocks $dir
19697         check_lfs_df inodes $dir
19698
19699         # create a random number of files
19700         echo "Creating $((numfiles - 1)) files and testing"
19701         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19702                 error "creating $((numfiles - 1)) files in $dir failed"
19703
19704         # write a random number of blocks to the first test file
19705         echo "Writing $numblocks 4K blocks and testing"
19706         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19707                 count=$numblocks &>/dev/null ||
19708                 error "dd to $dir/${tfile}-0 failed"
19709
19710         # retest
19711         check_lfs_df blocks $dir
19712         check_lfs_df inodes $dir
19713
19714         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19715                 error "unlinking $numfiles files in $dir failed"
19716 }
19717 run_test 418 "df and lfs df outputs match"
19718
19719 test_419()
19720 {
19721         local dir=$DIR/$tdir
19722
19723         mkdir -p $dir
19724         touch $dir/file
19725
19726         cancel_lru_locks mdc
19727
19728         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19729         $LCTL set_param fail_loc=0x1410
19730         cat $dir/file
19731         $LCTL set_param fail_loc=0
19732         rm -rf $dir
19733 }
19734 run_test 419 "Verify open file by name doesn't crash kernel"
19735
19736 prep_801() {
19737         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19738         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19739                 skip "Need server version at least 2.9.55"
19740
19741         start_full_debug_logging
19742 }
19743
19744 post_801() {
19745         stop_full_debug_logging
19746 }
19747
19748 barrier_stat() {
19749         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19750                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19751                            awk '/The barrier for/ { print $7 }')
19752                 echo $st
19753         else
19754                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19755                 echo \'$st\'
19756         fi
19757 }
19758
19759 barrier_expired() {
19760         local expired
19761
19762         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19763                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19764                           awk '/will be expired/ { print $7 }')
19765         else
19766                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19767         fi
19768
19769         echo $expired
19770 }
19771
19772 test_801a() {
19773         prep_801
19774
19775         echo "Start barrier_freeze at: $(date)"
19776         #define OBD_FAIL_BARRIER_DELAY          0x2202
19777         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19778         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19779
19780         sleep 2
19781         local b_status=$(barrier_stat)
19782         echo "Got barrier status at: $(date)"
19783         [ "$b_status" = "'freezing_p1'" ] ||
19784                 error "(1) unexpected barrier status $b_status"
19785
19786         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19787         wait
19788         b_status=$(barrier_stat)
19789         [ "$b_status" = "'frozen'" ] ||
19790                 error "(2) unexpected barrier status $b_status"
19791
19792         local expired=$(barrier_expired)
19793         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19794         sleep $((expired + 3))
19795
19796         b_status=$(barrier_stat)
19797         [ "$b_status" = "'expired'" ] ||
19798                 error "(3) unexpected barrier status $b_status"
19799
19800         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19801                 error "(4) fail to freeze barrier"
19802
19803         b_status=$(barrier_stat)
19804         [ "$b_status" = "'frozen'" ] ||
19805                 error "(5) unexpected barrier status $b_status"
19806
19807         echo "Start barrier_thaw at: $(date)"
19808         #define OBD_FAIL_BARRIER_DELAY          0x2202
19809         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19810         do_facet mgs $LCTL barrier_thaw $FSNAME &
19811
19812         sleep 2
19813         b_status=$(barrier_stat)
19814         echo "Got barrier status at: $(date)"
19815         [ "$b_status" = "'thawing'" ] ||
19816                 error "(6) unexpected barrier status $b_status"
19817
19818         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19819         wait
19820         b_status=$(barrier_stat)
19821         [ "$b_status" = "'thawed'" ] ||
19822                 error "(7) unexpected barrier status $b_status"
19823
19824         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19825         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19826         do_facet mgs $LCTL barrier_freeze $FSNAME
19827
19828         b_status=$(barrier_stat)
19829         [ "$b_status" = "'failed'" ] ||
19830                 error "(8) unexpected barrier status $b_status"
19831
19832         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19833         do_facet mgs $LCTL barrier_thaw $FSNAME
19834
19835         post_801
19836 }
19837 run_test 801a "write barrier user interfaces and stat machine"
19838
19839 test_801b() {
19840         prep_801
19841
19842         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19843         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19844         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19845         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19846         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19847
19848         cancel_lru_locks mdc
19849
19850         # 180 seconds should be long enough
19851         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19852
19853         local b_status=$(barrier_stat)
19854         [ "$b_status" = "'frozen'" ] ||
19855                 error "(6) unexpected barrier status $b_status"
19856
19857         mkdir $DIR/$tdir/d0/d10 &
19858         mkdir_pid=$!
19859
19860         touch $DIR/$tdir/d1/f13 &
19861         touch_pid=$!
19862
19863         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19864         ln_pid=$!
19865
19866         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19867         mv_pid=$!
19868
19869         rm -f $DIR/$tdir/d4/f12 &
19870         rm_pid=$!
19871
19872         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19873
19874         # To guarantee taht the 'stat' is not blocked
19875         b_status=$(barrier_stat)
19876         [ "$b_status" = "'frozen'" ] ||
19877                 error "(8) unexpected barrier status $b_status"
19878
19879         # let above commands to run at background
19880         sleep 5
19881
19882         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19883         ps -p $touch_pid || error "(10) touch should be blocked"
19884         ps -p $ln_pid || error "(11) link should be blocked"
19885         ps -p $mv_pid || error "(12) rename should be blocked"
19886         ps -p $rm_pid || error "(13) unlink should be blocked"
19887
19888         b_status=$(barrier_stat)
19889         [ "$b_status" = "'frozen'" ] ||
19890                 error "(14) unexpected barrier status $b_status"
19891
19892         do_facet mgs $LCTL barrier_thaw $FSNAME
19893         b_status=$(barrier_stat)
19894         [ "$b_status" = "'thawed'" ] ||
19895                 error "(15) unexpected barrier status $b_status"
19896
19897         wait $mkdir_pid || error "(16) mkdir should succeed"
19898         wait $touch_pid || error "(17) touch should succeed"
19899         wait $ln_pid || error "(18) link should succeed"
19900         wait $mv_pid || error "(19) rename should succeed"
19901         wait $rm_pid || error "(20) unlink should succeed"
19902
19903         post_801
19904 }
19905 run_test 801b "modification will be blocked by write barrier"
19906
19907 test_801c() {
19908         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19909
19910         prep_801
19911
19912         stop mds2 || error "(1) Fail to stop mds2"
19913
19914         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19915
19916         local b_status=$(barrier_stat)
19917         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19918                 do_facet mgs $LCTL barrier_thaw $FSNAME
19919                 error "(2) unexpected barrier status $b_status"
19920         }
19921
19922         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19923                 error "(3) Fail to rescan barrier bitmap"
19924
19925         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19926
19927         b_status=$(barrier_stat)
19928         [ "$b_status" = "'frozen'" ] ||
19929                 error "(4) unexpected barrier status $b_status"
19930
19931         do_facet mgs $LCTL barrier_thaw $FSNAME
19932         b_status=$(barrier_stat)
19933         [ "$b_status" = "'thawed'" ] ||
19934                 error "(5) unexpected barrier status $b_status"
19935
19936         local devname=$(mdsdevname 2)
19937
19938         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19939
19940         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19941                 error "(7) Fail to rescan barrier bitmap"
19942
19943         post_801
19944 }
19945 run_test 801c "rescan barrier bitmap"
19946
19947 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19948 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19949 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19950
19951 cleanup_802a() {
19952         trap 0
19953
19954         stopall
19955         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19956         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19957         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19958         setupall
19959 }
19960
19961 test_802a() {
19962
19963         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19964         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19965                 skip "Need server version at least 2.9.55"
19966
19967         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19968
19969         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19970
19971         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19972                 error "(2) Fail to copy"
19973
19974         trap cleanup_802a EXIT
19975
19976         # sync by force before remount as readonly
19977         sync; sync_all_data; sleep 3; sync_all_data
19978
19979         stopall
19980
19981         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19982         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19983         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19984
19985         echo "Mount the server as read only"
19986         setupall server_only || error "(3) Fail to start servers"
19987
19988         echo "Mount client without ro should fail"
19989         mount_client $MOUNT &&
19990                 error "(4) Mount client without 'ro' should fail"
19991
19992         echo "Mount client with ro should succeed"
19993         mount_client $MOUNT ro ||
19994                 error "(5) Mount client with 'ro' should succeed"
19995
19996         echo "Modify should be refused"
19997         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19998
19999         echo "Read should be allowed"
20000         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20001                 error "(7) Read should succeed under ro mode"
20002
20003         cleanup_802a
20004 }
20005 run_test 802a "simulate readonly device"
20006
20007 test_802b() {
20008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20009         remote_mds_nodsh && skip "remote MDS with nodsh"
20010
20011         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20012                 skip "readonly option not available"
20013
20014         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20015
20016         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20017                 error "(2) Fail to copy"
20018
20019         # write back all cached data before setting MDT to readonly
20020         cancel_lru_locks
20021         sync_all_data
20022
20023         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20024         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20025
20026         echo "Modify should be refused"
20027         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20028
20029         echo "Read should be allowed"
20030         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20031                 error "(7) Read should succeed under ro mode"
20032
20033         # disable readonly
20034         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20035 }
20036 run_test 802b "be able to set MDTs to readonly"
20037
20038 test_803() {
20039         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20040         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20041                 skip "MDS needs to be newer than 2.10.54"
20042
20043         mkdir -p $DIR/$tdir
20044         # Create some objects on all MDTs to trigger related logs objects
20045         for idx in $(seq $MDSCOUNT); do
20046                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20047                         $DIR/$tdir/dir${idx} ||
20048                         error "Fail to create $DIR/$tdir/dir${idx}"
20049         done
20050
20051         sync; sleep 3
20052         wait_delete_completed # ensure old test cleanups are finished
20053         echo "before create:"
20054         $LFS df -i $MOUNT
20055         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20056
20057         for i in {1..10}; do
20058                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20059                         error "Fail to create $DIR/$tdir/foo$i"
20060         done
20061
20062         sync; sleep 3
20063         echo "after create:"
20064         $LFS df -i $MOUNT
20065         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20066
20067         # allow for an llog to be cleaned up during the test
20068         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20069                 error "before ($before_used) + 10 > after ($after_used)"
20070
20071         for i in {1..10}; do
20072                 rm -rf $DIR/$tdir/foo$i ||
20073                         error "Fail to remove $DIR/$tdir/foo$i"
20074         done
20075
20076         sleep 3 # avoid MDT return cached statfs
20077         wait_delete_completed
20078         echo "after unlink:"
20079         $LFS df -i $MOUNT
20080         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20081
20082         # allow for an llog to be created during the test
20083         [ $after_used -le $((before_used + 1)) ] ||
20084                 error "after ($after_used) > before ($before_used) + 1"
20085 }
20086 run_test 803 "verify agent object for remote object"
20087
20088 test_804() {
20089         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20090         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20091                 skip "MDS needs to be newer than 2.10.54"
20092         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20093
20094         mkdir -p $DIR/$tdir
20095         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20096                 error "Fail to create $DIR/$tdir/dir0"
20097
20098         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20099         local dev=$(mdsdevname 2)
20100
20101         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20102                 grep ${fid} || error "NOT found agent entry for dir0"
20103
20104         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20105                 error "Fail to create $DIR/$tdir/dir1"
20106
20107         touch $DIR/$tdir/dir1/foo0 ||
20108                 error "Fail to create $DIR/$tdir/dir1/foo0"
20109         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20110         local rc=0
20111
20112         for idx in $(seq $MDSCOUNT); do
20113                 dev=$(mdsdevname $idx)
20114                 do_facet mds${idx} \
20115                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20116                         grep ${fid} && rc=$idx
20117         done
20118
20119         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20120                 error "Fail to rename foo0 to foo1"
20121         if [ $rc -eq 0 ]; then
20122                 for idx in $(seq $MDSCOUNT); do
20123                         dev=$(mdsdevname $idx)
20124                         do_facet mds${idx} \
20125                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20126                         grep ${fid} && rc=$idx
20127                 done
20128         fi
20129
20130         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20131                 error "Fail to rename foo1 to foo2"
20132         if [ $rc -eq 0 ]; then
20133                 for idx in $(seq $MDSCOUNT); do
20134                         dev=$(mdsdevname $idx)
20135                         do_facet mds${idx} \
20136                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20137                         grep ${fid} && rc=$idx
20138                 done
20139         fi
20140
20141         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20142
20143         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20144                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20145         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20146                 error "Fail to rename foo2 to foo0"
20147         unlink $DIR/$tdir/dir1/foo0 ||
20148                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20149         rm -rf $DIR/$tdir/dir0 ||
20150                 error "Fail to rm $DIR/$tdir/dir0"
20151
20152         for idx in $(seq $MDSCOUNT); do
20153                 dev=$(mdsdevname $idx)
20154                 rc=0
20155
20156                 stop mds${idx}
20157                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20158                         rc=$?
20159                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20160                         error "mount mds$idx failed"
20161                 df $MOUNT > /dev/null 2>&1
20162
20163                 # e2fsck should not return error
20164                 [ $rc -eq 0 ] ||
20165                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20166         done
20167 }
20168 run_test 804 "verify agent entry for remote entry"
20169
20170 cleanup_805() {
20171         do_facet $SINGLEMDS zfs set quota=$old $fsset
20172         unlinkmany $DIR/$tdir/f- 1000000
20173         trap 0
20174 }
20175
20176 test_805() {
20177         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20178         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20179         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20180                 skip "netfree not implemented before 0.7"
20181         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20182                 skip "Need MDS version at least 2.10.57"
20183
20184         local fsset
20185         local freekb
20186         local usedkb
20187         local old
20188         local quota
20189         local pref="osd-zfs.lustre-MDT0000."
20190
20191         # limit available space on MDS dataset to meet nospace issue
20192         # quickly. then ZFS 0.7.2 can use reserved space if asked
20193         # properly (using netfree flag in osd_declare_destroy()
20194         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20195         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20196                 gawk '{print $3}')
20197         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20198         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20199         let "usedkb=usedkb-freekb"
20200         let "freekb=freekb/2"
20201         if let "freekb > 5000"; then
20202                 let "freekb=5000"
20203         fi
20204         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20205         trap cleanup_805 EXIT
20206         mkdir $DIR/$tdir
20207         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20208         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20209         rm -rf $DIR/$tdir || error "not able to remove"
20210         do_facet $SINGLEMDS zfs set quota=$old $fsset
20211         trap 0
20212 }
20213 run_test 805 "ZFS can remove from full fs"
20214
20215 # Size-on-MDS test
20216 check_lsom_data()
20217 {
20218         local file=$1
20219         local size=$($LFS getsom -s $file)
20220         local expect=$(stat -c %s $file)
20221
20222         [[ $size == $expect ]] ||
20223                 error "$file expected size: $expect, got: $size"
20224
20225         local blocks=$($LFS getsom -b $file)
20226         expect=$(stat -c %b $file)
20227         [[ $blocks == $expect ]] ||
20228                 error "$file expected blocks: $expect, got: $blocks"
20229 }
20230
20231 check_lsom_size()
20232 {
20233         local size=$($LFS getsom -s $1)
20234         local expect=$2
20235
20236         [[ $size == $expect ]] ||
20237                 error "$file expected size: $expect, got: $size"
20238 }
20239
20240 test_806() {
20241         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20242                 skip "Need MDS version at least 2.11.52"
20243
20244         local bs=1048576
20245
20246         touch $DIR/$tfile || error "touch $tfile failed"
20247
20248         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20249         save_lustre_params client "llite.*.xattr_cache" > $save
20250         lctl set_param llite.*.xattr_cache=0
20251         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20252
20253         # single-threaded write
20254         echo "Test SOM for single-threaded write"
20255         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20256                 error "write $tfile failed"
20257         check_lsom_size $DIR/$tfile $bs
20258
20259         local num=32
20260         local size=$(($num * $bs))
20261         local offset=0
20262         local i
20263
20264         echo "Test SOM for single client multi-threaded($num) write"
20265         $TRUNCATE $DIR/$tfile 0
20266         for ((i = 0; i < $num; i++)); do
20267                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20268                 local pids[$i]=$!
20269                 offset=$((offset + $bs))
20270         done
20271         for (( i=0; i < $num; i++ )); do
20272                 wait ${pids[$i]}
20273         done
20274         check_lsom_size $DIR/$tfile $size
20275
20276         $TRUNCATE $DIR/$tfile 0
20277         for ((i = 0; i < $num; i++)); do
20278                 offset=$((offset - $bs))
20279                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20280                 local pids[$i]=$!
20281         done
20282         for (( i=0; i < $num; i++ )); do
20283                 wait ${pids[$i]}
20284         done
20285         check_lsom_size $DIR/$tfile $size
20286
20287         # multi-client wirtes
20288         num=$(get_node_count ${CLIENTS//,/ })
20289         size=$(($num * $bs))
20290         offset=0
20291         i=0
20292
20293         echo "Test SOM for multi-client ($num) writes"
20294         $TRUNCATE $DIR/$tfile 0
20295         for client in ${CLIENTS//,/ }; do
20296                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20297                 local pids[$i]=$!
20298                 i=$((i + 1))
20299                 offset=$((offset + $bs))
20300         done
20301         for (( i=0; i < $num; i++ )); do
20302                 wait ${pids[$i]}
20303         done
20304         check_lsom_size $DIR/$tfile $offset
20305
20306         i=0
20307         $TRUNCATE $DIR/$tfile 0
20308         for client in ${CLIENTS//,/ }; do
20309                 offset=$((offset - $bs))
20310                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20311                 local pids[$i]=$!
20312                 i=$((i + 1))
20313         done
20314         for (( i=0; i < $num; i++ )); do
20315                 wait ${pids[$i]}
20316         done
20317         check_lsom_size $DIR/$tfile $size
20318
20319         # verify truncate
20320         echo "Test SOM for truncate"
20321         $TRUNCATE $DIR/$tfile 1048576
20322         check_lsom_size $DIR/$tfile 1048576
20323         $TRUNCATE $DIR/$tfile 1234
20324         check_lsom_size $DIR/$tfile 1234
20325
20326         # verify SOM blocks count
20327         echo "Verify SOM block count"
20328         $TRUNCATE $DIR/$tfile 0
20329         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20330                 error "failed to write file $tfile"
20331         check_lsom_data $DIR/$tfile
20332 }
20333 run_test 806 "Verify Lazy Size on MDS"
20334
20335 test_807() {
20336         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20337         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20338                 skip "Need MDS version at least 2.11.52"
20339
20340         # Registration step
20341         changelog_register || error "changelog_register failed"
20342         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20343         changelog_users $SINGLEMDS | grep -q $cl_user ||
20344                 error "User $cl_user not found in changelog_users"
20345
20346         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20347         save_lustre_params client "llite.*.xattr_cache" > $save
20348         lctl set_param llite.*.xattr_cache=0
20349         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20350
20351         rm -rf $DIR/$tdir || error "rm $tdir failed"
20352         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20353         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20354         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20355         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20356                 error "truncate $tdir/trunc failed"
20357
20358         local bs=1048576
20359         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20360                 error "write $tfile failed"
20361
20362         # multi-client wirtes
20363         local num=$(get_node_count ${CLIENTS//,/ })
20364         local offset=0
20365         local i=0
20366
20367         echo "Test SOM for multi-client ($num) writes"
20368         touch $DIR/$tfile || error "touch $tfile failed"
20369         $TRUNCATE $DIR/$tfile 0
20370         for client in ${CLIENTS//,/ }; do
20371                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20372                 local pids[$i]=$!
20373                 i=$((i + 1))
20374                 offset=$((offset + $bs))
20375         done
20376         for (( i=0; i < $num; i++ )); do
20377                 wait ${pids[$i]}
20378         done
20379
20380         sleep 5
20381         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20382         check_lsom_data $DIR/$tdir/trunc
20383         check_lsom_data $DIR/$tdir/single_dd
20384         check_lsom_data $DIR/$tfile
20385
20386         rm -rf $DIR/$tdir
20387         # Deregistration step
20388         changelog_deregister || error "changelog_deregister failed"
20389 }
20390 run_test 807 "verify LSOM syncing tool"
20391
20392 check_som_nologged()
20393 {
20394         local lines=$($LFS changelog $FSNAME-MDT0000 |
20395                 grep 'x=trusted.som' | wc -l)
20396         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20397 }
20398
20399 test_808() {
20400         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20401                 skip "Need MDS version at least 2.11.55"
20402
20403         # Registration step
20404         changelog_register || error "changelog_register failed"
20405
20406         touch $DIR/$tfile || error "touch $tfile failed"
20407         check_som_nologged
20408
20409         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20410                 error "write $tfile failed"
20411         check_som_nologged
20412
20413         $TRUNCATE $DIR/$tfile 1234
20414         check_som_nologged
20415
20416         $TRUNCATE $DIR/$tfile 1048576
20417         check_som_nologged
20418
20419         # Deregistration step
20420         changelog_deregister || error "changelog_deregister failed"
20421 }
20422 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20423
20424 check_som_nodata()
20425 {
20426         $LFS getsom $1
20427         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20428 }
20429
20430 test_809() {
20431         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20432                 skip "Need MDS version at least 2.11.56"
20433
20434         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20435                 error "failed to create DoM-only file $DIR/$tfile"
20436         touch $DIR/$tfile || error "touch $tfile failed"
20437         check_som_nodata $DIR/$tfile
20438
20439         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20440                 error "write $tfile failed"
20441         check_som_nodata $DIR/$tfile
20442
20443         $TRUNCATE $DIR/$tfile 1234
20444         check_som_nodata $DIR/$tfile
20445
20446         $TRUNCATE $DIR/$tfile 4097
20447         check_som_nodata $DIR/$file
20448 }
20449 run_test 809 "Verify no SOM xattr store for DoM-only files"
20450
20451 test_810() {
20452         local ORIG
20453         local CSUM
20454
20455         # t10 seem to dislike partial pages
20456         lctl set_param osc.*.checksum_type=adler
20457         lctl set_param fail_loc=0x411
20458         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20459         ORIG=$(md5sum $DIR/$tfile)
20460         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20461         CSUM=$(md5sum $DIR/$tfile)
20462         set_checksum_type adler
20463         if [ "$ORIG" != "$CSUM" ]; then
20464                 error "$ORIG != $CSUM"
20465         fi
20466 }
20467 run_test 810 "partial page writes on ZFS (LU-11663)"
20468
20469 test_811() {
20470         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20471                 skip "Need MDS version at least 2.11.56"
20472
20473         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20474         do_facet mds1 $LCTL set_param fail_loc=0x165
20475         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20476
20477         stop mds1
20478         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20479
20480         sleep 5
20481         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20482                 error "MDD orphan cleanup thread not quit"
20483 }
20484 run_test 811 "orphan name stub can be cleaned up in startup"
20485
20486 test_812() {
20487         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20488                 skip "OST < 2.12.51 doesn't support this fail_loc"
20489
20490         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20491         # ensure ost1 is connected
20492         stat $DIR/$tfile >/dev/null || error "can't stat"
20493         wait_osc_import_state client ost1 FULL
20494         # no locks, no reqs to let the connection idle
20495         cancel_lru_locks osc
20496
20497         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20498 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20499         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20500         wait_osc_import_state client ost1 CONNECTING
20501         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20502
20503         stat $DIR/$tfile >/dev/null || error "can't stat file"
20504 }
20505 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20506
20507 test_813() {
20508         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20509         [ -z "$file_heat_sav" ] && skip "no file heat support"
20510
20511         local readsample
20512         local writesample
20513         local readbyte
20514         local writebyte
20515         local readsample1
20516         local writesample1
20517         local readbyte1
20518         local writebyte1
20519
20520         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20521         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20522
20523         $LCTL set_param -n llite.*.file_heat=1
20524         echo "Turn on file heat"
20525         echo "Period second: $period_second, Decay percentage: $decay_pct"
20526
20527         echo "QQQQ" > $DIR/$tfile
20528         echo "QQQQ" > $DIR/$tfile
20529         echo "QQQQ" > $DIR/$tfile
20530         cat $DIR/$tfile > /dev/null
20531         cat $DIR/$tfile > /dev/null
20532         cat $DIR/$tfile > /dev/null
20533         cat $DIR/$tfile > /dev/null
20534
20535         local out=$($LFS heat_get $DIR/$tfile)
20536
20537         $LFS heat_get $DIR/$tfile
20538         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20539         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20540         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20541         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20542
20543         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20544         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20545         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20546         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20547
20548         sleep $((period_second + 3))
20549         echo "Sleep $((period_second + 3)) seconds..."
20550         # The recursion formula to calculate the heat of the file f is as
20551         # follow:
20552         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20553         # Where Hi is the heat value in the period between time points i*I and
20554         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20555         # to the weight of Ci.
20556         out=$($LFS heat_get $DIR/$tfile)
20557         $LFS heat_get $DIR/$tfile
20558         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20559         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20560         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20561         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20562
20563         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20564                 error "read sample ($readsample) is wrong"
20565         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20566                 error "write sample ($writesample) is wrong"
20567         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20568                 error "read bytes ($readbyte) is wrong"
20569         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20570                 error "write bytes ($writebyte) is wrong"
20571
20572         echo "QQQQ" > $DIR/$tfile
20573         echo "QQQQ" > $DIR/$tfile
20574         echo "QQQQ" > $DIR/$tfile
20575         cat $DIR/$tfile > /dev/null
20576         cat $DIR/$tfile > /dev/null
20577         cat $DIR/$tfile > /dev/null
20578         cat $DIR/$tfile > /dev/null
20579
20580         sleep $((period_second + 3))
20581         echo "Sleep $((period_second + 3)) seconds..."
20582
20583         out=$($LFS heat_get $DIR/$tfile)
20584         $LFS heat_get $DIR/$tfile
20585         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20586         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20587         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20588         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20589
20590         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20591                 4 * $decay_pct) / 100") -eq 1 ] ||
20592                 error "read sample ($readsample1) is wrong"
20593         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20594                 3 * $decay_pct) / 100") -eq 1 ] ||
20595                 error "write sample ($writesample1) is wrong"
20596         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20597                 20 * $decay_pct) / 100") -eq 1 ] ||
20598                 error "read bytes ($readbyte1) is wrong"
20599         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20600                 15 * $decay_pct) / 100") -eq 1 ] ||
20601                 error "write bytes ($writebyte1) is wrong"
20602
20603         echo "Turn off file heat for the file $DIR/$tfile"
20604         $LFS heat_set -o $DIR/$tfile
20605
20606         echo "QQQQ" > $DIR/$tfile
20607         echo "QQQQ" > $DIR/$tfile
20608         echo "QQQQ" > $DIR/$tfile
20609         cat $DIR/$tfile > /dev/null
20610         cat $DIR/$tfile > /dev/null
20611         cat $DIR/$tfile > /dev/null
20612         cat $DIR/$tfile > /dev/null
20613
20614         out=$($LFS heat_get $DIR/$tfile)
20615         $LFS heat_get $DIR/$tfile
20616         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20617         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20618         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20619         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20620
20621         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20622         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20623         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20624         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20625
20626         echo "Trun on file heat for the file $DIR/$tfile"
20627         $LFS heat_set -O $DIR/$tfile
20628
20629         echo "QQQQ" > $DIR/$tfile
20630         echo "QQQQ" > $DIR/$tfile
20631         echo "QQQQ" > $DIR/$tfile
20632         cat $DIR/$tfile > /dev/null
20633         cat $DIR/$tfile > /dev/null
20634         cat $DIR/$tfile > /dev/null
20635         cat $DIR/$tfile > /dev/null
20636
20637         out=$($LFS heat_get $DIR/$tfile)
20638         $LFS heat_get $DIR/$tfile
20639         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20640         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20641         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20642         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20643
20644         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20645         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20646         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20647         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20648
20649         $LFS heat_set -c $DIR/$tfile
20650         $LCTL set_param -n llite.*.file_heat=0
20651         echo "Turn off file heat support for the Lustre filesystem"
20652
20653         echo "QQQQ" > $DIR/$tfile
20654         echo "QQQQ" > $DIR/$tfile
20655         echo "QQQQ" > $DIR/$tfile
20656         cat $DIR/$tfile > /dev/null
20657         cat $DIR/$tfile > /dev/null
20658         cat $DIR/$tfile > /dev/null
20659         cat $DIR/$tfile > /dev/null
20660
20661         out=$($LFS heat_get $DIR/$tfile)
20662         $LFS heat_get $DIR/$tfile
20663         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20664         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20665         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20666         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20667
20668         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20669         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20670         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20671         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20672
20673         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20674         rm -f $DIR/$tfile
20675 }
20676 run_test 813 "File heat verfication"
20677
20678 #
20679 # tests that do cleanup/setup should be run at the end
20680 #
20681
20682 test_900() {
20683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20684         local ls
20685
20686         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20687         $LCTL set_param fail_loc=0x903
20688
20689         cancel_lru_locks MGC
20690
20691         FAIL_ON_ERROR=true cleanup
20692         FAIL_ON_ERROR=true setup
20693 }
20694 run_test 900 "umount should not race with any mgc requeue thread"
20695
20696 complete $SECONDS
20697 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20698 check_and_cleanup_lustre
20699 if [ "$I_MOUNTED" != "yes" ]; then
20700         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20701 fi
20702 exit_status