Whamcloud - gitweb
LU-12261 tests: Race between exec and truncate
[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         # Make sure exec of $tdir/sleep wins race with truncate
4163         sleep 1
4164         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4165         kill $SLEEP_PID
4166 }
4167 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4168
4169 test_43b() {
4170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4171
4172         test_mkdir $DIR/$tdir
4173         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4174         $DIR/$tdir/sleep 60 &
4175         SLEEP_PID=$!
4176         # Make sure exec of $tdir/sleep wins race with truncate
4177         sleep 1
4178         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4179         kill $SLEEP_PID
4180 }
4181 run_test 43b "truncate of file being executed should return -ETXTBSY"
4182
4183 test_43c() {
4184         local testdir="$DIR/$tdir"
4185         test_mkdir $testdir
4186         cp $SHELL $testdir/
4187         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4188                 ( cd $testdir && md5sum -c )
4189 }
4190 run_test 43c "md5sum of copy into lustre"
4191
4192 test_44A() { # was test_44
4193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4194
4195         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4196         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4197 }
4198 run_test 44A "zero length read from a sparse stripe"
4199
4200 test_44a() {
4201         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4202                 awk '{ print $2 }')
4203         [ -z "$nstripe" ] && skip "can't get stripe info"
4204         [[ $nstripe -gt $OSTCOUNT ]] &&
4205                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4206
4207         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4208                 awk '{ print $2 }')
4209         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4210                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4211                         awk '{ print $2 }')
4212         fi
4213
4214         OFFSETS="0 $((stride/2)) $((stride-1))"
4215         for offset in $OFFSETS; do
4216                 for i in $(seq 0 $((nstripe-1))); do
4217                         local GLOBALOFFSETS=""
4218                         # size in Bytes
4219                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4220                         local myfn=$DIR/d44a-$size
4221                         echo "--------writing $myfn at $size"
4222                         ll_sparseness_write $myfn $size ||
4223                                 error "ll_sparseness_write"
4224                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4225                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4226                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4227
4228                         for j in $(seq 0 $((nstripe-1))); do
4229                                 # size in Bytes
4230                                 size=$((((j + $nstripe )*$stride + $offset)))
4231                                 ll_sparseness_write $myfn $size ||
4232                                         error "ll_sparseness_write"
4233                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4234                         done
4235                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4236                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4237                         rm -f $myfn
4238                 done
4239         done
4240 }
4241 run_test 44a "test sparse pwrite ==============================="
4242
4243 dirty_osc_total() {
4244         tot=0
4245         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4246                 tot=$(($tot + $d))
4247         done
4248         echo $tot
4249 }
4250 do_dirty_record() {
4251         before=`dirty_osc_total`
4252         echo executing "\"$*\""
4253         eval $*
4254         after=`dirty_osc_total`
4255         echo before $before, after $after
4256 }
4257 test_45() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259
4260         f="$DIR/f45"
4261         # Obtain grants from OST if it supports it
4262         echo blah > ${f}_grant
4263         stop_writeback
4264         sync
4265         do_dirty_record "echo blah > $f"
4266         [[ $before -eq $after ]] && error "write wasn't cached"
4267         do_dirty_record "> $f"
4268         [[ $before -gt $after ]] || error "truncate 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 "sync"
4272         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4273         do_dirty_record "echo blah > $f"
4274         [[ $before -eq $after ]] && error "write wasn't cached"
4275         do_dirty_record "cancel_lru_locks osc"
4276         [[ $before -gt $after ]] ||
4277                 error "lock cancellation didn't lower dirty count"
4278         start_writeback
4279 }
4280 run_test 45 "osc io page accounting ============================"
4281
4282 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4283 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4284 # objects offset and an assert hit when an rpc was built with 1023's mapped
4285 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4286 test_46() {
4287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4288
4289         f="$DIR/f46"
4290         stop_writeback
4291         sync
4292         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4293         sync
4294         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4295         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4296         sync
4297         start_writeback
4298 }
4299 run_test 46 "dirtying a previously written page ================"
4300
4301 # test_47 is removed "Device nodes check" is moved to test_28
4302
4303 test_48a() { # bug 2399
4304         [ "$mds1_FSTYPE" = "zfs" ] &&
4305         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4306                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4307
4308         test_mkdir $DIR/$tdir
4309         cd $DIR/$tdir
4310         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4311         test_mkdir $DIR/$tdir
4312         touch foo || error "'touch foo' failed after recreating cwd"
4313         test_mkdir bar
4314         touch .foo || error "'touch .foo' failed after recreating cwd"
4315         test_mkdir .bar
4316         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4317         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4318         cd . || error "'cd .' failed after recreating cwd"
4319         mkdir . && error "'mkdir .' worked after recreating cwd"
4320         rmdir . && error "'rmdir .' worked after recreating cwd"
4321         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4322         cd .. || error "'cd ..' failed after recreating cwd"
4323 }
4324 run_test 48a "Access renamed working dir (should return errors)="
4325
4326 test_48b() { # bug 2399
4327         rm -rf $DIR/$tdir
4328         test_mkdir $DIR/$tdir
4329         cd $DIR/$tdir
4330         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4331         touch foo && error "'touch foo' worked after removing cwd"
4332         mkdir foo && error "'mkdir foo' worked after removing cwd"
4333         touch .foo && error "'touch .foo' worked after removing cwd"
4334         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4335         ls . > /dev/null && error "'ls .' worked after removing cwd"
4336         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4337         mkdir . && error "'mkdir .' worked after removing cwd"
4338         rmdir . && error "'rmdir .' worked after removing cwd"
4339         ln -s . foo && error "'ln -s .' worked after removing cwd"
4340         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4341 }
4342 run_test 48b "Access removed working dir (should return errors)="
4343
4344 test_48c() { # bug 2350
4345         #lctl set_param debug=-1
4346         #set -vx
4347         rm -rf $DIR/$tdir
4348         test_mkdir -p $DIR/$tdir/dir
4349         cd $DIR/$tdir/dir
4350         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4351         $TRACE touch foo && error "touch foo worked after removing cwd"
4352         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4353         touch .foo && error "touch .foo worked after removing cwd"
4354         mkdir .foo && error "mkdir .foo worked after removing cwd"
4355         $TRACE ls . && error "'ls .' worked after removing cwd"
4356         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4357         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4358         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4359         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4360         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4361 }
4362 run_test 48c "Access removed working subdir (should return errors)"
4363
4364 test_48d() { # bug 2350
4365         #lctl set_param debug=-1
4366         #set -vx
4367         rm -rf $DIR/$tdir
4368         test_mkdir -p $DIR/$tdir/dir
4369         cd $DIR/$tdir/dir
4370         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4371         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4372         $TRACE touch foo && error "'touch foo' worked after removing parent"
4373         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4374         touch .foo && error "'touch .foo' worked after removing parent"
4375         mkdir .foo && error "mkdir .foo worked after removing parent"
4376         $TRACE ls . && error "'ls .' worked after removing parent"
4377         $TRACE ls .. && error "'ls ..' worked after removing parent"
4378         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4379         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4380         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4381         true
4382 }
4383 run_test 48d "Access removed parent subdir (should return errors)"
4384
4385 test_48e() { # bug 4134
4386         #lctl set_param debug=-1
4387         #set -vx
4388         rm -rf $DIR/$tdir
4389         test_mkdir -p $DIR/$tdir/dir
4390         cd $DIR/$tdir/dir
4391         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4392         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4393         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4394         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4395         # On a buggy kernel addition of "touch foo" after cd .. will
4396         # produce kernel oops in lookup_hash_it
4397         touch ../foo && error "'cd ..' worked after recreate parent"
4398         cd $DIR
4399         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4400 }
4401 run_test 48e "Access to recreated parent subdir (should return errors)"
4402
4403 test_49() { # LU-1030
4404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4405         remote_ost_nodsh && skip "remote OST with nodsh"
4406
4407         # get ost1 size - lustre-OST0000
4408         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4409                 awk '{ print $4 }')
4410         # write 800M at maximum
4411         [[ $ost1_size -lt 2 ]] && ost1_size=2
4412         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4413
4414         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4415         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4416         local dd_pid=$!
4417
4418         # change max_pages_per_rpc while writing the file
4419         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4420         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4421         # loop until dd process exits
4422         while ps ax -opid | grep -wq $dd_pid; do
4423                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4424                 sleep $((RANDOM % 5 + 1))
4425         done
4426         # restore original max_pages_per_rpc
4427         $LCTL set_param $osc1_mppc=$orig_mppc
4428         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4429 }
4430 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4431
4432 test_50() {
4433         # bug 1485
4434         test_mkdir $DIR/$tdir
4435         cd $DIR/$tdir
4436         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4437 }
4438 run_test 50 "special situations: /proc symlinks  ==============="
4439
4440 test_51a() {    # was test_51
4441         # bug 1516 - create an empty entry right after ".." then split dir
4442         test_mkdir -c1 $DIR/$tdir
4443         touch $DIR/$tdir/foo
4444         $MCREATE $DIR/$tdir/bar
4445         rm $DIR/$tdir/foo
4446         createmany -m $DIR/$tdir/longfile 201
4447         FNUM=202
4448         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4449                 $MCREATE $DIR/$tdir/longfile$FNUM
4450                 FNUM=$(($FNUM + 1))
4451                 echo -n "+"
4452         done
4453         echo
4454         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4455 }
4456 run_test 51a "special situations: split htree with empty entry =="
4457
4458 cleanup_print_lfs_df () {
4459         trap 0
4460         $LFS df
4461         $LFS df -i
4462 }
4463
4464 test_51b() {
4465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4466
4467         local dir=$DIR/$tdir
4468         local nrdirs=$((65536 + 100))
4469
4470         # cleanup the directory
4471         rm -fr $dir
4472
4473         test_mkdir -c1 $dir
4474
4475         $LFS df
4476         $LFS df -i
4477         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4478         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4479         [[ $numfree -lt $nrdirs ]] &&
4480                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4481
4482         # need to check free space for the directories as well
4483         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4484         numfree=$(( blkfree / $(fs_inode_ksize) ))
4485         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4486
4487         trap cleanup_print_lfs_df EXIT
4488
4489         # create files
4490         createmany -d $dir/d $nrdirs || {
4491                 unlinkmany $dir/d $nrdirs
4492                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4493         }
4494
4495         # really created :
4496         nrdirs=$(ls -U $dir | wc -l)
4497
4498         # unlink all but 100 subdirectories, then check it still works
4499         local left=100
4500         local delete=$((nrdirs - left))
4501
4502         $LFS df
4503         $LFS df -i
4504
4505         # for ldiskfs the nlink count should be 1, but this is OSD specific
4506         # and so this is listed for informational purposes only
4507         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4508         unlinkmany -d $dir/d $delete ||
4509                 error "unlink of first $delete subdirs failed"
4510
4511         echo "nlink between: $(stat -c %h $dir)"
4512         local found=$(ls -U $dir | wc -l)
4513         [ $found -ne $left ] &&
4514                 error "can't find subdirs: found only $found, expected $left"
4515
4516         unlinkmany -d $dir/d $delete $left ||
4517                 error "unlink of second $left subdirs failed"
4518         # regardless of whether the backing filesystem tracks nlink accurately
4519         # or not, the nlink count shouldn't be more than "." and ".." here
4520         local after=$(stat -c %h $dir)
4521         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4522                 echo "nlink after: $after"
4523
4524         cleanup_print_lfs_df
4525 }
4526 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4527
4528 test_51d() {
4529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4530         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4531
4532         test_mkdir $DIR/$tdir
4533         createmany -o $DIR/$tdir/t- 1000
4534         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4535         for N in $(seq 0 $((OSTCOUNT - 1))); do
4536                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4537                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4538                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4539                         '($1 == '$N') { objs += 1 } \
4540                         END { printf("%0.0f", objs) }')
4541                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4542         done
4543         unlinkmany $DIR/$tdir/t- 1000
4544
4545         NLAST=0
4546         for N in $(seq 1 $((OSTCOUNT - 1))); do
4547                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4548                         error "OST $N has less objects vs OST $NLAST" \
4549                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4550                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4551                         error "OST $N has less objects vs OST $NLAST" \
4552                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4553
4554                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4555                         error "OST $N has less #0 objects vs OST $NLAST" \
4556                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4557                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4558                         error "OST $N has less #0 objects vs OST $NLAST" \
4559                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4560                 NLAST=$N
4561         done
4562         rm -f $TMP/$tfile
4563 }
4564 run_test 51d "check object distribution"
4565
4566 test_51e() {
4567         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4568                 skip_env "ldiskfs only test"
4569         fi
4570
4571         test_mkdir -c1 $DIR/$tdir
4572         test_mkdir -c1 $DIR/$tdir/d0
4573
4574         touch $DIR/$tdir/d0/foo
4575         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4576                 error "file exceed 65000 nlink limit!"
4577         unlinkmany $DIR/$tdir/d0/f- 65001
4578         return 0
4579 }
4580 run_test 51e "check file nlink limit"
4581
4582 test_51f() {
4583         test_mkdir $DIR/$tdir
4584
4585         local max=100000
4586         local ulimit_old=$(ulimit -n)
4587         local spare=20 # number of spare fd's for scripts/libraries, etc.
4588         local mdt=$($LFS getstripe -m $DIR/$tdir)
4589         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4590
4591         echo "MDT$mdt numfree=$numfree, max=$max"
4592         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4593         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4594                 while ! ulimit -n $((numfree + spare)); do
4595                         numfree=$((numfree * 3 / 4))
4596                 done
4597                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4598         else
4599                 echo "left ulimit at $ulimit_old"
4600         fi
4601
4602         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4603                 unlinkmany $DIR/$tdir/f $numfree
4604                 error "create+open $numfree files in $DIR/$tdir failed"
4605         }
4606         ulimit -n $ulimit_old
4607
4608         # if createmany exits at 120s there will be fewer than $numfree files
4609         unlinkmany $DIR/$tdir/f $numfree || true
4610 }
4611 run_test 51f "check many open files limit"
4612
4613 test_52a() {
4614         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4615         test_mkdir $DIR/$tdir
4616         touch $DIR/$tdir/foo
4617         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4618         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4619         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4620         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4621         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4622                                         error "link worked"
4623         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4624         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4625         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4626                                                      error "lsattr"
4627         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4628         cp -r $DIR/$tdir $TMP/
4629         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4630 }
4631 run_test 52a "append-only flag test (should return errors)"
4632
4633 test_52b() {
4634         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4635         test_mkdir $DIR/$tdir
4636         touch $DIR/$tdir/foo
4637         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4638         cat test > $DIR/$tdir/foo && error "cat test worked"
4639         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4640         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4641         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4642                                         error "link worked"
4643         echo foo >> $DIR/$tdir/foo && error "echo worked"
4644         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4645         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4646         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4647         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4648                                                         error "lsattr"
4649         chattr -i $DIR/$tdir/foo || error "chattr failed"
4650
4651         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4652 }
4653 run_test 52b "immutable flag test (should return errors) ======="
4654
4655 test_53() {
4656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4657         remote_mds_nodsh && skip "remote MDS with nodsh"
4658         remote_ost_nodsh && skip "remote OST with nodsh"
4659
4660         local param
4661         local param_seq
4662         local ostname
4663         local mds_last
4664         local mds_last_seq
4665         local ost_last
4666         local ost_last_seq
4667         local ost_last_id
4668         local ostnum
4669         local node
4670         local found=false
4671         local support_last_seq=true
4672
4673         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4674                 support_last_seq=false
4675
4676         # only test MDT0000
4677         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4678         local value
4679         for value in $(do_facet $SINGLEMDS \
4680                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4681                 param=$(echo ${value[0]} | cut -d "=" -f1)
4682                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4683
4684                 if $support_last_seq; then
4685                         param_seq=$(echo $param |
4686                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4687                         mds_last_seq=$(do_facet $SINGLEMDS \
4688                                        $LCTL get_param -n $param_seq)
4689                 fi
4690                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4691
4692                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4693                 node=$(facet_active_host ost$((ostnum+1)))
4694                 param="obdfilter.$ostname.last_id"
4695                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4696                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4697                         ost_last_id=$ost_last
4698
4699                         if $support_last_seq; then
4700                                 ost_last_id=$(echo $ost_last |
4701                                               awk -F':' '{print $2}' |
4702                                               sed -e "s/^0x//g")
4703                                 ost_last_seq=$(echo $ost_last |
4704                                                awk -F':' '{print $1}')
4705                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4706                         fi
4707
4708                         if [[ $ost_last_id != $mds_last ]]; then
4709                                 error "$ost_last_id != $mds_last"
4710                         else
4711                                 found=true
4712                                 break
4713                         fi
4714                 done
4715         done
4716         $found || error "can not match last_seq/last_id for $mdtosc"
4717         return 0
4718 }
4719 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4720
4721 test_54a() {
4722         perl -MSocket -e ';' || skip "no Socket perl module installed"
4723
4724         $SOCKETSERVER $DIR/socket ||
4725                 error "$SOCKETSERVER $DIR/socket failed: $?"
4726         $SOCKETCLIENT $DIR/socket ||
4727                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4728         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4729 }
4730 run_test 54a "unix domain socket test =========================="
4731
4732 test_54b() {
4733         f="$DIR/f54b"
4734         mknod $f c 1 3
4735         chmod 0666 $f
4736         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4737 }
4738 run_test 54b "char device works in lustre ======================"
4739
4740 find_loop_dev() {
4741         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4742         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4743         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4744
4745         for i in $(seq 3 7); do
4746                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4747                 LOOPDEV=$LOOPBASE$i
4748                 LOOPNUM=$i
4749                 break
4750         done
4751 }
4752
4753 cleanup_54c() {
4754         local rc=0
4755         loopdev="$DIR/loop54c"
4756
4757         trap 0
4758         $UMOUNT $DIR/$tdir || rc=$?
4759         losetup -d $loopdev || true
4760         losetup -d $LOOPDEV || true
4761         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4762         return $rc
4763 }
4764
4765 test_54c() {
4766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4767
4768         loopdev="$DIR/loop54c"
4769
4770         find_loop_dev
4771         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4772         trap cleanup_54c EXIT
4773         mknod $loopdev b 7 $LOOPNUM
4774         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4775         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4776         losetup $loopdev $DIR/$tfile ||
4777                 error "can't set up $loopdev for $DIR/$tfile"
4778         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4779         test_mkdir $DIR/$tdir
4780         mount -t ext2 $loopdev $DIR/$tdir ||
4781                 error "error mounting $loopdev on $DIR/$tdir"
4782         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4783                 error "dd write"
4784         df $DIR/$tdir
4785         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4786                 error "dd read"
4787         cleanup_54c
4788 }
4789 run_test 54c "block device works in lustre ====================="
4790
4791 test_54d() {
4792         f="$DIR/f54d"
4793         string="aaaaaa"
4794         mknod $f p
4795         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4796 }
4797 run_test 54d "fifo device works in lustre ======================"
4798
4799 test_54e() {
4800         f="$DIR/f54e"
4801         string="aaaaaa"
4802         cp -aL /dev/console $f
4803         echo $string > $f || error "echo $string to $f failed"
4804 }
4805 run_test 54e "console/tty device works in lustre ======================"
4806
4807 test_56a() {
4808         local numfiles=3
4809         local dir=$DIR/$tdir
4810
4811         rm -rf $dir
4812         test_mkdir -p $dir/dir
4813         for i in $(seq $numfiles); do
4814                 touch $dir/file$i
4815                 touch $dir/dir/file$i
4816         done
4817
4818         local numcomp=$($LFS getstripe --component-count $dir)
4819
4820         [[ $numcomp == 0 ]] && numcomp=1
4821
4822         # test lfs getstripe with --recursive
4823         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4824
4825         [[ $filenum -eq $((numfiles * 2)) ]] ||
4826                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4827         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4828         [[ $filenum -eq $numfiles ]] ||
4829                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4830         echo "$LFS getstripe showed obdidx or l_ost_idx"
4831
4832         # test lfs getstripe with file instead of dir
4833         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4834         [[ $filenum -eq 1 ]] ||
4835                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4836         echo "$LFS getstripe file1 passed"
4837
4838         #test lfs getstripe with --verbose
4839         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4840         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4841                 error "$LFS getstripe --verbose $dir: "\
4842                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4843         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4844                 error "$LFS getstripe $dir: showed lmm_magic"
4845
4846         #test lfs getstripe with -v prints lmm_fid
4847         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4848         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4849                 error "$LFS getstripe -v $dir: "\
4850                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4851         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4852                 error "$LFS getstripe $dir: showed lmm_fid by default"
4853         echo "$LFS getstripe --verbose passed"
4854
4855         #check for FID information
4856         local fid1=$($LFS getstripe --fid $dir/file1)
4857         local fid2=$($LFS getstripe --verbose $dir/file1 |
4858                      awk '/lmm_fid: / { print $2; exit; }')
4859         local fid3=$($LFS path2fid $dir/file1)
4860
4861         [ "$fid1" != "$fid2" ] &&
4862                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4863         [ "$fid1" != "$fid3" ] &&
4864                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4865         echo "$LFS getstripe --fid passed"
4866
4867         #test lfs getstripe with --obd
4868         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4869                 error "$LFS getstripe --obd wrong_uuid: should return error"
4870
4871         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4872
4873         local ostidx=1
4874         local obduuid=$(ostuuid_from_index $ostidx)
4875         local found=$($LFS getstripe -r --obd $obduuid $dir |
4876                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4877
4878         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4879         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4880                 ((filenum--))
4881         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4882                 ((filenum--))
4883
4884         [[ $found -eq $filenum ]] ||
4885                 error "$LFS getstripe --obd: found $found expect $filenum"
4886         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4887                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4888                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4889                 error "$LFS getstripe --obd: should not show file on other obd"
4890         echo "$LFS getstripe --obd passed"
4891 }
4892 run_test 56a "check $LFS getstripe"
4893
4894 test_56b() {
4895         local dir=$DIR/$tdir
4896         local numdirs=3
4897
4898         test_mkdir $dir
4899         for i in $(seq $numdirs); do
4900                 test_mkdir $dir/dir$i
4901         done
4902
4903         # test lfs getdirstripe default mode is non-recursion, which is
4904         # different from lfs getstripe
4905         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4906
4907         [[ $dircnt -eq 1 ]] ||
4908                 error "$LFS getdirstripe: found $dircnt, not 1"
4909         dircnt=$($LFS getdirstripe --recursive $dir |
4910                 grep -c lmv_stripe_count)
4911         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4912                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4913 }
4914 run_test 56b "check $LFS getdirstripe"
4915
4916 test_56c() {
4917         remote_ost_nodsh && skip "remote OST with nodsh"
4918
4919         local ost_idx=0
4920         local ost_name=$(ostname_from_index $ost_idx)
4921         local old_status=$(ost_dev_status $ost_idx)
4922
4923         [[ -z "$old_status" ]] ||
4924                 skip_env "OST $ost_name is in $old_status status"
4925
4926         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4927         sleep_maxage
4928
4929         local new_status=$(ost_dev_status $ost_idx)
4930
4931         [[ "$new_status" = "D" ]] ||
4932                 error "OST $ost_name is in status of '$new_status', not 'D'"
4933
4934         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4935         sleep_maxage
4936
4937         new_status=$(ost_dev_status $ost_idx)
4938         [[ -z "$new_status" ]] ||
4939                 error "OST $ost_name is in status of '$new_status', not ''"
4940 }
4941 run_test 56c "check 'lfs df' showing device status"
4942
4943 NUMFILES=3
4944 NUMDIRS=3
4945 setup_56() {
4946         local local_tdir="$1"
4947         local local_numfiles="$2"
4948         local local_numdirs="$3"
4949         local dir_params="$4"
4950         local dir_stripe_params="$5"
4951
4952         if [ ! -d "$local_tdir" ] ; then
4953                 test_mkdir -p $dir_stripe_params $local_tdir
4954                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4955                 for i in $(seq $local_numfiles) ; do
4956                         touch $local_tdir/file$i
4957                 done
4958                 for i in $(seq $local_numdirs) ; do
4959                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4960                         for j in $(seq $local_numfiles) ; do
4961                                 touch $local_tdir/dir$i/file$j
4962                         done
4963                 done
4964         fi
4965 }
4966
4967 setup_56_special() {
4968         local local_tdir=$1
4969         local local_numfiles=$2
4970         local local_numdirs=$3
4971
4972         setup_56 $local_tdir $local_numfiles $local_numdirs
4973
4974         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4975                 for i in $(seq $local_numfiles) ; do
4976                         mknod $local_tdir/loop${i}b b 7 $i
4977                         mknod $local_tdir/null${i}c c 1 3
4978                         ln -s $local_tdir/file1 $local_tdir/link${i}
4979                 done
4980                 for i in $(seq $local_numdirs) ; do
4981                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4982                         mknod $local_tdir/dir$i/null${i}c c 1 3
4983                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4984                 done
4985         fi
4986 }
4987
4988 test_56g() {
4989         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4990         local expected=$(($NUMDIRS + 2))
4991
4992         setup_56 $dir $NUMFILES $NUMDIRS
4993
4994         # test lfs find with -name
4995         for i in $(seq $NUMFILES) ; do
4996                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4997
4998                 [ $nums -eq $expected ] ||
4999                         error "lfs find -name '*$i' $dir wrong: "\
5000                               "found $nums, expected $expected"
5001         done
5002 }
5003 run_test 56g "check lfs find -name"
5004
5005 test_56h() {
5006         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5007         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5008
5009         setup_56 $dir $NUMFILES $NUMDIRS
5010
5011         # test lfs find with ! -name
5012         for i in $(seq $NUMFILES) ; do
5013                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5014
5015                 [ $nums -eq $expected ] ||
5016                         error "lfs find ! -name '*$i' $dir wrong: "\
5017                               "found $nums, expected $expected"
5018         done
5019 }
5020 run_test 56h "check lfs find ! -name"
5021
5022 test_56i() {
5023         local dir=$DIR/$tdir
5024
5025         test_mkdir $dir
5026
5027         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5028         local out=$($cmd)
5029
5030         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5031 }
5032 run_test 56i "check 'lfs find -ost UUID' skips directories"
5033
5034 test_56j() {
5035         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5036
5037         setup_56_special $dir $NUMFILES $NUMDIRS
5038
5039         local expected=$((NUMDIRS + 1))
5040         local cmd="$LFS find -type d $dir"
5041         local nums=$($cmd | wc -l)
5042
5043         [ $nums -eq $expected ] ||
5044                 error "'$cmd' wrong: found $nums, expected $expected"
5045 }
5046 run_test 56j "check lfs find -type d"
5047
5048 test_56k() {
5049         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5050
5051         setup_56_special $dir $NUMFILES $NUMDIRS
5052
5053         local expected=$(((NUMDIRS + 1) * NUMFILES))
5054         local cmd="$LFS find -type f $dir"
5055         local nums=$($cmd | wc -l)
5056
5057         [ $nums -eq $expected ] ||
5058                 error "'$cmd' wrong: found $nums, expected $expected"
5059 }
5060 run_test 56k "check lfs find -type f"
5061
5062 test_56l() {
5063         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5064
5065         setup_56_special $dir $NUMFILES $NUMDIRS
5066
5067         local expected=$((NUMDIRS + NUMFILES))
5068         local cmd="$LFS find -type b $dir"
5069         local nums=$($cmd | wc -l)
5070
5071         [ $nums -eq $expected ] ||
5072                 error "'$cmd' wrong: found $nums, expected $expected"
5073 }
5074 run_test 56l "check lfs find -type b"
5075
5076 test_56m() {
5077         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5078
5079         setup_56_special $dir $NUMFILES $NUMDIRS
5080
5081         local expected=$((NUMDIRS + NUMFILES))
5082         local cmd="$LFS find -type c $dir"
5083         local nums=$($cmd | wc -l)
5084         [ $nums -eq $expected ] ||
5085                 error "'$cmd' wrong: found $nums, expected $expected"
5086 }
5087 run_test 56m "check lfs find -type c"
5088
5089 test_56n() {
5090         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5091         setup_56_special $dir $NUMFILES $NUMDIRS
5092
5093         local expected=$((NUMDIRS + NUMFILES))
5094         local cmd="$LFS find -type l $dir"
5095         local nums=$($cmd | wc -l)
5096
5097         [ $nums -eq $expected ] ||
5098                 error "'$cmd' wrong: found $nums, expected $expected"
5099 }
5100 run_test 56n "check lfs find -type l"
5101
5102 test_56o() {
5103         local dir=$DIR/$tdir
5104
5105         setup_56 $dir $NUMFILES $NUMDIRS
5106         utime $dir/file1 > /dev/null || error "utime (1)"
5107         utime $dir/file2 > /dev/null || error "utime (2)"
5108         utime $dir/dir1 > /dev/null || error "utime (3)"
5109         utime $dir/dir2 > /dev/null || error "utime (4)"
5110         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5111         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5112
5113         local expected=4
5114         local nums=$($LFS find -mtime +0 $dir | wc -l)
5115
5116         [ $nums -eq $expected ] ||
5117                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5118
5119         expected=12
5120         cmd="$LFS find -mtime 0 $dir"
5121         nums=$($cmd | wc -l)
5122         [ $nums -eq $expected ] ||
5123                 error "'$cmd' wrong: found $nums, expected $expected"
5124 }
5125 run_test 56o "check lfs find -mtime for old files"
5126
5127 test_56ob() {
5128         local dir=$DIR/$tdir
5129         local expected=1
5130         local count=0
5131
5132         # just to make sure there is something that won't be found
5133         test_mkdir $dir
5134         touch $dir/$tfile.now
5135
5136         for age in year week day hour min; do
5137                 count=$((count + 1))
5138
5139                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5140                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5141                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5142
5143                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5144                 local nums=$($cmd | wc -l)
5145                 [ $nums -eq $expected ] ||
5146                         error "'$cmd' wrong: found $nums, expected $expected"
5147
5148                 cmd="$LFS find $dir -atime $count${age:0:1}"
5149                 nums=$($cmd | wc -l)
5150                 [ $nums -eq $expected ] ||
5151                         error "'$cmd' wrong: found $nums, expected $expected"
5152         done
5153
5154         sleep 2
5155         cmd="$LFS find $dir -ctime +1s -type f"
5156         nums=$($cmd | wc -l)
5157         (( $nums == $count * 2 + 1)) ||
5158                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5159 }
5160 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5161
5162 test_56p() {
5163         [ $RUNAS_ID -eq $UID ] &&
5164                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5165
5166         local dir=$DIR/$tdir
5167
5168         setup_56 $dir $NUMFILES $NUMDIRS
5169         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5170
5171         local expected=$NUMFILES
5172         local cmd="$LFS find -uid $RUNAS_ID $dir"
5173         local nums=$($cmd | wc -l)
5174
5175         [ $nums -eq $expected ] ||
5176                 error "'$cmd' wrong: found $nums, expected $expected"
5177
5178         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5179         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5180         nums=$($cmd | wc -l)
5181         [ $nums -eq $expected ] ||
5182                 error "'$cmd' wrong: found $nums, expected $expected"
5183 }
5184 run_test 56p "check lfs find -uid and ! -uid"
5185
5186 test_56q() {
5187         [ $RUNAS_ID -eq $UID ] &&
5188                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5189
5190         local dir=$DIR/$tdir
5191
5192         setup_56 $dir $NUMFILES $NUMDIRS
5193         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5194
5195         local expected=$NUMFILES
5196         local cmd="$LFS find -gid $RUNAS_GID $dir"
5197         local nums=$($cmd | wc -l)
5198
5199         [ $nums -eq $expected ] ||
5200                 error "'$cmd' wrong: found $nums, expected $expected"
5201
5202         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5203         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5204         nums=$($cmd | wc -l)
5205         [ $nums -eq $expected ] ||
5206                 error "'$cmd' wrong: found $nums, expected $expected"
5207 }
5208 run_test 56q "check lfs find -gid and ! -gid"
5209
5210 test_56r() {
5211         local dir=$DIR/$tdir
5212
5213         setup_56 $dir $NUMFILES $NUMDIRS
5214
5215         local expected=12
5216         local cmd="$LFS find -size 0 -type f $dir"
5217         local nums=$($cmd | wc -l)
5218
5219         [ $nums -eq $expected ] ||
5220                 error "'$cmd' wrong: found $nums, expected $expected"
5221         expected=0
5222         cmd="$LFS find ! -size 0 -type f $dir"
5223         nums=$($cmd | wc -l)
5224         [ $nums -eq $expected ] ||
5225                 error "'$cmd' wrong: found $nums, expected $expected"
5226         echo "test" > $dir/$tfile
5227         echo "test2" > $dir/$tfile.2 && sync
5228         expected=1
5229         cmd="$LFS find -size 5 -type f $dir"
5230         nums=$($cmd | wc -l)
5231         [ $nums -eq $expected ] ||
5232                 error "'$cmd' wrong: found $nums, expected $expected"
5233         expected=1
5234         cmd="$LFS find -size +5 -type f $dir"
5235         nums=$($cmd | wc -l)
5236         [ $nums -eq $expected ] ||
5237                 error "'$cmd' wrong: found $nums, expected $expected"
5238         expected=2
5239         cmd="$LFS find -size +0 -type f $dir"
5240         nums=$($cmd | wc -l)
5241         [ $nums -eq $expected ] ||
5242                 error "'$cmd' wrong: found $nums, expected $expected"
5243         expected=2
5244         cmd="$LFS find ! -size -5 -type f $dir"
5245         nums=$($cmd | wc -l)
5246         [ $nums -eq $expected ] ||
5247                 error "'$cmd' wrong: found $nums, expected $expected"
5248         expected=12
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 run_test 56r "check lfs find -size works"
5255
5256 test_56s() { # LU-611 #LU-9369
5257         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5258
5259         local dir=$DIR/$tdir
5260         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5261
5262         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5263         for i in $(seq $NUMDIRS); do
5264                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5265         done
5266
5267         local expected=$NUMDIRS
5268         local cmd="$LFS find -c $OSTCOUNT $dir"
5269         local nums=$($cmd | wc -l)
5270
5271         [ $nums -eq $expected ] || {
5272                 $LFS getstripe -R $dir
5273                 error "'$cmd' wrong: found $nums, expected $expected"
5274         }
5275
5276         expected=$((NUMDIRS + onestripe))
5277         cmd="$LFS find -stripe-count +0 -type f $dir"
5278         nums=$($cmd | wc -l)
5279         [ $nums -eq $expected ] || {
5280                 $LFS getstripe -R $dir
5281                 error "'$cmd' wrong: found $nums, expected $expected"
5282         }
5283
5284         expected=$onestripe
5285         cmd="$LFS find -stripe-count 1 -type f $dir"
5286         nums=$($cmd | wc -l)
5287         [ $nums -eq $expected ] || {
5288                 $LFS getstripe -R $dir
5289                 error "'$cmd' wrong: found $nums, expected $expected"
5290         }
5291
5292         cmd="$LFS find -stripe-count -2 -type f $dir"
5293         nums=$($cmd | wc -l)
5294         [ $nums -eq $expected ] || {
5295                 $LFS getstripe -R $dir
5296                 error "'$cmd' wrong: found $nums, expected $expected"
5297         }
5298
5299         expected=0
5300         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5301         nums=$($cmd | wc -l)
5302         [ $nums -eq $expected ] || {
5303                 $LFS getstripe -R $dir
5304                 error "'$cmd' wrong: found $nums, expected $expected"
5305         }
5306 }
5307 run_test 56s "check lfs find -stripe-count works"
5308
5309 test_56t() { # LU-611 #LU-9369
5310         local dir=$DIR/$tdir
5311
5312         setup_56 $dir 0 $NUMDIRS
5313         for i in $(seq $NUMDIRS); do
5314                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5315         done
5316
5317         local expected=$NUMDIRS
5318         local cmd="$LFS find -S 8M $dir"
5319         local nums=$($cmd | wc -l)
5320
5321         [ $nums -eq $expected ] || {
5322                 $LFS getstripe -R $dir
5323                 error "'$cmd' wrong: found $nums, expected $expected"
5324         }
5325         rm -rf $dir
5326
5327         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5328
5329         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5330
5331         expected=$(((NUMDIRS + 1) * NUMFILES))
5332         cmd="$LFS find -stripe-size 512k -type f $dir"
5333         nums=$($cmd | wc -l)
5334         [ $nums -eq $expected ] ||
5335                 error "'$cmd' wrong: found $nums, expected $expected"
5336
5337         cmd="$LFS find -stripe-size +320k -type f $dir"
5338         nums=$($cmd | wc -l)
5339         [ $nums -eq $expected ] ||
5340                 error "'$cmd' wrong: found $nums, expected $expected"
5341
5342         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5343         cmd="$LFS find -stripe-size +200k -type f $dir"
5344         nums=$($cmd | wc -l)
5345         [ $nums -eq $expected ] ||
5346                 error "'$cmd' wrong: found $nums, expected $expected"
5347
5348         cmd="$LFS find -stripe-size -640k -type f $dir"
5349         nums=$($cmd | wc -l)
5350         [ $nums -eq $expected ] ||
5351                 error "'$cmd' wrong: found $nums, expected $expected"
5352
5353         expected=4
5354         cmd="$LFS find -stripe-size 256k -type f $dir"
5355         nums=$($cmd | wc -l)
5356         [ $nums -eq $expected ] ||
5357                 error "'$cmd' wrong: found $nums, expected $expected"
5358
5359         cmd="$LFS find -stripe-size -320k -type f $dir"
5360         nums=$($cmd | wc -l)
5361         [ $nums -eq $expected ] ||
5362                 error "'$cmd' wrong: found $nums, expected $expected"
5363
5364         expected=0
5365         cmd="$LFS find -stripe-size 1024k -type f $dir"
5366         nums=$($cmd | wc -l)
5367         [ $nums -eq $expected ] ||
5368                 error "'$cmd' wrong: found $nums, expected $expected"
5369 }
5370 run_test 56t "check lfs find -stripe-size works"
5371
5372 test_56u() { # LU-611
5373         local dir=$DIR/$tdir
5374
5375         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5376
5377         if [[ $OSTCOUNT -gt 1 ]]; then
5378                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5379                 onestripe=4
5380         else
5381                 onestripe=0
5382         fi
5383
5384         local expected=$(((NUMDIRS + 1) * NUMFILES))
5385         local cmd="$LFS find -stripe-index 0 -type f $dir"
5386         local nums=$($cmd | wc -l)
5387
5388         [ $nums -eq $expected ] ||
5389                 error "'$cmd' wrong: found $nums, expected $expected"
5390
5391         expected=$onestripe
5392         cmd="$LFS find -stripe-index 1 -type f $dir"
5393         nums=$($cmd | wc -l)
5394         [ $nums -eq $expected ] ||
5395                 error "'$cmd' wrong: found $nums, expected $expected"
5396
5397         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5398         nums=$($cmd | wc -l)
5399         [ $nums -eq $expected ] ||
5400                 error "'$cmd' wrong: found $nums, expected $expected"
5401
5402         expected=0
5403         # This should produce an error and not return any files
5404         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5405         nums=$($cmd 2>/dev/null | wc -l)
5406         [ $nums -eq $expected ] ||
5407                 error "'$cmd' wrong: found $nums, expected $expected"
5408
5409         if [[ $OSTCOUNT -gt 1 ]]; then
5410                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5411                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5412                 nums=$($cmd | wc -l)
5413                 [ $nums -eq $expected ] ||
5414                         error "'$cmd' wrong: found $nums, expected $expected"
5415         fi
5416 }
5417 run_test 56u "check lfs find -stripe-index works"
5418
5419 test_56v() {
5420         local mdt_idx=0
5421         local dir=$DIR/$tdir
5422
5423         setup_56 $dir $NUMFILES $NUMDIRS
5424
5425         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5426         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5427
5428         for file in $($LFS find -m $UUID $dir); do
5429                 file_midx=$($LFS getstripe -m $file)
5430                 [ $file_midx -eq $mdt_idx ] ||
5431                         error "lfs find -m $UUID != getstripe -m $file_midx"
5432         done
5433 }
5434 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5435
5436 test_56w() {
5437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5439
5440         local dir=$DIR/$tdir
5441
5442         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5443
5444         local stripe_size=$($LFS getstripe -S -d $dir) ||
5445                 error "$LFS getstripe -S -d $dir failed"
5446         stripe_size=${stripe_size%% *}
5447
5448         local file_size=$((stripe_size * OSTCOUNT))
5449         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5450         local required_space=$((file_num * file_size))
5451         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5452                            head -n1)
5453         [[ $free_space -le $((required_space / 1024)) ]] &&
5454                 skip_env "need $required_space, have $free_space kbytes"
5455
5456         local dd_bs=65536
5457         local dd_count=$((file_size / dd_bs))
5458
5459         # write data into the files
5460         local i
5461         local j
5462         local file
5463
5464         for i in $(seq $NUMFILES); do
5465                 file=$dir/file$i
5466                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5467                         error "write data into $file failed"
5468         done
5469         for i in $(seq $NUMDIRS); do
5470                 for j in $(seq $NUMFILES); do
5471                         file=$dir/dir$i/file$j
5472                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5473                                 error "write data into $file failed"
5474                 done
5475         done
5476
5477         # $LFS_MIGRATE will fail if hard link migration is unsupported
5478         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5479                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5480                         error "creating links to $dir/dir1/file1 failed"
5481         fi
5482
5483         local expected=-1
5484
5485         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5486
5487         # lfs_migrate file
5488         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5489
5490         echo "$cmd"
5491         eval $cmd || error "$cmd failed"
5492
5493         check_stripe_count $dir/file1 $expected
5494
5495         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5496         then
5497                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5498                 # OST 1 if it is on OST 0. This file is small enough to
5499                 # be on only one stripe.
5500                 file=$dir/migr_1_ost
5501                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5502                         error "write data into $file failed"
5503                 local obdidx=$($LFS getstripe -i $file)
5504                 local oldmd5=$(md5sum $file)
5505                 local newobdidx=0
5506
5507                 [[ $obdidx -eq 0 ]] && newobdidx=1
5508                 cmd="$LFS migrate -i $newobdidx $file"
5509                 echo $cmd
5510                 eval $cmd || error "$cmd failed"
5511
5512                 local realobdix=$($LFS getstripe -i $file)
5513                 local newmd5=$(md5sum $file)
5514
5515                 [[ $newobdidx -ne $realobdix ]] &&
5516                         error "new OST is different (was=$obdidx, "\
5517                               "wanted=$newobdidx, got=$realobdix)"
5518                 [[ "$oldmd5" != "$newmd5" ]] &&
5519                         error "md5sum differ: $oldmd5, $newmd5"
5520         fi
5521
5522         # lfs_migrate dir
5523         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5524         echo "$cmd"
5525         eval $cmd || error "$cmd failed"
5526
5527         for j in $(seq $NUMFILES); do
5528                 check_stripe_count $dir/dir1/file$j $expected
5529         done
5530
5531         # lfs_migrate works with lfs find
5532         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5533              $LFS_MIGRATE -y -c $expected"
5534         echo "$cmd"
5535         eval $cmd || error "$cmd failed"
5536
5537         for i in $(seq 2 $NUMFILES); do
5538                 check_stripe_count $dir/file$i $expected
5539         done
5540         for i in $(seq 2 $NUMDIRS); do
5541                 for j in $(seq $NUMFILES); do
5542                 check_stripe_count $dir/dir$i/file$j $expected
5543                 done
5544         done
5545 }
5546 run_test 56w "check lfs_migrate -c stripe_count works"
5547
5548 test_56wb() {
5549         local file1=$DIR/$tdir/file1
5550         local create_pool=false
5551         local initial_pool=$($LFS getstripe -p $DIR)
5552         local pool_list=()
5553         local pool=""
5554
5555         echo -n "Creating test dir..."
5556         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5557         echo "done."
5558
5559         echo -n "Creating test file..."
5560         touch $file1 || error "cannot create file"
5561         echo "done."
5562
5563         echo -n "Detecting existing pools..."
5564         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5565
5566         if [ ${#pool_list[@]} -gt 0 ]; then
5567                 echo "${pool_list[@]}"
5568                 for thispool in "${pool_list[@]}"; do
5569                         if [[ -z "$initial_pool" ||
5570                               "$initial_pool" != "$thispool" ]]; then
5571                                 pool="$thispool"
5572                                 echo "Using existing pool '$pool'"
5573                                 break
5574                         fi
5575                 done
5576         else
5577                 echo "none detected."
5578         fi
5579         if [ -z "$pool" ]; then
5580                 pool=${POOL:-testpool}
5581                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5582                 echo -n "Creating pool '$pool'..."
5583                 create_pool=true
5584                 pool_add $pool &> /dev/null ||
5585                         error "pool_add failed"
5586                 echo "done."
5587
5588                 echo -n "Adding target to pool..."
5589                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5590                         error "pool_add_targets failed"
5591                 echo "done."
5592         fi
5593
5594         echo -n "Setting pool using -p option..."
5595         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5596                 error "migrate failed rc = $?"
5597         echo "done."
5598
5599         echo -n "Verifying test file is in pool after migrating..."
5600         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5601                 error "file was not migrated to pool $pool"
5602         echo "done."
5603
5604         echo -n "Removing test file from pool '$pool'..."
5605         $LFS migrate $file1 &> /dev/null ||
5606                 error "cannot remove from pool"
5607         [ "$($LFS getstripe -p $file1)" ] &&
5608                 error "pool still set"
5609         echo "done."
5610
5611         echo -n "Setting pool using --pool option..."
5612         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5613                 error "migrate failed rc = $?"
5614         echo "done."
5615
5616         # Clean up
5617         rm -f $file1
5618         if $create_pool; then
5619                 destroy_test_pools 2> /dev/null ||
5620                         error "destroy test pools failed"
5621         fi
5622 }
5623 run_test 56wb "check lfs_migrate pool support"
5624
5625 test_56wc() {
5626         local file1="$DIR/$tdir/file1"
5627
5628         echo -n "Creating test dir..."
5629         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5630         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5631         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5632                 error "cannot set stripe"
5633         echo "done"
5634
5635         echo -n "Setting initial stripe for test file..."
5636         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5637                 error "cannot set stripe"
5638         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5639                 error "stripe size not set"
5640         echo "done."
5641
5642         # File currently set to -S 512K -c 1
5643
5644         # Ensure -c and -S options are rejected when -R is set
5645         echo -n "Verifying incompatible options are detected..."
5646         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5647                 error "incompatible -c and -R options not detected"
5648         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5649                 error "incompatible -S and -R options not detected"
5650         echo "done."
5651
5652         # Ensure unrecognized options are passed through to 'lfs migrate'
5653         echo -n "Verifying -S option is passed through to lfs migrate..."
5654         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5655                 error "migration failed"
5656         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5657                 error "file was not restriped"
5658         echo "done."
5659
5660         # File currently set to -S 1M -c 1
5661
5662         # Ensure long options are supported
5663         echo -n "Verifying long options supported..."
5664         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5665                 error "long option without argument not supported"
5666         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5667                 error "long option with argument not supported"
5668         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5669                 error "file not restriped with --stripe-size option"
5670         echo "done."
5671
5672         # File currently set to -S 512K -c 1
5673
5674         if [ "$OSTCOUNT" -gt 1 ]; then
5675                 echo -n "Verifying explicit stripe count can be set..."
5676                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5677                         error "migrate failed"
5678                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5679                         error "file not restriped to explicit count"
5680                 echo "done."
5681         fi
5682
5683         # File currently set to -S 512K -c 1 or -S 512K -c 2
5684
5685         # Ensure parent striping is used if -R is set, and no stripe
5686         # count or size is specified
5687         echo -n "Setting stripe for parent directory..."
5688         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5689                 error "cannot set stripe"
5690         echo "done."
5691
5692         echo -n "Verifying restripe option uses parent stripe settings..."
5693         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5694                 error "migrate failed"
5695         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5696                 error "file not restriped to parent settings"
5697         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5698                 error "file not restriped to parent settings"
5699         echo "done."
5700
5701         # File currently set to -S 1M -c 1
5702
5703         # Ensure striping is preserved if -R is not set, and no stripe
5704         # count or size is specified
5705         echo -n "Verifying striping size preserved when not specified..."
5706         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5707         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5708                 error "cannot set stripe on parent directory"
5709         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5710                 error "migrate failed"
5711         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5712                 error "file was restriped"
5713         echo "done."
5714
5715         # Ensure file name properly detected when final option has no argument
5716         echo -n "Verifying file name properly detected..."
5717         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5718                 error "file name interpreted as option argument"
5719         echo "done."
5720
5721         # Clean up
5722         rm -f "$file1"
5723 }
5724 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5725
5726 test_56wd() {
5727         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5728
5729         local file1=$DIR/$tdir/file1
5730
5731         echo -n "Creating test dir..."
5732         test_mkdir $DIR/$tdir || error "cannot create dir"
5733         echo "done."
5734
5735         echo -n "Creating test file..."
5736         touch $file1
5737         echo "done."
5738
5739         # Ensure 'lfs migrate' will fail by using a non-existent option,
5740         # and make sure rsync is not called to recover
5741         echo -n "Make sure --no-rsync option works..."
5742         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5743                 grep -q 'refusing to fall back to rsync' ||
5744                 error "rsync was called with --no-rsync set"
5745         echo "done."
5746
5747         # Ensure rsync is called without trying 'lfs migrate' first
5748         echo -n "Make sure --rsync option works..."
5749         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5750                 grep -q 'falling back to rsync' &&
5751                 error "lfs migrate was called with --rsync set"
5752         echo "done."
5753
5754         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5755         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5756                 grep -q 'at the same time' ||
5757                 error "--rsync and --no-rsync accepted concurrently"
5758         echo "done."
5759
5760         # Clean up
5761         rm -f $file1
5762 }
5763 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5764
5765 test_56x() {
5766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5767         check_swap_layouts_support
5768
5769         local dir=$DIR/$tdir
5770         local ref1=/etc/passwd
5771         local file1=$dir/file1
5772
5773         test_mkdir $dir || error "creating dir $dir"
5774         $LFS setstripe -c 2 $file1
5775         cp $ref1 $file1
5776         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5777         stripe=$($LFS getstripe -c $file1)
5778         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5779         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5780
5781         # clean up
5782         rm -f $file1
5783 }
5784 run_test 56x "lfs migration support"
5785
5786 test_56xa() {
5787         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5788         check_swap_layouts_support
5789
5790         local dir=$DIR/$tdir/$testnum
5791
5792         test_mkdir -p $dir
5793
5794         local ref1=/etc/passwd
5795         local file1=$dir/file1
5796
5797         $LFS setstripe -c 2 $file1
5798         cp $ref1 $file1
5799         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5800
5801         local stripe=$($LFS getstripe -c $file1)
5802
5803         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5804         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5805
5806         # clean up
5807         rm -f $file1
5808 }
5809 run_test 56xa "lfs migration --block support"
5810
5811 check_migrate_links() {
5812         local dir="$1"
5813         local file1="$dir/file1"
5814         local begin="$2"
5815         local count="$3"
5816         local total_count=$(($begin + $count - 1))
5817         local symlink_count=10
5818         local uniq_count=10
5819
5820         if [ ! -f "$file1" ]; then
5821                 echo -n "creating initial file..."
5822                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5823                         error "cannot setstripe initial file"
5824                 echo "done"
5825
5826                 echo -n "creating symlinks..."
5827                 for s in $(seq 1 $symlink_count); do
5828                         ln -s "$file1" "$dir/slink$s" ||
5829                                 error "cannot create symlinks"
5830                 done
5831                 echo "done"
5832
5833                 echo -n "creating nonlinked files..."
5834                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5835                         error "cannot create nonlinked files"
5836                 echo "done"
5837         fi
5838
5839         # create hard links
5840         if [ ! -f "$dir/file$total_count" ]; then
5841                 echo -n "creating hard links $begin:$total_count..."
5842                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5843                         /dev/null || error "cannot create hard links"
5844                 echo "done"
5845         fi
5846
5847         echo -n "checking number of hard links listed in xattrs..."
5848         local fid=$($LFS getstripe -F "$file1")
5849         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5850
5851         echo "${#paths[*]}"
5852         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5853                         skip "hard link list has unexpected size, skipping test"
5854         fi
5855         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5856                         error "link names should exceed xattrs size"
5857         fi
5858
5859         echo -n "migrating files..."
5860         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5861         local rc=$?
5862         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5863         echo "done"
5864
5865         # make sure all links have been properly migrated
5866         echo -n "verifying files..."
5867         fid=$($LFS getstripe -F "$file1") ||
5868                 error "cannot get fid for file $file1"
5869         for i in $(seq 2 $total_count); do
5870                 local fid2=$($LFS getstripe -F $dir/file$i)
5871
5872                 [ "$fid2" == "$fid" ] ||
5873                         error "migrated hard link has mismatched FID"
5874         done
5875
5876         # make sure hard links were properly detected, and migration was
5877         # performed only once for the entire link set; nonlinked files should
5878         # also be migrated
5879         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5880         local expected=$(($uniq_count + 1))
5881
5882         [ "$actual" -eq  "$expected" ] ||
5883                 error "hard links individually migrated ($actual != $expected)"
5884
5885         # make sure the correct number of hard links are present
5886         local hardlinks=$(stat -c '%h' "$file1")
5887
5888         [ $hardlinks -eq $total_count ] ||
5889                 error "num hard links $hardlinks != $total_count"
5890         echo "done"
5891
5892         return 0
5893 }
5894
5895 test_56xb() {
5896         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5897                 skip "Need MDS version at least 2.10.55"
5898
5899         local dir="$DIR/$tdir"
5900
5901         test_mkdir "$dir" || error "cannot create dir $dir"
5902
5903         echo "testing lfs migrate mode when all links fit within xattrs"
5904         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5905
5906         echo "testing rsync mode when all links fit within xattrs"
5907         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5908
5909         echo "testing lfs migrate mode when all links do not fit within xattrs"
5910         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5911
5912         echo "testing rsync mode when all links do not fit within xattrs"
5913         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5914
5915
5916         # clean up
5917         rm -rf $dir
5918 }
5919 run_test 56xb "lfs migration hard link support"
5920
5921 test_56xc() {
5922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5923
5924         local dir="$DIR/$tdir"
5925
5926         test_mkdir "$dir" || error "cannot create dir $dir"
5927
5928         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5929         echo -n "Setting initial stripe for 20MB test file..."
5930         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5931         echo "done"
5932         echo -n "Sizing 20MB test file..."
5933         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5934         echo "done"
5935         echo -n "Verifying small file autostripe count is 1..."
5936         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5937                 error "cannot migrate 20MB file"
5938         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5939                 error "cannot get stripe for $dir/20mb"
5940         [ $stripe_count -eq 1 ] ||
5941                 error "unexpected stripe count $stripe_count for 20MB file"
5942         rm -f "$dir/20mb"
5943         echo "done"
5944
5945         # Test 2: File is small enough to fit within the available space on
5946         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5947         # have at least an additional 1KB for each desired stripe for test 3
5948         echo -n "Setting stripe for 1GB test file..."
5949         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5950         echo "done"
5951         echo -n "Sizing 1GB test file..."
5952         # File size is 1GB + 3KB
5953         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5954                 error "cannot create 1GB test file"
5955         echo "done"
5956         echo -n "Migrating 1GB file..."
5957         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5958                 error "cannot migrate file"
5959         echo "done"
5960         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5961         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5962                 error "cannot get stripe for $dir/1gb"
5963         [ $stripe_count -eq 2 ] ||
5964                 error "unexpected stripe count $stripe_count (expected 2)"
5965         echo "done"
5966
5967         # Test 3: File is too large to fit within the available space on
5968         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5969         if [ $OSTCOUNT -ge 3 ]; then
5970                 # The required available space is calculated as
5971                 # file size (1GB + 3KB) / OST count (3).
5972                 local kb_per_ost=349526
5973
5974                 echo -n "Migrating 1GB file..."
5975                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5976                         /dev/null || error "cannot migrate file"
5977                 echo "done"
5978
5979                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5980                 echo -n "Verifying autostripe count with limited space..."
5981                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5982                         error "unexpected stripe count $stripe_count (wanted 3)"
5983                 echo "done"
5984         fi
5985
5986         # clean up
5987         rm -rf $dir
5988 }
5989 run_test 56xc "lfs migration autostripe"
5990
5991 test_56y() {
5992         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5993                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5994
5995         local res=""
5996         local dir=$DIR/$tdir
5997         local f1=$dir/file1
5998         local f2=$dir/file2
5999
6000         test_mkdir -p $dir || error "creating dir $dir"
6001         touch $f1 || error "creating std file $f1"
6002         $MULTIOP $f2 H2c || error "creating released file $f2"
6003
6004         # a directory can be raid0, so ask only for files
6005         res=$($LFS find $dir -L raid0 -type f | wc -l)
6006         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6007
6008         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6009         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6010
6011         # only files can be released, so no need to force file search
6012         res=$($LFS find $dir -L released)
6013         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6014
6015         res=$($LFS find $dir -type f \! -L released)
6016         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6017 }
6018 run_test 56y "lfs find -L raid0|released"
6019
6020 test_56z() { # LU-4824
6021         # This checks to make sure 'lfs find' continues after errors
6022         # There are two classes of errors that should be caught:
6023         # - If multiple paths are provided, all should be searched even if one
6024         #   errors out
6025         # - If errors are encountered during the search, it should not terminate
6026         #   early
6027         local dir=$DIR/$tdir
6028         local i
6029
6030         test_mkdir $dir
6031         for i in d{0..9}; do
6032                 test_mkdir $dir/$i
6033         done
6034         touch $dir/d{0..9}/$tfile
6035         $LFS find $DIR/non_existent_dir $dir &&
6036                 error "$LFS find did not return an error"
6037         # Make a directory unsearchable. This should NOT be the last entry in
6038         # directory order.  Arbitrarily pick the 6th entry
6039         chmod 700 $($LFS find $dir -type d | sed '6!d')
6040
6041         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6042
6043         # The user should be able to see 10 directories and 9 files
6044         [ $count == 19 ] || error "$LFS find did not continue after error"
6045 }
6046 run_test 56z "lfs find should continue after an error"
6047
6048 test_56aa() { # LU-5937
6049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6050
6051         local dir=$DIR/$tdir
6052
6053         mkdir $dir
6054         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6055
6056         createmany -o $dir/striped_dir/${tfile}- 1024
6057         local dirs=$($LFS find --size +8k $dir/)
6058
6059         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6060 }
6061 run_test 56aa "lfs find --size under striped dir"
6062
6063 test_56ab() { # LU-10705
6064         test_mkdir $DIR/$tdir
6065         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6066         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6067         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6068         # Flush writes to ensure valid blocks.  Need to be more thorough for
6069         # ZFS, since blocks are not allocated/returned to client immediately.
6070         sync_all_data
6071         wait_zfs_commit ost1 2
6072         cancel_lru_locks osc
6073         ls -ls $DIR/$tdir
6074
6075         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6076
6077         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6078
6079         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6080         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6081
6082         rm -f $DIR/$tdir/$tfile.[123]
6083 }
6084 run_test 56ab "lfs find --blocks"
6085
6086 test_56ba() {
6087         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6088                 skip "Need MDS version at least 2.10.50"
6089
6090         # Create composite files with one component
6091         local dir=$DIR/$tdir
6092
6093         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6094         # Create composite files with three components
6095         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6096         # Create non-composite files
6097         createmany -o $dir/${tfile}- 10
6098
6099         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6100
6101         [[ $nfiles == 10 ]] ||
6102                 error "lfs find -E 1M found $nfiles != 10 files"
6103
6104         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6105         [[ $nfiles == 25 ]] ||
6106                 error "lfs find ! -E 1M found $nfiles != 25 files"
6107
6108         # All files have a component that starts at 0
6109         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6110         [[ $nfiles == 35 ]] ||
6111                 error "lfs find --component-start 0 - $nfiles != 35 files"
6112
6113         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6114         [[ $nfiles == 15 ]] ||
6115                 error "lfs find --component-start 2M - $nfiles != 15 files"
6116
6117         # All files created here have a componenet that does not starts at 2M
6118         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6119         [[ $nfiles == 35 ]] ||
6120                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6121
6122         # Find files with a specified number of components
6123         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6124         [[ $nfiles == 15 ]] ||
6125                 error "lfs find --component-count 3 - $nfiles != 15 files"
6126
6127         # Remember non-composite files have a component count of zero
6128         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6129         [[ $nfiles == 10 ]] ||
6130                 error "lfs find --component-count 0 - $nfiles != 10 files"
6131
6132         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6133         [[ $nfiles == 20 ]] ||
6134                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6135
6136         # All files have a flag called "init"
6137         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6138         [[ $nfiles == 35 ]] ||
6139                 error "lfs find --component-flags init - $nfiles != 35 files"
6140
6141         # Multi-component files will have a component not initialized
6142         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6143         [[ $nfiles == 15 ]] ||
6144                 error "lfs find !--component-flags init - $nfiles != 15 files"
6145
6146         rm -rf $dir
6147
6148 }
6149 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6150
6151 test_56ca() {
6152         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6153                 skip "Need MDS version at least 2.10.57"
6154
6155         local td=$DIR/$tdir
6156         local tf=$td/$tfile
6157         local dir
6158         local nfiles
6159         local cmd
6160         local i
6161         local j
6162
6163         # create mirrored directories and mirrored files
6164         mkdir $td || error "mkdir $td failed"
6165         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6166         createmany -o $tf- 10 || error "create $tf- failed"
6167
6168         for i in $(seq 2); do
6169                 dir=$td/dir$i
6170                 mkdir $dir || error "mkdir $dir failed"
6171                 $LFS mirror create -N$((3 + i)) $dir ||
6172                         error "create mirrored dir $dir failed"
6173                 createmany -o $dir/$tfile- 10 ||
6174                         error "create $dir/$tfile- failed"
6175         done
6176
6177         # change the states of some mirrored files
6178         echo foo > $tf-6
6179         for i in $(seq 2); do
6180                 dir=$td/dir$i
6181                 for j in $(seq 4 9); do
6182                         echo foo > $dir/$tfile-$j
6183                 done
6184         done
6185
6186         # find mirrored files with specific mirror count
6187         cmd="$LFS find --mirror-count 3 --type f $td"
6188         nfiles=$($cmd | wc -l)
6189         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6190
6191         cmd="$LFS find ! --mirror-count 3 --type f $td"
6192         nfiles=$($cmd | wc -l)
6193         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6194
6195         cmd="$LFS find --mirror-count +2 --type f $td"
6196         nfiles=$($cmd | wc -l)
6197         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6198
6199         cmd="$LFS find --mirror-count -6 --type f $td"
6200         nfiles=$($cmd | wc -l)
6201         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6202
6203         # find mirrored files with specific file state
6204         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6205         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6206
6207         cmd="$LFS find --mirror-state=ro --type f $td"
6208         nfiles=$($cmd | wc -l)
6209         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6210
6211         cmd="$LFS find ! --mirror-state=ro --type f $td"
6212         nfiles=$($cmd | wc -l)
6213         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6214
6215         cmd="$LFS find --mirror-state=wp --type f $td"
6216         nfiles=$($cmd | wc -l)
6217         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6218
6219         cmd="$LFS find ! --mirror-state=sp --type f $td"
6220         nfiles=$($cmd | wc -l)
6221         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6222 }
6223 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6224
6225 test_57a() {
6226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6227         # note test will not do anything if MDS is not local
6228         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6229                 skip_env "ldiskfs only test"
6230         fi
6231         remote_mds_nodsh && skip "remote MDS with nodsh"
6232
6233         local MNTDEV="osd*.*MDT*.mntdev"
6234         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6235         [ -z "$DEV" ] && error "can't access $MNTDEV"
6236         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6237                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6238                         error "can't access $DEV"
6239                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6240                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6241                 rm $TMP/t57a.dump
6242         done
6243 }
6244 run_test 57a "verify MDS filesystem created with large inodes =="
6245
6246 test_57b() {
6247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6248         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6249                 skip_env "ldiskfs only test"
6250         fi
6251         remote_mds_nodsh && skip "remote MDS with nodsh"
6252
6253         local dir=$DIR/$tdir
6254         local filecount=100
6255         local file1=$dir/f1
6256         local fileN=$dir/f$filecount
6257
6258         rm -rf $dir || error "removing $dir"
6259         test_mkdir -c1 $dir
6260         local mdtidx=$($LFS getstripe -m $dir)
6261         local mdtname=MDT$(printf %04x $mdtidx)
6262         local facet=mds$((mdtidx + 1))
6263
6264         echo "mcreating $filecount files"
6265         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6266
6267         # verify that files do not have EAs yet
6268         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6269                 error "$file1 has an EA"
6270         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6271                 error "$fileN has an EA"
6272
6273         sync
6274         sleep 1
6275         df $dir  #make sure we get new statfs data
6276         local mdsfree=$(do_facet $facet \
6277                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6278         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6279         local file
6280
6281         echo "opening files to create objects/EAs"
6282         for file in $(seq -f $dir/f%g 1 $filecount); do
6283                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6284                         error "opening $file"
6285         done
6286
6287         # verify that files have EAs now
6288         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6289         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6290
6291         sleep 1  #make sure we get new statfs data
6292         df $dir
6293         local mdsfree2=$(do_facet $facet \
6294                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6295         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6296
6297         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6298                 if [ "$mdsfree" != "$mdsfree2" ]; then
6299                         error "MDC before $mdcfree != after $mdcfree2"
6300                 else
6301                         echo "MDC before $mdcfree != after $mdcfree2"
6302                         echo "unable to confirm if MDS has large inodes"
6303                 fi
6304         fi
6305         rm -rf $dir
6306 }
6307 run_test 57b "default LOV EAs are stored inside large inodes ==="
6308
6309 test_58() {
6310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6311         [ -z "$(which wiretest 2>/dev/null)" ] &&
6312                         skip_env "could not find wiretest"
6313
6314         wiretest
6315 }
6316 run_test 58 "verify cross-platform wire constants =============="
6317
6318 test_59() {
6319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6320
6321         echo "touch 130 files"
6322         createmany -o $DIR/f59- 130
6323         echo "rm 130 files"
6324         unlinkmany $DIR/f59- 130
6325         sync
6326         # wait for commitment of removal
6327         wait_delete_completed
6328 }
6329 run_test 59 "verify cancellation of llog records async ========="
6330
6331 TEST60_HEAD="test_60 run $RANDOM"
6332 test_60a() {
6333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6334         remote_mgs_nodsh && skip "remote MGS with nodsh"
6335         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6336                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6337                         skip_env "missing subtest run-llog.sh"
6338
6339         log "$TEST60_HEAD - from kernel mode"
6340         do_facet mgs "$LCTL dk > /dev/null"
6341         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6342         do_facet mgs $LCTL dk > $TMP/$tfile
6343
6344         # LU-6388: test llog_reader
6345         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6346         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6347         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6348                         skip_env "missing llog_reader"
6349         local fstype=$(facet_fstype mgs)
6350         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6351                 skip_env "Only for ldiskfs or zfs type mgs"
6352
6353         local mntpt=$(facet_mntpt mgs)
6354         local mgsdev=$(mgsdevname 1)
6355         local fid_list
6356         local fid
6357         local rec_list
6358         local rec
6359         local rec_type
6360         local obj_file
6361         local path
6362         local seq
6363         local oid
6364         local pass=true
6365
6366         #get fid and record list
6367         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6368                 tail -n 4))
6369         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6370                 tail -n 4))
6371         #remount mgs as ldiskfs or zfs type
6372         stop mgs || error "stop mgs failed"
6373         mount_fstype mgs || error "remount mgs failed"
6374         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6375                 fid=${fid_list[i]}
6376                 rec=${rec_list[i]}
6377                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6378                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6379                 oid=$((16#$oid))
6380
6381                 case $fstype in
6382                         ldiskfs )
6383                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6384                         zfs )
6385                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6386                 esac
6387                 echo "obj_file is $obj_file"
6388                 do_facet mgs $llog_reader $obj_file
6389
6390                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6391                         awk '{ print $3 }' | sed -e "s/^type=//g")
6392                 if [ $rec_type != $rec ]; then
6393                         echo "FAILED test_60a wrong record type $rec_type," \
6394                               "should be $rec"
6395                         pass=false
6396                         break
6397                 fi
6398
6399                 #check obj path if record type is LLOG_LOGID_MAGIC
6400                 if [ "$rec" == "1064553b" ]; then
6401                         path=$(do_facet mgs $llog_reader $obj_file |
6402                                 grep "path=" | awk '{ print $NF }' |
6403                                 sed -e "s/^path=//g")
6404                         if [ $obj_file != $mntpt/$path ]; then
6405                                 echo "FAILED test_60a wrong obj path" \
6406                                       "$montpt/$path, should be $obj_file"
6407                                 pass=false
6408                                 break
6409                         fi
6410                 fi
6411         done
6412         rm -f $TMP/$tfile
6413         #restart mgs before "error", otherwise it will block the next test
6414         stop mgs || error "stop mgs failed"
6415         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6416         $pass || error "test failed, see FAILED test_60a messages for specifics"
6417 }
6418 run_test 60a "llog_test run from kernel module and test llog_reader"
6419
6420 test_60b() { # bug 6411
6421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6422
6423         dmesg > $DIR/$tfile
6424         LLOG_COUNT=$(do_facet mgs dmesg |
6425                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6426                           /llog_[a-z]*.c:[0-9]/ {
6427                                 if (marker)
6428                                         from_marker++
6429                                 from_begin++
6430                           }
6431                           END {
6432                                 if (marker)
6433                                         print from_marker
6434                                 else
6435                                         print from_begin
6436                           }")
6437
6438         [[ $LLOG_COUNT -gt 120 ]] &&
6439                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6440 }
6441 run_test 60b "limit repeated messages from CERROR/CWARN"
6442
6443 test_60c() {
6444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6445
6446         echo "create 5000 files"
6447         createmany -o $DIR/f60c- 5000
6448 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6449         lctl set_param fail_loc=0x80000137
6450         unlinkmany $DIR/f60c- 5000
6451         lctl set_param fail_loc=0
6452 }
6453 run_test 60c "unlink file when mds full"
6454
6455 test_60d() {
6456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6457
6458         SAVEPRINTK=$(lctl get_param -n printk)
6459         # verify "lctl mark" is even working"
6460         MESSAGE="test message ID $RANDOM $$"
6461         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6462         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6463
6464         lctl set_param printk=0 || error "set lnet.printk failed"
6465         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6466         MESSAGE="new test message ID $RANDOM $$"
6467         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6468         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6469         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6470
6471         lctl set_param -n printk="$SAVEPRINTK"
6472 }
6473 run_test 60d "test printk console message masking"
6474
6475 test_60e() {
6476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6477         remote_mds_nodsh && skip "remote MDS with nodsh"
6478
6479         touch $DIR/$tfile
6480 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6481         do_facet mds1 lctl set_param fail_loc=0x15b
6482         rm $DIR/$tfile
6483 }
6484 run_test 60e "no space while new llog is being created"
6485
6486 test_60g() {
6487         local pid
6488
6489         test_mkdir -c $MDSCOUNT $DIR/$tdir
6490         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6491
6492         (
6493                 local index=0
6494                 while true; do
6495                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6496                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6497                         index=$((index + 1))
6498                 done
6499         ) &
6500
6501         pid=$!
6502
6503         for i in $(seq 100); do 
6504                 # define OBD_FAIL_OSD_TXN_START    0x19a
6505                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6506                 usleep 100
6507         done
6508
6509         kill -9 $pid
6510
6511         mkdir $DIR/$tdir/new || error "mkdir failed"
6512         rmdir $DIR/$tdir/new || error "rmdir failed"
6513 }
6514 run_test 60g "transaction abort won't cause MDT hung"
6515
6516 test_61a() {
6517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6518
6519         f="$DIR/f61"
6520         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6521         cancel_lru_locks osc
6522         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6523         sync
6524 }
6525 run_test 61a "mmap() writes don't make sync hang ================"
6526
6527 test_61b() {
6528         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6529 }
6530 run_test 61b "mmap() of unstriped file is successful"
6531
6532 # bug 2330 - insufficient obd_match error checking causes LBUG
6533 test_62() {
6534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6535
6536         f="$DIR/f62"
6537         echo foo > $f
6538         cancel_lru_locks osc
6539         lctl set_param fail_loc=0x405
6540         cat $f && error "cat succeeded, expect -EIO"
6541         lctl set_param fail_loc=0
6542 }
6543 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6544 # match every page all of the time.
6545 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6546
6547 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6548 # Though this test is irrelevant anymore, it helped to reveal some
6549 # other grant bugs (LU-4482), let's keep it.
6550 test_63a() {   # was test_63
6551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6552
6553         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6554
6555         for i in `seq 10` ; do
6556                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6557                 sleep 5
6558                 kill $!
6559                 sleep 1
6560         done
6561
6562         rm -f $DIR/f63 || true
6563 }
6564 run_test 63a "Verify oig_wait interruption does not crash ======="
6565
6566 # bug 2248 - async write errors didn't return to application on sync
6567 # bug 3677 - async write errors left page locked
6568 test_63b() {
6569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6570
6571         debugsave
6572         lctl set_param debug=-1
6573
6574         # ensure we have a grant to do async writes
6575         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6576         rm $DIR/$tfile
6577
6578         sync    # sync lest earlier test intercept the fail_loc
6579
6580         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6581         lctl set_param fail_loc=0x80000406
6582         $MULTIOP $DIR/$tfile Owy && \
6583                 error "sync didn't return ENOMEM"
6584         sync; sleep 2; sync     # do a real sync this time to flush page
6585         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6586                 error "locked page left in cache after async error" || true
6587         debugrestore
6588 }
6589 run_test 63b "async write errors should be returned to fsync ==="
6590
6591 test_64a () {
6592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6593
6594         df $DIR
6595         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6596 }
6597 run_test 64a "verify filter grant calculations (in kernel) ====="
6598
6599 test_64b () {
6600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6601
6602         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6603 }
6604 run_test 64b "check out-of-space detection on client"
6605
6606 test_64c() {
6607         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6608 }
6609 run_test 64c "verify grant shrink"
6610
6611 # this does exactly what osc_request.c:osc_announce_cached() does in
6612 # order to calculate max amount of grants to ask from server
6613 want_grant() {
6614         local tgt=$1
6615
6616         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6617         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6618
6619         ((rpc_in_flight ++));
6620         nrpages=$((nrpages * rpc_in_flight))
6621
6622         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6623
6624         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6625
6626         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6627         local undirty=$((nrpages * PAGE_SIZE))
6628
6629         local max_extent_pages
6630         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6631             grep grant_max_extent_size | awk '{print $2}')
6632         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6633         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6634         local grant_extent_tax
6635         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6636             grep grant_extent_tax | awk '{print $2}')
6637
6638         undirty=$((undirty + nrextents * grant_extent_tax))
6639
6640         echo $undirty
6641 }
6642
6643 # this is size of unit for grant allocation. It should be equal to
6644 # what tgt_grant.c:tgt_grant_chunk() calculates
6645 grant_chunk() {
6646         local tgt=$1
6647         local max_brw_size
6648         local grant_extent_tax
6649
6650         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6651             grep max_brw_size | awk '{print $2}')
6652
6653         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6654             grep grant_extent_tax | awk '{print $2}')
6655
6656         echo $(((max_brw_size + grant_extent_tax) * 2))
6657 }
6658
6659 test_64d() {
6660         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6661                 skip "OST < 2.10.55 doesn't limit grants enough"
6662
6663         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6664         local file=$DIR/$tfile
6665
6666         [[ $($LCTL get_param osc.${tgt}.import |
6667              grep "connect_flags:.*grant_param") ]] ||
6668                 skip "no grant_param connect flag"
6669
6670         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6671
6672         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6673
6674         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6675         stack_trap "rm -f $file" EXIT
6676
6677         $LFS setstripe $file -i 0 -c 1
6678         dd if=/dev/zero of=$file bs=1M count=1000 &
6679         ddpid=$!
6680
6681         while true
6682         do
6683                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6684                 if [[ $cur_grant -gt $max_cur_granted ]]
6685                 then
6686                         kill $ddpid
6687                         error "cur_grant $cur_grant > $max_cur_granted"
6688                 fi
6689                 kill -0 $ddpid
6690                 [[ $? -ne 0 ]] && break;
6691                 sleep 2
6692         done
6693
6694         rm -f $DIR/$tfile
6695         wait_delete_completed
6696         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6697 }
6698 run_test 64d "check grant limit exceed"
6699
6700 # bug 1414 - set/get directories' stripe info
6701 test_65a() {
6702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6703
6704         test_mkdir $DIR/$tdir
6705         touch $DIR/$tdir/f1
6706         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6707 }
6708 run_test 65a "directory with no stripe info"
6709
6710 test_65b() {
6711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6712
6713         test_mkdir $DIR/$tdir
6714         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6715
6716         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6717                                                 error "setstripe"
6718         touch $DIR/$tdir/f2
6719         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6720 }
6721 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6722
6723 test_65c() {
6724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6725         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6726
6727         test_mkdir $DIR/$tdir
6728         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6729
6730         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6731                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6732         touch $DIR/$tdir/f3
6733         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6734 }
6735 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6736
6737 test_65d() {
6738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6739
6740         test_mkdir $DIR/$tdir
6741         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6742         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6743
6744         if [[ $STRIPECOUNT -le 0 ]]; then
6745                 sc=1
6746         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6747 #LOV_MAX_STRIPE_COUNT is 2000
6748                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6749         else
6750                 sc=$(($STRIPECOUNT - 1))
6751         fi
6752         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6753         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6754         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6755                 error "lverify failed"
6756 }
6757 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6758
6759 test_65e() {
6760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6761
6762         test_mkdir $DIR/$tdir
6763
6764         $LFS setstripe $DIR/$tdir || error "setstripe"
6765         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6766                                         error "no stripe info failed"
6767         touch $DIR/$tdir/f6
6768         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6769 }
6770 run_test 65e "directory setstripe defaults"
6771
6772 test_65f() {
6773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6774
6775         test_mkdir $DIR/${tdir}f
6776         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6777                 error "setstripe succeeded" || true
6778 }
6779 run_test 65f "dir setstripe permission (should return error) ==="
6780
6781 test_65g() {
6782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6783
6784         test_mkdir $DIR/$tdir
6785         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6786
6787         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6788                 error "setstripe -S failed"
6789         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6790         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6791                 error "delete default stripe failed"
6792 }
6793 run_test 65g "directory setstripe -d"
6794
6795 test_65h() {
6796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6797
6798         test_mkdir $DIR/$tdir
6799         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6800
6801         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6802                 error "setstripe -S failed"
6803         test_mkdir $DIR/$tdir/dd1
6804         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6805                 error "stripe info inherit failed"
6806 }
6807 run_test 65h "directory stripe info inherit ===================="
6808
6809 test_65i() {
6810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6811
6812         save_layout_restore_at_exit $MOUNT
6813
6814         # bug6367: set non-default striping on root directory
6815         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6816
6817         # bug12836: getstripe on -1 default directory striping
6818         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6819
6820         # bug12836: getstripe -v on -1 default directory striping
6821         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6822
6823         # bug12836: new find on -1 default directory striping
6824         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6825 }
6826 run_test 65i "various tests to set root directory striping"
6827
6828 test_65j() { # bug6367
6829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6830
6831         sync; sleep 1
6832
6833         # if we aren't already remounting for each test, do so for this test
6834         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6835                 cleanup || error "failed to unmount"
6836                 setup
6837         fi
6838
6839         save_layout_restore_at_exit $MOUNT
6840
6841         $LFS setstripe -d $MOUNT || error "setstripe failed"
6842 }
6843 run_test 65j "set default striping on root directory (bug 6367)="
6844
6845 cleanup_65k() {
6846         rm -rf $DIR/$tdir
6847         wait_delete_completed
6848         do_facet $SINGLEMDS "lctl set_param -n \
6849                 osp.$ost*MDT0000.max_create_count=$max_count"
6850         do_facet $SINGLEMDS "lctl set_param -n \
6851                 osp.$ost*MDT0000.create_count=$count"
6852         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6853         echo $INACTIVE_OSC "is Activate"
6854
6855         wait_osc_import_state mds ost$ostnum FULL
6856 }
6857
6858 test_65k() { # bug11679
6859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6861         remote_mds_nodsh && skip "remote MDS with nodsh"
6862
6863         local disable_precreate=true
6864         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6865                 disable_precreate=false
6866
6867         echo "Check OST status: "
6868         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6869                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6870
6871         for OSC in $MDS_OSCS; do
6872                 echo $OSC "is active"
6873                 do_facet $SINGLEMDS lctl --device %$OSC activate
6874         done
6875
6876         for INACTIVE_OSC in $MDS_OSCS; do
6877                 local ost=$(osc_to_ost $INACTIVE_OSC)
6878                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6879                                lov.*md*.target_obd |
6880                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6881
6882                 mkdir -p $DIR/$tdir
6883                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6884                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6885
6886                 echo "Deactivate: " $INACTIVE_OSC
6887                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6888
6889                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6890                               osp.$ost*MDT0000.create_count")
6891                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6892                                   osp.$ost*MDT0000.max_create_count")
6893                 $disable_precreate &&
6894                         do_facet $SINGLEMDS "lctl set_param -n \
6895                                 osp.$ost*MDT0000.max_create_count=0"
6896
6897                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6898                         [ -f $DIR/$tdir/$idx ] && continue
6899                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6900                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6901                                 { cleanup_65k;
6902                                   error "setstripe $idx should succeed"; }
6903                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6904                 done
6905                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6906                 rmdir $DIR/$tdir
6907
6908                 do_facet $SINGLEMDS "lctl set_param -n \
6909                         osp.$ost*MDT0000.max_create_count=$max_count"
6910                 do_facet $SINGLEMDS "lctl set_param -n \
6911                         osp.$ost*MDT0000.create_count=$count"
6912                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6913                 echo $INACTIVE_OSC "is Activate"
6914
6915                 wait_osc_import_state mds ost$ostnum FULL
6916         done
6917 }
6918 run_test 65k "validate manual striping works properly with deactivated OSCs"
6919
6920 test_65l() { # bug 12836
6921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6922
6923         test_mkdir -p $DIR/$tdir/test_dir
6924         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6925         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6926 }
6927 run_test 65l "lfs find on -1 stripe dir ========================"
6928
6929 test_65m() {
6930         local layout=$(save_layout $MOUNT)
6931         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6932                 restore_layout $MOUNT $layout
6933                 error "setstripe should fail by non-root users"
6934         }
6935         true
6936 }
6937 run_test 65m "normal user can't set filesystem default stripe"
6938
6939 test_65n() {
6940         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6941         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6942                 skip "Need MDS version at least 2.12.50"
6943         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6944
6945         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6946         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6947         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6948
6949         local root_layout=$(save_layout $MOUNT)
6950         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6951
6952         # new subdirectory under root directory should not inherit
6953         # the default layout from root
6954         local dir1=$MOUNT/$tdir-1
6955         mkdir $dir1 || error "mkdir $dir1 failed"
6956         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6957                 error "$dir1 shouldn't have LOV EA"
6958
6959         # delete the default layout on root directory
6960         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6961
6962         local dir2=$MOUNT/$tdir-2
6963         mkdir $dir2 || error "mkdir $dir2 failed"
6964         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6965                 error "$dir2 shouldn't have LOV EA"
6966
6967         # set a new striping pattern on root directory
6968         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6969         local new_def_stripe_size=$((def_stripe_size * 2))
6970         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6971                 error "set stripe size on $MOUNT failed"
6972
6973         # new file created in $dir2 should inherit the new stripe size from
6974         # the filesystem default
6975         local file2=$dir2/$tfile-2
6976         touch $file2 || error "touch $file2 failed"
6977
6978         local file2_stripe_size=$($LFS getstripe -S $file2)
6979         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6980                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6981
6982         local dir3=$MOUNT/$tdir-3
6983         mkdir $dir3 || error "mkdir $dir3 failed"
6984         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6985                 error "$dir3 shouldn't have LOV EA"
6986
6987         # set OST pool on root directory
6988         local pool=$TESTNAME
6989         pool_add $pool || error "add $pool failed"
6990         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6991                 error "add targets to $pool failed"
6992
6993         $LFS setstripe -p $pool $MOUNT ||
6994                 error "set OST pool on $MOUNT failed"
6995
6996         # new file created in $dir3 should inherit the pool from
6997         # the filesystem default
6998         local file3=$dir3/$tfile-3
6999         touch $file3 || error "touch $file3 failed"
7000
7001         local file3_pool=$($LFS getstripe -p $file3)
7002         [[ "$file3_pool" = "$pool" ]] ||
7003                 error "$file3 didn't inherit OST pool $pool"
7004
7005         local dir4=$MOUNT/$tdir-4
7006         mkdir $dir4 || error "mkdir $dir4 failed"
7007         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7008                 error "$dir4 shouldn't have LOV EA"
7009
7010         # new file created in $dir4 should inherit the pool from
7011         # the filesystem default
7012         local file4=$dir4/$tfile-4
7013         touch $file4 || error "touch $file4 failed"
7014
7015         local file4_pool=$($LFS getstripe -p $file4)
7016         [[ "$file4_pool" = "$pool" ]] ||
7017                 error "$file4 didn't inherit OST pool $pool"
7018
7019         # new subdirectory under non-root directory should inherit
7020         # the default layout from its parent directory
7021         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7022                 error "set directory layout on $dir4 failed"
7023
7024         local dir5=$dir4/$tdir-5
7025         mkdir $dir5 || error "mkdir $dir5 failed"
7026
7027         local dir4_layout=$(get_layout_param $dir4)
7028         local dir5_layout=$(get_layout_param $dir5)
7029         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7030                 error "$dir5 should inherit the default layout from $dir4"
7031 }
7032 run_test 65n "don't inherit default layout from root for new subdirectories"
7033
7034 # bug 2543 - update blocks count on client
7035 test_66() {
7036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7037
7038         COUNT=${COUNT:-8}
7039         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7040         sync; sync_all_data; sync; sync_all_data
7041         cancel_lru_locks osc
7042         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7043         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7044 }
7045 run_test 66 "update inode blocks count on client ==============="
7046
7047 meminfo() {
7048         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7049 }
7050
7051 swap_used() {
7052         swapon -s | awk '($1 == "'$1'") { print $4 }'
7053 }
7054
7055 # bug5265, obdfilter oa2dentry return -ENOENT
7056 # #define OBD_FAIL_SRV_ENOENT 0x217
7057 test_69() {
7058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7059         remote_ost_nodsh && skip "remote OST with nodsh"
7060
7061         f="$DIR/$tfile"
7062         $LFS setstripe -c 1 -i 0 $f
7063
7064         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7065
7066         do_facet ost1 lctl set_param fail_loc=0x217
7067         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7068         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7069
7070         do_facet ost1 lctl set_param fail_loc=0
7071         $DIRECTIO write $f 0 2 || error "write error"
7072
7073         cancel_lru_locks osc
7074         $DIRECTIO read $f 0 1 || error "read error"
7075
7076         do_facet ost1 lctl set_param fail_loc=0x217
7077         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7078
7079         do_facet ost1 lctl set_param fail_loc=0
7080         rm -f $f
7081 }
7082 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7083
7084 test_71() {
7085         test_mkdir $DIR/$tdir
7086         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7087         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7088 }
7089 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7090
7091 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7093         [ "$RUNAS_ID" = "$UID" ] &&
7094                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7095         # Check that testing environment is properly set up. Skip if not
7096         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7097                 skip_env "User $RUNAS_ID does not exist - skipping"
7098
7099         touch $DIR/$tfile
7100         chmod 777 $DIR/$tfile
7101         chmod ug+s $DIR/$tfile
7102         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7103                 error "$RUNAS dd $DIR/$tfile failed"
7104         # See if we are still setuid/sgid
7105         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7106                 error "S/gid is not dropped on write"
7107         # Now test that MDS is updated too
7108         cancel_lru_locks mdc
7109         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7110                 error "S/gid is not dropped on MDS"
7111         rm -f $DIR/$tfile
7112 }
7113 run_test 72a "Test that remove suid works properly (bug5695) ===="
7114
7115 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7116         local perm
7117
7118         [ "$RUNAS_ID" = "$UID" ] &&
7119                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7120         [ "$RUNAS_ID" -eq 0 ] &&
7121                 skip_env "RUNAS_ID = 0 -- skipping"
7122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7123         # Check that testing environment is properly set up. Skip if not
7124         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7125                 skip_env "User $RUNAS_ID does not exist - skipping"
7126
7127         touch $DIR/${tfile}-f{g,u}
7128         test_mkdir $DIR/${tfile}-dg
7129         test_mkdir $DIR/${tfile}-du
7130         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7131         chmod g+s $DIR/${tfile}-{f,d}g
7132         chmod u+s $DIR/${tfile}-{f,d}u
7133         for perm in 777 2777 4777; do
7134                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7135                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7136                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7137                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7138         done
7139         true
7140 }
7141 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7142
7143 # bug 3462 - multiple simultaneous MDC requests
7144 test_73() {
7145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7146
7147         test_mkdir $DIR/d73-1
7148         test_mkdir $DIR/d73-2
7149         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7150         pid1=$!
7151
7152         lctl set_param fail_loc=0x80000129
7153         $MULTIOP $DIR/d73-1/f73-2 Oc &
7154         sleep 1
7155         lctl set_param fail_loc=0
7156
7157         $MULTIOP $DIR/d73-2/f73-3 Oc &
7158         pid3=$!
7159
7160         kill -USR1 $pid1
7161         wait $pid1 || return 1
7162
7163         sleep 25
7164
7165         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7166         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7167         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7168
7169         rm -rf $DIR/d73-*
7170 }
7171 run_test 73 "multiple MDC requests (should not deadlock)"
7172
7173 test_74a() { # bug 6149, 6184
7174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7175
7176         touch $DIR/f74a
7177         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7178         #
7179         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7180         # will spin in a tight reconnection loop
7181         $LCTL set_param fail_loc=0x8000030e
7182         # get any lock that won't be difficult - lookup works.
7183         ls $DIR/f74a
7184         $LCTL set_param fail_loc=0
7185         rm -f $DIR/f74a
7186         true
7187 }
7188 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7189
7190 test_74b() { # bug 13310
7191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7192
7193         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7194         #
7195         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7196         # will spin in a tight reconnection loop
7197         $LCTL set_param fail_loc=0x8000030e
7198         # get a "difficult" lock
7199         touch $DIR/f74b
7200         $LCTL set_param fail_loc=0
7201         rm -f $DIR/f74b
7202         true
7203 }
7204 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7205
7206 test_74c() {
7207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7208
7209         #define OBD_FAIL_LDLM_NEW_LOCK
7210         $LCTL set_param fail_loc=0x319
7211         touch $DIR/$tfile && error "touch successful"
7212         $LCTL set_param fail_loc=0
7213         true
7214 }
7215 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7216
7217 num_inodes() {
7218         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7219 }
7220
7221 test_76() { # Now for bug 20433, added originally in bug 1443
7222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7223
7224         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7225
7226         cancel_lru_locks osc
7227         BEFORE_INODES=$(num_inodes)
7228         echo "before inodes: $BEFORE_INODES"
7229         local COUNT=1000
7230         [ "$SLOW" = "no" ] && COUNT=100
7231         for i in $(seq $COUNT); do
7232                 touch $DIR/$tfile
7233                 rm -f $DIR/$tfile
7234         done
7235         cancel_lru_locks osc
7236         AFTER_INODES=$(num_inodes)
7237         echo "after inodes: $AFTER_INODES"
7238         local wait=0
7239         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7240                 sleep 2
7241                 AFTER_INODES=$(num_inodes)
7242                 wait=$((wait+2))
7243                 echo "wait $wait seconds inodes: $AFTER_INODES"
7244                 if [ $wait -gt 30 ]; then
7245                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7246                 fi
7247         done
7248 }
7249 run_test 76 "confirm clients recycle inodes properly ===="
7250
7251
7252 export ORIG_CSUM=""
7253 set_checksums()
7254 {
7255         # Note: in sptlrpc modes which enable its own bulk checksum, the
7256         # original crc32_le bulk checksum will be automatically disabled,
7257         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7258         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7259         # In this case set_checksums() will not be no-op, because sptlrpc
7260         # bulk checksum will be enabled all through the test.
7261
7262         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7263         lctl set_param -n osc.*.checksums $1
7264         return 0
7265 }
7266
7267 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7268                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7269 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7270                              tr -d [] | head -n1)}
7271 set_checksum_type()
7272 {
7273         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7274         log "set checksum type to $1"
7275         return 0
7276 }
7277 F77_TMP=$TMP/f77-temp
7278 F77SZ=8
7279 setup_f77() {
7280         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7281                 error "error writing to $F77_TMP"
7282 }
7283
7284 test_77a() { # bug 10889
7285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7286         $GSS && skip_env "could not run with gss"
7287
7288         [ ! -f $F77_TMP ] && setup_f77
7289         set_checksums 1
7290         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7291         set_checksums 0
7292         rm -f $DIR/$tfile
7293 }
7294 run_test 77a "normal checksum read/write operation"
7295
7296 test_77b() { # bug 10889
7297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7298         $GSS && skip_env "could not run with gss"
7299
7300         [ ! -f $F77_TMP ] && setup_f77
7301         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7302         $LCTL set_param fail_loc=0x80000409
7303         set_checksums 1
7304
7305         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7306                 error "dd error: $?"
7307         $LCTL set_param fail_loc=0
7308
7309         for algo in $CKSUM_TYPES; do
7310                 cancel_lru_locks osc
7311                 set_checksum_type $algo
7312                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7313                 $LCTL set_param fail_loc=0x80000408
7314                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7315                 $LCTL set_param fail_loc=0
7316         done
7317         set_checksums 0
7318         set_checksum_type $ORIG_CSUM_TYPE
7319         rm -f $DIR/$tfile
7320 }
7321 run_test 77b "checksum error on client write, read"
7322
7323 cleanup_77c() {
7324         trap 0
7325         set_checksums 0
7326         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7327         $check_ost &&
7328                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7329         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7330         $check_ost && [ -n "$ost_file_prefix" ] &&
7331                 do_facet ost1 rm -f ${ost_file_prefix}\*
7332 }
7333
7334 test_77c() {
7335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7336         $GSS && skip_env "could not run with gss"
7337         remote_ost_nodsh && skip "remote OST with nodsh"
7338
7339         local bad1
7340         local osc_file_prefix
7341         local osc_file
7342         local check_ost=false
7343         local ost_file_prefix
7344         local ost_file
7345         local orig_cksum
7346         local dump_cksum
7347         local fid
7348
7349         # ensure corruption will occur on first OSS/OST
7350         $LFS setstripe -i 0 $DIR/$tfile
7351
7352         [ ! -f $F77_TMP ] && setup_f77
7353         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7354                 error "dd write error: $?"
7355         fid=$($LFS path2fid $DIR/$tfile)
7356
7357         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7358         then
7359                 check_ost=true
7360                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7361                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7362         else
7363                 echo "OSS do not support bulk pages dump upon error"
7364         fi
7365
7366         osc_file_prefix=$($LCTL get_param -n debug_path)
7367         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7368
7369         trap cleanup_77c EXIT
7370
7371         set_checksums 1
7372         # enable bulk pages dump upon error on Client
7373         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7374         # enable bulk pages dump upon error on OSS
7375         $check_ost &&
7376                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7377
7378         # flush Client cache to allow next read to reach OSS
7379         cancel_lru_locks osc
7380
7381         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7382         $LCTL set_param fail_loc=0x80000408
7383         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7384         $LCTL set_param fail_loc=0
7385
7386         rm -f $DIR/$tfile
7387
7388         # check cksum dump on Client
7389         osc_file=$(ls ${osc_file_prefix}*)
7390         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7391         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7392         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7393         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7394         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7395                      cksum)
7396         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7397         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7398                 error "dump content does not match on Client"
7399
7400         $check_ost || skip "No need to check cksum dump on OSS"
7401
7402         # check cksum dump on OSS
7403         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7404         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7405         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7406         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7407         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7408                 error "dump content does not match on OSS"
7409
7410         cleanup_77c
7411 }
7412 run_test 77c "checksum error on client read with debug"
7413
7414 test_77d() { # bug 10889
7415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7416         $GSS && skip_env "could not run with gss"
7417
7418         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7419         $LCTL set_param fail_loc=0x80000409
7420         set_checksums 1
7421         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7422                 error "direct write: rc=$?"
7423         $LCTL set_param fail_loc=0
7424         set_checksums 0
7425
7426         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7427         $LCTL set_param fail_loc=0x80000408
7428         set_checksums 1
7429         cancel_lru_locks osc
7430         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7431                 error "direct read: rc=$?"
7432         $LCTL set_param fail_loc=0
7433         set_checksums 0
7434 }
7435 run_test 77d "checksum error on OST direct write, read"
7436
7437 test_77f() { # bug 10889
7438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7439         $GSS && skip_env "could not run with gss"
7440
7441         set_checksums 1
7442         for algo in $CKSUM_TYPES; do
7443                 cancel_lru_locks osc
7444                 set_checksum_type $algo
7445                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7446                 $LCTL set_param fail_loc=0x409
7447                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7448                         error "direct write succeeded"
7449                 $LCTL set_param fail_loc=0
7450         done
7451         set_checksum_type $ORIG_CSUM_TYPE
7452         set_checksums 0
7453 }
7454 run_test 77f "repeat checksum error on write (expect error)"
7455
7456 test_77g() { # bug 10889
7457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7458         $GSS && skip_env "could not run with gss"
7459         remote_ost_nodsh && skip "remote OST with nodsh"
7460
7461         [ ! -f $F77_TMP ] && setup_f77
7462
7463         local file=$DIR/$tfile
7464         stack_trap "rm -f $file" EXIT
7465
7466         $LFS setstripe -c 1 -i 0 $file
7467         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7468         do_facet ost1 lctl set_param fail_loc=0x8000021a
7469         set_checksums 1
7470         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7471                 error "write error: rc=$?"
7472         do_facet ost1 lctl set_param fail_loc=0
7473         set_checksums 0
7474
7475         cancel_lru_locks osc
7476         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7477         do_facet ost1 lctl set_param fail_loc=0x8000021b
7478         set_checksums 1
7479         cmp $F77_TMP $file || error "file compare failed"
7480         do_facet ost1 lctl set_param fail_loc=0
7481         set_checksums 0
7482 }
7483 run_test 77g "checksum error on OST write, read"
7484
7485 test_77k() { # LU-10906
7486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7487         $GSS && skip_env "could not run with gss"
7488
7489         local cksum_param="osc.$FSNAME*.checksums"
7490         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7491         local checksum
7492         local i
7493
7494         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7495         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7496         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7497                 EXIT
7498
7499         for i in 0 1; do
7500                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7501                         error "failed to set checksum=$i on MGS"
7502                 wait_update $HOSTNAME "$get_checksum" $i
7503                 #remount
7504                 echo "remount client, checksum should be $i"
7505                 remount_client $MOUNT || "failed to remount client"
7506                 checksum=$(eval $get_checksum)
7507                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7508         done
7509         # remove persistent param to avoid races with checksum mountopt below
7510         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7511                 error "failed to delete checksum on MGS"
7512
7513         for opt in "checksum" "nochecksum"; do
7514                 #remount with mount option
7515                 echo "remount client with option $opt, checksum should be $i"
7516                 umount_client $MOUNT || "failed to umount client"
7517                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7518                         "failed to mount client with option '$opt'"
7519                 checksum=$(eval $get_checksum)
7520                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7521                 i=$((i - 1))
7522         done
7523
7524         remount_client $MOUNT || "failed to remount client"
7525 }
7526 run_test 77k "enable/disable checksum correctly"
7527
7528 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7529 rm -f $F77_TMP
7530 unset F77_TMP
7531
7532 cleanup_test_78() {
7533         trap 0
7534         rm -f $DIR/$tfile
7535 }
7536
7537 test_78() { # bug 10901
7538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7539         remote_ost || skip_env "local OST"
7540
7541         NSEQ=5
7542         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7543         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7544         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7545         echo "MemTotal: $MEMTOTAL"
7546
7547         # reserve 256MB of memory for the kernel and other running processes,
7548         # and then take 1/2 of the remaining memory for the read/write buffers.
7549         if [ $MEMTOTAL -gt 512 ] ;then
7550                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7551         else
7552                 # for those poor memory-starved high-end clusters...
7553                 MEMTOTAL=$((MEMTOTAL / 2))
7554         fi
7555         echo "Mem to use for directio: $MEMTOTAL"
7556
7557         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7558         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7559         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7560         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7561                 head -n1)
7562         echo "Smallest OST: $SMALLESTOST"
7563         [[ $SMALLESTOST -lt 10240 ]] &&
7564                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7565
7566         trap cleanup_test_78 EXIT
7567
7568         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7569                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7570
7571         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7572         echo "File size: $F78SIZE"
7573         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7574         for i in $(seq 1 $NSEQ); do
7575                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7576                 echo directIO rdwr round $i of $NSEQ
7577                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7578         done
7579
7580         cleanup_test_78
7581 }
7582 run_test 78 "handle large O_DIRECT writes correctly ============"
7583
7584 test_79() { # bug 12743
7585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7586
7587         wait_delete_completed
7588
7589         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7590         BKFREE=$(calc_osc_kbytes kbytesfree)
7591         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7592
7593         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7594         DFTOTAL=`echo $STRING | cut -d, -f1`
7595         DFUSED=`echo $STRING  | cut -d, -f2`
7596         DFAVAIL=`echo $STRING | cut -d, -f3`
7597         DFFREE=$(($DFTOTAL - $DFUSED))
7598
7599         ALLOWANCE=$((64 * $OSTCOUNT))
7600
7601         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7602            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7603                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7604         fi
7605         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7606            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7607                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7608         fi
7609         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7610            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7611                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7612         fi
7613 }
7614 run_test 79 "df report consistency check ======================="
7615
7616 test_80() { # bug 10718
7617         remote_ost_nodsh && skip "remote OST with nodsh"
7618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7619
7620         # relax strong synchronous semantics for slow backends like ZFS
7621         local soc="obdfilter.*.sync_on_lock_cancel"
7622         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7623         local hosts=
7624         if [ "$soc_old" != "never" ] &&
7625                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7626                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7627                                 facet_active_host $host; done | sort -u)
7628                         do_nodes $hosts lctl set_param $soc=never
7629         fi
7630
7631         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7632         sync; sleep 1; sync
7633         local BEFORE=`date +%s`
7634         cancel_lru_locks osc
7635         local AFTER=`date +%s`
7636         local DIFF=$((AFTER-BEFORE))
7637         if [ $DIFF -gt 1 ] ; then
7638                 error "elapsed for 1M@1T = $DIFF"
7639         fi
7640
7641         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7642
7643         rm -f $DIR/$tfile
7644 }
7645 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7646
7647 test_81a() { # LU-456
7648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7649         remote_ost_nodsh && skip "remote OST with nodsh"
7650
7651         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7652         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7653         do_facet ost1 lctl set_param fail_loc=0x80000228
7654
7655         # write should trigger a retry and success
7656         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7657         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7658         RC=$?
7659         if [ $RC -ne 0 ] ; then
7660                 error "write should success, but failed for $RC"
7661         fi
7662 }
7663 run_test 81a "OST should retry write when get -ENOSPC ==============="
7664
7665 test_81b() { # LU-456
7666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7667         remote_ost_nodsh && skip "remote OST with nodsh"
7668
7669         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7670         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7671         do_facet ost1 lctl set_param fail_loc=0x228
7672
7673         # write should retry several times and return -ENOSPC finally
7674         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7676         RC=$?
7677         ENOSPC=28
7678         if [ $RC -ne $ENOSPC ] ; then
7679                 error "dd should fail for -ENOSPC, but succeed."
7680         fi
7681 }
7682 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7683
7684 test_82() { # LU-1031
7685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7686         local gid1=14091995
7687         local gid2=16022000
7688
7689         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7690         local MULTIPID1=$!
7691         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7692         local MULTIPID2=$!
7693         kill -USR1 $MULTIPID2
7694         sleep 2
7695         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7696                 error "First grouplock does not block second one"
7697         else
7698                 echo "Second grouplock blocks first one"
7699         fi
7700         kill -USR1 $MULTIPID1
7701         wait $MULTIPID1
7702         wait $MULTIPID2
7703 }
7704 run_test 82 "Basic grouplock test"
7705
7706 test_99() {
7707         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7708
7709         test_mkdir $DIR/$tdir.cvsroot
7710         chown $RUNAS_ID $DIR/$tdir.cvsroot
7711
7712         cd $TMP
7713         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7714
7715         cd /etc/init.d
7716         # some versions of cvs import exit(1) when asked to import links or
7717         # files they can't read.  ignore those files.
7718         local toignore=$(find . -type l -printf '-I %f\n' -o \
7719                          ! -perm /4 -printf '-I %f\n')
7720         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7721                 $tdir.reposname vtag rtag
7722
7723         cd $DIR
7724         test_mkdir $DIR/$tdir.reposname
7725         chown $RUNAS_ID $DIR/$tdir.reposname
7726         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7727
7728         cd $DIR/$tdir.reposname
7729         $RUNAS touch foo99
7730         $RUNAS cvs add -m 'addmsg' foo99
7731         $RUNAS cvs update
7732         $RUNAS cvs commit -m 'nomsg' foo99
7733         rm -fr $DIR/$tdir.cvsroot
7734 }
7735 run_test 99 "cvs strange file/directory operations"
7736
7737 test_100() {
7738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7739         [[ "$NETTYPE" =~ tcp ]] ||
7740                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7741         remote_ost_nodsh && skip "remote OST with nodsh"
7742         remote_mds_nodsh && skip "remote MDS with nodsh"
7743         remote_servers ||
7744                 skip "useless for local single node setup"
7745
7746         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7747                 [ "$PROT" != "tcp" ] && continue
7748                 RPORT=$(echo $REMOTE | cut -d: -f2)
7749                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7750
7751                 rc=0
7752                 LPORT=`echo $LOCAL | cut -d: -f2`
7753                 if [ $LPORT -ge 1024 ]; then
7754                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7755                         netstat -tna
7756                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7757                 fi
7758         done
7759         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7760 }
7761 run_test 100 "check local port using privileged port ==========="
7762
7763 function get_named_value()
7764 {
7765     local tag
7766
7767     tag=$1
7768     while read ;do
7769         line=$REPLY
7770         case $line in
7771         $tag*)
7772             echo $line | sed "s/^$tag[ ]*//"
7773             break
7774             ;;
7775         esac
7776     done
7777 }
7778
7779 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7780                    awk '/^max_cached_mb/ { print $2 }')
7781
7782 cleanup_101a() {
7783         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7784         trap 0
7785 }
7786
7787 test_101a() {
7788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7789         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7790
7791         local s
7792         local discard
7793         local nreads=10000
7794         local cache_limit=32
7795
7796         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7797         trap cleanup_101a EXIT
7798         $LCTL set_param -n llite.*.read_ahead_stats 0
7799         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7800
7801         #
7802         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7803         #
7804         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7805         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7806
7807         discard=0
7808         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7809                 get_named_value 'read but discarded' | cut -d" " -f1); do
7810                         discard=$(($discard + $s))
7811         done
7812         cleanup_101a
7813
7814         if [[ $(($discard * 10)) -gt $nreads ]]; then
7815                 $LCTL get_param osc.*-osc*.rpc_stats
7816                 $LCTL get_param llite.*.read_ahead_stats
7817                 error "too many ($discard) discarded pages"
7818         fi
7819         rm -f $DIR/$tfile || true
7820 }
7821 run_test 101a "check read-ahead for random reads"
7822
7823 setup_test101bc() {
7824         test_mkdir $DIR/$tdir
7825         local ssize=$1
7826         local FILE_LENGTH=$2
7827         STRIPE_OFFSET=0
7828
7829         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7830
7831         local list=$(comma_list $(osts_nodes))
7832         set_osd_param $list '' read_cache_enable 0
7833         set_osd_param $list '' writethrough_cache_enable 0
7834
7835         trap cleanup_test101bc EXIT
7836         # prepare the read-ahead file
7837         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7838
7839         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7840                                 count=$FILE_SIZE_MB 2> /dev/null
7841
7842 }
7843
7844 cleanup_test101bc() {
7845         trap 0
7846         rm -rf $DIR/$tdir
7847         rm -f $DIR/$tfile
7848
7849         local list=$(comma_list $(osts_nodes))
7850         set_osd_param $list '' read_cache_enable 1
7851         set_osd_param $list '' writethrough_cache_enable 1
7852 }
7853
7854 calc_total() {
7855         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7856 }
7857
7858 ra_check_101() {
7859         local READ_SIZE=$1
7860         local STRIPE_SIZE=$2
7861         local FILE_LENGTH=$3
7862         local RA_INC=1048576
7863         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7864         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7865                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7866         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7867                         get_named_value 'read but discarded' |
7868                         cut -d" " -f1 | calc_total)
7869         if [[ $DISCARD -gt $discard_limit ]]; then
7870                 $LCTL get_param llite.*.read_ahead_stats
7871                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7872         else
7873                 echo "Read-ahead success for size ${READ_SIZE}"
7874         fi
7875 }
7876
7877 test_101b() {
7878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7880
7881         local STRIPE_SIZE=1048576
7882         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7883
7884         if [ $SLOW == "yes" ]; then
7885                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7886         else
7887                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7888         fi
7889
7890         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7891
7892         # prepare the read-ahead file
7893         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7894         cancel_lru_locks osc
7895         for BIDX in 2 4 8 16 32 64 128 256
7896         do
7897                 local BSIZE=$((BIDX*4096))
7898                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7899                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7900                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7901                 $LCTL set_param -n llite.*.read_ahead_stats 0
7902                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7903                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7904                 cancel_lru_locks osc
7905                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7906         done
7907         cleanup_test101bc
7908         true
7909 }
7910 run_test 101b "check stride-io mode read-ahead ================="
7911
7912 test_101c() {
7913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7914
7915         local STRIPE_SIZE=1048576
7916         local FILE_LENGTH=$((STRIPE_SIZE*100))
7917         local nreads=10000
7918         local rsize=65536
7919         local osc_rpc_stats
7920
7921         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7922
7923         cancel_lru_locks osc
7924         $LCTL set_param osc.*.rpc_stats 0
7925         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7926         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7927                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7928                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7929                 local size
7930
7931                 if [ $lines -le 20 ]; then
7932                         continue
7933                 fi
7934                 for size in 1 2 4 8; do
7935                         local rpc=$(echo "$stats" |
7936                                     awk '($1 == "'$size':") {print $2; exit; }')
7937                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7938                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7939                 done
7940                 echo "$osc_rpc_stats check passed!"
7941         done
7942         cleanup_test101bc
7943         true
7944 }
7945 run_test 101c "check stripe_size aligned read-ahead ================="
7946
7947 set_read_ahead() {
7948         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7949         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7950 }
7951
7952 test_101d() {
7953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7954
7955         local file=$DIR/$tfile
7956         local sz_MB=${FILESIZE_101d:-500}
7957         local ra_MB=${READAHEAD_MB:-40}
7958
7959         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7960         [ $free_MB -lt $sz_MB ] &&
7961                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7962
7963         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7964         $LFS setstripe -c -1 $file || error "setstripe failed"
7965
7966         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7967         echo Cancel LRU locks on lustre client to flush the client cache
7968         cancel_lru_locks osc
7969
7970         echo Disable read-ahead
7971         local old_READAHEAD=$(set_read_ahead 0)
7972
7973         echo Reading the test file $file with read-ahead disabled
7974         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7975
7976         echo Cancel LRU locks on lustre client to flush the client cache
7977         cancel_lru_locks osc
7978         echo Enable read-ahead with ${ra_MB}MB
7979         set_read_ahead $ra_MB
7980
7981         echo Reading the test file $file with read-ahead enabled
7982         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7983
7984         echo "read-ahead disabled time read $raOFF"
7985         echo "read-ahead enabled  time read $raON"
7986
7987         set_read_ahead $old_READAHEAD
7988         rm -f $file
7989         wait_delete_completed
7990
7991         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
7992                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7993 }
7994 run_test 101d "file read with and without read-ahead enabled"
7995
7996 test_101e() {
7997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7998
7999         local file=$DIR/$tfile
8000         local size_KB=500  #KB
8001         local count=100
8002         local bsize=1024
8003
8004         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8005         local need_KB=$((count * size_KB))
8006         [[ $free_KB -le $need_KB ]] &&
8007                 skip_env "Need free space $need_KB, have $free_KB"
8008
8009         echo "Creating $count ${size_KB}K test files"
8010         for ((i = 0; i < $count; i++)); do
8011                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8012         done
8013
8014         echo "Cancel LRU locks on lustre client to flush the client cache"
8015         cancel_lru_locks $OSC
8016
8017         echo "Reset readahead stats"
8018         $LCTL set_param -n llite.*.read_ahead_stats 0
8019
8020         for ((i = 0; i < $count; i++)); do
8021                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8022         done
8023
8024         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8025                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8026
8027         for ((i = 0; i < $count; i++)); do
8028                 rm -rf $file.$i 2>/dev/null
8029         done
8030
8031         #10000 means 20% reads are missing in readahead
8032         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8033 }
8034 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8035
8036 test_101f() {
8037         which iozone || skip_env "no iozone installed"
8038
8039         local old_debug=$($LCTL get_param debug)
8040         old_debug=${old_debug#*=}
8041         $LCTL set_param debug="reada mmap"
8042
8043         # create a test file
8044         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8045
8046         echo Cancel LRU locks on lustre client to flush the client cache
8047         cancel_lru_locks osc
8048
8049         echo Reset readahead stats
8050         $LCTL set_param -n llite.*.read_ahead_stats 0
8051
8052         echo mmap read the file with small block size
8053         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8054                 > /dev/null 2>&1
8055
8056         echo checking missing pages
8057         $LCTL get_param llite.*.read_ahead_stats
8058         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8059                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8060
8061         $LCTL set_param debug="$old_debug"
8062         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8063         rm -f $DIR/$tfile
8064 }
8065 run_test 101f "check mmap read performance"
8066
8067 test_101g_brw_size_test() {
8068         local mb=$1
8069         local pages=$((mb * 1048576 / PAGE_SIZE))
8070         local file=$DIR/$tfile
8071
8072         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8073                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8074         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8075                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8076                         return 2
8077         done
8078
8079         stack_trap "rm -f $file" EXIT
8080         $LCTL set_param -n osc.*.rpc_stats=0
8081
8082         # 10 RPCs should be enough for the test
8083         local count=10
8084         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8085                 { error "dd write ${mb} MB blocks failed"; return 3; }
8086         cancel_lru_locks osc
8087         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8088                 { error "dd write ${mb} MB blocks failed"; return 4; }
8089
8090         # calculate number of full-sized read and write RPCs
8091         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8092                 sed -n '/pages per rpc/,/^$/p' |
8093                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8094                 END { print reads,writes }'))
8095         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8096                 return 5
8097         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8098                 return 6
8099
8100         return 0
8101 }
8102
8103 test_101g() {
8104         remote_ost_nodsh && skip "remote OST with nodsh"
8105
8106         local rpcs
8107         local osts=$(get_facets OST)
8108         local list=$(comma_list $(osts_nodes))
8109         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8110         local brw_size="obdfilter.*.brw_size"
8111
8112         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8113
8114         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8115
8116         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8117                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8118                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8119            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8120                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8121                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8122
8123                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8124                         suffix="M"
8125
8126                 if [[ $orig_mb -lt 16 ]]; then
8127                         save_lustre_params $osts "$brw_size" > $p
8128                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8129                                 error "set 16MB RPC size failed"
8130
8131                         echo "remount client to enable new RPC size"
8132                         remount_client $MOUNT || error "remount_client failed"
8133                 fi
8134
8135                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8136                 # should be able to set brw_size=12, but no rpc_stats for that
8137                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8138         fi
8139
8140         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8141
8142         if [[ $orig_mb -lt 16 ]]; then
8143                 restore_lustre_params < $p
8144                 remount_client $MOUNT || error "remount_client restore failed"
8145         fi
8146
8147         rm -f $p $DIR/$tfile
8148 }
8149 run_test 101g "Big bulk(4/16 MiB) readahead"
8150
8151 setup_test102() {
8152         test_mkdir $DIR/$tdir
8153         chown $RUNAS_ID $DIR/$tdir
8154         STRIPE_SIZE=65536
8155         STRIPE_OFFSET=1
8156         STRIPE_COUNT=$OSTCOUNT
8157         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8158
8159         trap cleanup_test102 EXIT
8160         cd $DIR
8161         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8162         cd $DIR/$tdir
8163         for num in 1 2 3 4; do
8164                 for count in $(seq 1 $STRIPE_COUNT); do
8165                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8166                                 local size=`expr $STRIPE_SIZE \* $num`
8167                                 local file=file"$num-$idx-$count"
8168                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8169                         done
8170                 done
8171         done
8172
8173         cd $DIR
8174         $1 tar cf $TMP/f102.tar $tdir --xattrs
8175 }
8176
8177 cleanup_test102() {
8178         trap 0
8179         rm -f $TMP/f102.tar
8180         rm -rf $DIR/d0.sanity/d102
8181 }
8182
8183 test_102a() {
8184         [ "$UID" != 0 ] && skip "must run as root"
8185         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8186                 skip_env "must have user_xattr"
8187
8188         [ -z "$(which setfattr 2>/dev/null)" ] &&
8189                 skip_env "could not find setfattr"
8190
8191         local testfile=$DIR/$tfile
8192
8193         touch $testfile
8194         echo "set/get xattr..."
8195         setfattr -n trusted.name1 -v value1 $testfile ||
8196                 error "setfattr -n trusted.name1=value1 $testfile failed"
8197         getfattr -n trusted.name1 $testfile 2> /dev/null |
8198           grep "trusted.name1=.value1" ||
8199                 error "$testfile missing trusted.name1=value1"
8200
8201         setfattr -n user.author1 -v author1 $testfile ||
8202                 error "setfattr -n user.author1=author1 $testfile failed"
8203         getfattr -n user.author1 $testfile 2> /dev/null |
8204           grep "user.author1=.author1" ||
8205                 error "$testfile missing trusted.author1=author1"
8206
8207         echo "listxattr..."
8208         setfattr -n trusted.name2 -v value2 $testfile ||
8209                 error "$testfile unable to set trusted.name2"
8210         setfattr -n trusted.name3 -v value3 $testfile ||
8211                 error "$testfile unable to set trusted.name3"
8212         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8213             grep "trusted.name" | wc -l) -eq 3 ] ||
8214                 error "$testfile missing 3 trusted.name xattrs"
8215
8216         setfattr -n user.author2 -v author2 $testfile ||
8217                 error "$testfile unable to set user.author2"
8218         setfattr -n user.author3 -v author3 $testfile ||
8219                 error "$testfile unable to set user.author3"
8220         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8221             grep "user.author" | wc -l) -eq 3 ] ||
8222                 error "$testfile missing 3 user.author xattrs"
8223
8224         echo "remove xattr..."
8225         setfattr -x trusted.name1 $testfile ||
8226                 error "$testfile error deleting trusted.name1"
8227         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8228                 error "$testfile did not delete trusted.name1 xattr"
8229
8230         setfattr -x user.author1 $testfile ||
8231                 error "$testfile error deleting user.author1"
8232         echo "set lustre special xattr ..."
8233         $LFS setstripe -c1 $testfile
8234         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8235                 awk -F "=" '/trusted.lov/ { print $2 }' )
8236         setfattr -n "trusted.lov" -v $lovea $testfile ||
8237                 error "$testfile doesn't ignore setting trusted.lov again"
8238         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8239                 error "$testfile allow setting invalid trusted.lov"
8240         rm -f $testfile
8241 }
8242 run_test 102a "user xattr test =================================="
8243
8244 test_102b() {
8245         [ -z "$(which setfattr 2>/dev/null)" ] &&
8246                 skip_env "could not find setfattr"
8247         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8248
8249         # b10930: get/set/list trusted.lov xattr
8250         echo "get/set/list trusted.lov xattr ..."
8251         local testfile=$DIR/$tfile
8252         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8253                 error "setstripe failed"
8254         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8255                 error "getstripe failed"
8256         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8257                 error "can't get trusted.lov from $testfile"
8258
8259         local testfile2=${testfile}2
8260         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8261                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8262
8263         $MCREATE $testfile2
8264         setfattr -n trusted.lov -v $value $testfile2
8265         local stripe_size=$($LFS getstripe -S $testfile2)
8266         local stripe_count=$($LFS getstripe -c $testfile2)
8267         [[ $stripe_size -eq 65536 ]] ||
8268                 error "stripe size $stripe_size != 65536"
8269         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8270                 error "stripe count $stripe_count != $STRIPECOUNT"
8271         rm -f $DIR/$tfile
8272 }
8273 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8274
8275 test_102c() {
8276         [ -z "$(which setfattr 2>/dev/null)" ] &&
8277                 skip_env "could not find setfattr"
8278         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8279
8280         # b10930: get/set/list lustre.lov xattr
8281         echo "get/set/list lustre.lov xattr ..."
8282         test_mkdir $DIR/$tdir
8283         chown $RUNAS_ID $DIR/$tdir
8284         local testfile=$DIR/$tdir/$tfile
8285         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8286                 error "setstripe failed"
8287         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8288                 error "getstripe failed"
8289         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8290         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8291
8292         local testfile2=${testfile}2
8293         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8294                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8295
8296         $RUNAS $MCREATE $testfile2
8297         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8298         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8299         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8300         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8301         [ $stripe_count -eq $STRIPECOUNT ] ||
8302                 error "stripe count $stripe_count != $STRIPECOUNT"
8303 }
8304 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8305
8306 compare_stripe_info1() {
8307         local stripe_index_all_zero=true
8308
8309         for num in 1 2 3 4; do
8310                 for count in $(seq 1 $STRIPE_COUNT); do
8311                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8312                                 local size=$((STRIPE_SIZE * num))
8313                                 local file=file"$num-$offset-$count"
8314                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8315                                 [[ $stripe_size -ne $size ]] &&
8316                                     error "$file: size $stripe_size != $size"
8317                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8318                                 # allow fewer stripes to be created, ORI-601
8319                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8320                                     error "$file: count $stripe_count != $count"
8321                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8322                                 [[ $stripe_index -ne 0 ]] &&
8323                                         stripe_index_all_zero=false
8324                         done
8325                 done
8326         done
8327         $stripe_index_all_zero &&
8328                 error "all files are being extracted starting from OST index 0"
8329         return 0
8330 }
8331
8332 have_xattrs_include() {
8333         tar --help | grep -q xattrs-include &&
8334                 echo --xattrs-include="lustre.*"
8335 }
8336
8337 test_102d() {
8338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8339         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8340
8341         XINC=$(have_xattrs_include)
8342         setup_test102
8343         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8344         cd $DIR/$tdir/$tdir
8345         compare_stripe_info1
8346 }
8347 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8348
8349 test_102f() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8352
8353         XINC=$(have_xattrs_include)
8354         setup_test102
8355         test_mkdir $DIR/$tdir.restore
8356         cd $DIR
8357         tar cf - --xattrs $tdir | tar xf - \
8358                 -C $DIR/$tdir.restore --xattrs $XINC
8359         cd $DIR/$tdir.restore/$tdir
8360         compare_stripe_info1
8361 }
8362 run_test 102f "tar copy files, not keep osts"
8363
8364 grow_xattr() {
8365         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8366                 skip "must have user_xattr"
8367         [ -z "$(which setfattr 2>/dev/null)" ] &&
8368                 skip_env "could not find setfattr"
8369         [ -z "$(which getfattr 2>/dev/null)" ] &&
8370                 skip_env "could not find getfattr"
8371
8372         local xsize=${1:-1024}  # in bytes
8373         local file=$DIR/$tfile
8374         local value="$(generate_string $xsize)"
8375         local xbig=trusted.big
8376         local toobig=$2
8377
8378         touch $file
8379         log "save $xbig on $file"
8380         if [ -z "$toobig" ]
8381         then
8382                 setfattr -n $xbig -v $value $file ||
8383                         error "saving $xbig on $file failed"
8384         else
8385                 setfattr -n $xbig -v $value $file &&
8386                         error "saving $xbig on $file succeeded"
8387                 return 0
8388         fi
8389
8390         local orig=$(get_xattr_value $xbig $file)
8391         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8392
8393         local xsml=trusted.sml
8394         log "save $xsml on $file"
8395         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8396
8397         local new=$(get_xattr_value $xbig $file)
8398         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8399
8400         log "grow $xsml on $file"
8401         setfattr -n $xsml -v "$value" $file ||
8402                 error "growing $xsml on $file failed"
8403
8404         new=$(get_xattr_value $xbig $file)
8405         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8406         log "$xbig still valid after growing $xsml"
8407
8408         rm -f $file
8409 }
8410
8411 test_102h() { # bug 15777
8412         grow_xattr 1024
8413 }
8414 run_test 102h "grow xattr from inside inode to external block"
8415
8416 test_102ha() {
8417         large_xattr_enabled || skip_env "ea_inode feature disabled"
8418
8419         echo "setting xattr of max xattr size: $(max_xattr_size)"
8420         grow_xattr $(max_xattr_size)
8421
8422         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8423         echo "This should fail:"
8424         grow_xattr $(($(max_xattr_size) + 10)) 1
8425 }
8426 run_test 102ha "grow xattr from inside inode to external inode"
8427
8428 test_102i() { # bug 17038
8429         [ -z "$(which getfattr 2>/dev/null)" ] &&
8430                 skip "could not find getfattr"
8431
8432         touch $DIR/$tfile
8433         ln -s $DIR/$tfile $DIR/${tfile}link
8434         getfattr -n trusted.lov $DIR/$tfile ||
8435                 error "lgetxattr on $DIR/$tfile failed"
8436         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8437                 grep -i "no such attr" ||
8438                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8439         rm -f $DIR/$tfile $DIR/${tfile}link
8440 }
8441 run_test 102i "lgetxattr test on symbolic link ============"
8442
8443 test_102j() {
8444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8445         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8446
8447         XINC=$(have_xattrs_include)
8448         setup_test102 "$RUNAS"
8449         chown $RUNAS_ID $DIR/$tdir
8450         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8451         cd $DIR/$tdir/$tdir
8452         compare_stripe_info1 "$RUNAS"
8453 }
8454 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8455
8456 test_102k() {
8457         [ -z "$(which setfattr 2>/dev/null)" ] &&
8458                 skip "could not find setfattr"
8459
8460         touch $DIR/$tfile
8461         # b22187 just check that does not crash for regular file.
8462         setfattr -n trusted.lov $DIR/$tfile
8463         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8464         local test_kdir=$DIR/$tdir
8465         test_mkdir $test_kdir
8466         local default_size=$($LFS getstripe -S $test_kdir)
8467         local default_count=$($LFS getstripe -c $test_kdir)
8468         local default_offset=$($LFS getstripe -i $test_kdir)
8469         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8470                 error 'dir setstripe failed'
8471         setfattr -n trusted.lov $test_kdir
8472         local stripe_size=$($LFS getstripe -S $test_kdir)
8473         local stripe_count=$($LFS getstripe -c $test_kdir)
8474         local stripe_offset=$($LFS getstripe -i $test_kdir)
8475         [ $stripe_size -eq $default_size ] ||
8476                 error "stripe size $stripe_size != $default_size"
8477         [ $stripe_count -eq $default_count ] ||
8478                 error "stripe count $stripe_count != $default_count"
8479         [ $stripe_offset -eq $default_offset ] ||
8480                 error "stripe offset $stripe_offset != $default_offset"
8481         rm -rf $DIR/$tfile $test_kdir
8482 }
8483 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8484
8485 test_102l() {
8486         [ -z "$(which getfattr 2>/dev/null)" ] &&
8487                 skip "could not find getfattr"
8488
8489         # LU-532 trusted. xattr is invisible to non-root
8490         local testfile=$DIR/$tfile
8491
8492         touch $testfile
8493
8494         echo "listxattr as user..."
8495         chown $RUNAS_ID $testfile
8496         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8497             grep -q "trusted" &&
8498                 error "$testfile trusted xattrs are user visible"
8499
8500         return 0;
8501 }
8502 run_test 102l "listxattr size test =================================="
8503
8504 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8505         local path=$DIR/$tfile
8506         touch $path
8507
8508         listxattr_size_check $path || error "listattr_size_check $path failed"
8509 }
8510 run_test 102m "Ensure listxattr fails on small bufffer ========"
8511
8512 cleanup_test102
8513
8514 getxattr() { # getxattr path name
8515         # Return the base64 encoding of the value of xattr name on path.
8516         local path=$1
8517         local name=$2
8518
8519         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8520         # file: $path
8521         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8522         #
8523         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8524
8525         getfattr --absolute-names --encoding=base64 --name=$name $path |
8526                 awk -F= -v name=$name '$1 == name {
8527                         print substr($0, index($0, "=") + 1);
8528         }'
8529 }
8530
8531 test_102n() { # LU-4101 mdt: protect internal xattrs
8532         [ -z "$(which setfattr 2>/dev/null)" ] &&
8533                 skip "could not find setfattr"
8534         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8535         then
8536                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8537         fi
8538
8539         local file0=$DIR/$tfile.0
8540         local file1=$DIR/$tfile.1
8541         local xattr0=$TMP/$tfile.0
8542         local xattr1=$TMP/$tfile.1
8543         local namelist="lov lma lmv link fid version som hsm"
8544         local name
8545         local value
8546
8547         rm -rf $file0 $file1 $xattr0 $xattr1
8548         touch $file0 $file1
8549
8550         # Get 'before' xattrs of $file1.
8551         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8552
8553         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8554                 namelist+=" lfsck_namespace"
8555         for name in $namelist; do
8556                 # Try to copy xattr from $file0 to $file1.
8557                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8558
8559                 setfattr --name=trusted.$name --value="$value" $file1 ||
8560                         error "setxattr 'trusted.$name' failed"
8561
8562                 # Try to set a garbage xattr.
8563                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8564
8565                 if [[ x$name == "xlov" ]]; then
8566                         setfattr --name=trusted.lov --value="$value" $file1 &&
8567                         error "setxattr invalid 'trusted.lov' success"
8568                 else
8569                         setfattr --name=trusted.$name --value="$value" $file1 ||
8570                                 error "setxattr invalid 'trusted.$name' failed"
8571                 fi
8572
8573                 # Try to remove the xattr from $file1. We don't care if this
8574                 # appears to succeed or fail, we just don't want there to be
8575                 # any changes or crashes.
8576                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8577         done
8578
8579         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8580         then
8581                 name="lfsck_ns"
8582                 # Try to copy xattr from $file0 to $file1.
8583                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8584
8585                 setfattr --name=trusted.$name --value="$value" $file1 ||
8586                         error "setxattr 'trusted.$name' failed"
8587
8588                 # Try to set a garbage xattr.
8589                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8590
8591                 setfattr --name=trusted.$name --value="$value" $file1 ||
8592                         error "setxattr 'trusted.$name' failed"
8593
8594                 # Try to remove the xattr from $file1. We don't care if this
8595                 # appears to succeed or fail, we just don't want there to be
8596                 # any changes or crashes.
8597                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8598         fi
8599
8600         # Get 'after' xattrs of file1.
8601         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8602
8603         if ! diff $xattr0 $xattr1; then
8604                 error "before and after xattrs of '$file1' differ"
8605         fi
8606
8607         rm -rf $file0 $file1 $xattr0 $xattr1
8608
8609         return 0
8610 }
8611 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8612
8613 test_102p() { # LU-4703 setxattr did not check ownership
8614         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8615                 skip "MDS needs to be at least 2.5.56"
8616
8617         local testfile=$DIR/$tfile
8618
8619         touch $testfile
8620
8621         echo "setfacl as user..."
8622         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8623         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8624
8625         echo "setfattr as user..."
8626         setfacl -m "u:$RUNAS_ID:---" $testfile
8627         $RUNAS setfattr -x system.posix_acl_access $testfile
8628         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8629 }
8630 run_test 102p "check setxattr(2) correctly fails without permission"
8631
8632 test_102q() {
8633         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8634                 skip "MDS needs to be at least 2.6.92"
8635
8636         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8637 }
8638 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8639
8640 test_102r() {
8641         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8642                 skip "MDS needs to be at least 2.6.93"
8643
8644         touch $DIR/$tfile || error "touch"
8645         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8646         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8647         rm $DIR/$tfile || error "rm"
8648
8649         #normal directory
8650         mkdir -p $DIR/$tdir || error "mkdir"
8651         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8652         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8653         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8654                 error "$testfile error deleting user.author1"
8655         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8656                 grep "user.$(basename $tdir)" &&
8657                 error "$tdir did not delete user.$(basename $tdir)"
8658         rmdir $DIR/$tdir || error "rmdir"
8659
8660         #striped directory
8661         test_mkdir $DIR/$tdir
8662         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8663         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8664         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8665                 error "$testfile error deleting user.author1"
8666         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8667                 grep "user.$(basename $tdir)" &&
8668                 error "$tdir did not delete user.$(basename $tdir)"
8669         rmdir $DIR/$tdir || error "rm striped dir"
8670 }
8671 run_test 102r "set EAs with empty values"
8672
8673 test_102s() {
8674         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8675                 skip "MDS needs to be at least 2.11.52"
8676
8677         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8678
8679         save_lustre_params client "llite.*.xattr_cache" > $save
8680
8681         for cache in 0 1; do
8682                 lctl set_param llite.*.xattr_cache=$cache
8683
8684                 rm -f $DIR/$tfile
8685                 touch $DIR/$tfile || error "touch"
8686                 for prefix in lustre security system trusted user; do
8687                         # Note getxattr() may fail with 'Operation not
8688                         # supported' or 'No such attribute' depending
8689                         # on prefix and cache.
8690                         getfattr -n $prefix.n102s $DIR/$tfile &&
8691                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8692                 done
8693         done
8694
8695         restore_lustre_params < $save
8696 }
8697 run_test 102s "getting nonexistent xattrs should fail"
8698
8699 test_102t() {
8700         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8701                 skip "MDS needs to be at least 2.11.52"
8702
8703         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8704
8705         save_lustre_params client "llite.*.xattr_cache" > $save
8706
8707         for cache in 0 1; do
8708                 lctl set_param llite.*.xattr_cache=$cache
8709
8710                 for buf_size in 0 256; do
8711                         rm -f $DIR/$tfile
8712                         touch $DIR/$tfile || error "touch"
8713                         setfattr -n user.multiop $DIR/$tfile
8714                         $MULTIOP $DIR/$tfile oa$buf_size ||
8715                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8716                 done
8717         done
8718
8719         restore_lustre_params < $save
8720 }
8721 run_test 102t "zero length xattr values handled correctly"
8722
8723 run_acl_subtest()
8724 {
8725     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8726     return $?
8727 }
8728
8729 test_103a() {
8730         [ "$UID" != 0 ] && skip "must run as root"
8731         $GSS && skip_env "could not run under gss"
8732         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8733                 skip_env "must have acl enabled"
8734         [ -z "$(which setfacl 2>/dev/null)" ] &&
8735                 skip_env "could not find setfacl"
8736         remote_mds_nodsh && skip "remote MDS with nodsh"
8737
8738         gpasswd -a daemon bin                           # LU-5641
8739         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8740
8741         declare -a identity_old
8742
8743         for num in $(seq $MDSCOUNT); do
8744                 switch_identity $num true || identity_old[$num]=$?
8745         done
8746
8747         SAVE_UMASK=$(umask)
8748         umask 0022
8749         mkdir -p $DIR/$tdir
8750         cd $DIR/$tdir
8751
8752         echo "performing cp ..."
8753         run_acl_subtest cp || error "run_acl_subtest cp failed"
8754         echo "performing getfacl-noacl..."
8755         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8756         echo "performing misc..."
8757         run_acl_subtest misc || error  "misc test failed"
8758         echo "performing permissions..."
8759         run_acl_subtest permissions || error "permissions failed"
8760         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8761         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8762                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8763                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8764         then
8765                 echo "performing permissions xattr..."
8766                 run_acl_subtest permissions_xattr ||
8767                         error "permissions_xattr failed"
8768         fi
8769         echo "performing setfacl..."
8770         run_acl_subtest setfacl || error  "setfacl test failed"
8771
8772         # inheritance test got from HP
8773         echo "performing inheritance..."
8774         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8775         chmod +x make-tree || error "chmod +x failed"
8776         run_acl_subtest inheritance || error "inheritance test failed"
8777         rm -f make-tree
8778
8779         echo "LU-974 ignore umask when acl is enabled..."
8780         run_acl_subtest 974 || error "LU-974 umask test failed"
8781         if [ $MDSCOUNT -ge 2 ]; then
8782                 run_acl_subtest 974_remote ||
8783                         error "LU-974 umask test failed under remote dir"
8784         fi
8785
8786         echo "LU-2561 newly created file is same size as directory..."
8787         if [ "$mds1_FSTYPE" != "zfs" ]; then
8788                 run_acl_subtest 2561 || error "LU-2561 test failed"
8789         else
8790                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8791         fi
8792
8793         run_acl_subtest 4924 || error "LU-4924 test failed"
8794
8795         cd $SAVE_PWD
8796         umask $SAVE_UMASK
8797
8798         for num in $(seq $MDSCOUNT); do
8799                 if [ "${identity_old[$num]}" = 1 ]; then
8800                         switch_identity $num false || identity_old[$num]=$?
8801                 fi
8802         done
8803 }
8804 run_test 103a "acl test"
8805
8806 test_103b() {
8807         declare -a pids
8808         local U
8809
8810         for U in {0..511}; do
8811                 {
8812                 local O=$(printf "%04o" $U)
8813
8814                 umask $(printf "%04o" $((511 ^ $O)))
8815                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8816                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8817
8818                 (( $S == ($O & 0666) )) ||
8819                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8820
8821                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8822                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8823                 (( $S == ($O & 0666) )) ||
8824                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8825
8826                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8827                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8828                 (( $S == ($O & 0666) )) ||
8829                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8830                 rm -f $DIR/$tfile.[smp]$0
8831                 } &
8832                 local pid=$!
8833
8834                 # limit the concurrently running threads to 64. LU-11878
8835                 local idx=$((U % 64))
8836                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8837                 pids[idx]=$pid
8838         done
8839         wait
8840 }
8841 run_test 103b "umask lfs setstripe"
8842
8843 test_103c() {
8844         mkdir -p $DIR/$tdir
8845         cp -rp $DIR/$tdir $DIR/$tdir.bak
8846
8847         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8848                 error "$DIR/$tdir shouldn't contain default ACL"
8849         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8850                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8851         true
8852 }
8853 run_test 103c "'cp -rp' won't set empty acl"
8854
8855 test_104a() {
8856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8857
8858         touch $DIR/$tfile
8859         lfs df || error "lfs df failed"
8860         lfs df -ih || error "lfs df -ih failed"
8861         lfs df -h $DIR || error "lfs df -h $DIR failed"
8862         lfs df -i $DIR || error "lfs df -i $DIR failed"
8863         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8864         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8865
8866         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8867         lctl --device %$OSC deactivate
8868         lfs df || error "lfs df with deactivated OSC failed"
8869         lctl --device %$OSC activate
8870         # wait the osc back to normal
8871         wait_osc_import_ready client ost
8872
8873         lfs df || error "lfs df with reactivated OSC failed"
8874         rm -f $DIR/$tfile
8875 }
8876 run_test 104a "lfs df [-ih] [path] test ========================="
8877
8878 test_104b() {
8879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8880         [ $RUNAS_ID -eq $UID ] &&
8881                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8882
8883         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8884                         grep "Permission denied" | wc -l)))
8885         if [ $denied_cnt -ne 0 ]; then
8886                 error "lfs check servers test failed"
8887         fi
8888 }
8889 run_test 104b "$RUNAS lfs check servers test ===================="
8890
8891 test_105a() {
8892         # doesn't work on 2.4 kernels
8893         touch $DIR/$tfile
8894         if $(flock_is_enabled); then
8895                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8896         else
8897                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8898         fi
8899         rm -f $DIR/$tfile
8900 }
8901 run_test 105a "flock when mounted without -o flock test ========"
8902
8903 test_105b() {
8904         touch $DIR/$tfile
8905         if $(flock_is_enabled); then
8906                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8907         else
8908                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8909         fi
8910         rm -f $DIR/$tfile
8911 }
8912 run_test 105b "fcntl when mounted without -o flock test ========"
8913
8914 test_105c() {
8915         touch $DIR/$tfile
8916         if $(flock_is_enabled); then
8917                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8918         else
8919                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8920         fi
8921         rm -f $DIR/$tfile
8922 }
8923 run_test 105c "lockf when mounted without -o flock test"
8924
8925 test_105d() { # bug 15924
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927
8928         test_mkdir $DIR/$tdir
8929         flock_is_enabled || skip_env "mount w/o flock enabled"
8930         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8931         $LCTL set_param fail_loc=0x80000315
8932         flocks_test 2 $DIR/$tdir
8933 }
8934 run_test 105d "flock race (should not freeze) ========"
8935
8936 test_105e() { # bug 22660 && 22040
8937         flock_is_enabled || skip_env "mount w/o flock enabled"
8938
8939         touch $DIR/$tfile
8940         flocks_test 3 $DIR/$tfile
8941 }
8942 run_test 105e "Two conflicting flocks from same process"
8943
8944 test_106() { #bug 10921
8945         test_mkdir $DIR/$tdir
8946         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8947         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8948 }
8949 run_test 106 "attempt exec of dir followed by chown of that dir"
8950
8951 test_107() {
8952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8953
8954         CDIR=`pwd`
8955         local file=core
8956
8957         cd $DIR
8958         rm -f $file
8959
8960         local save_pattern=$(sysctl -n kernel.core_pattern)
8961         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8962         sysctl -w kernel.core_pattern=$file
8963         sysctl -w kernel.core_uses_pid=0
8964
8965         ulimit -c unlimited
8966         sleep 60 &
8967         SLEEPPID=$!
8968
8969         sleep 1
8970
8971         kill -s 11 $SLEEPPID
8972         wait $SLEEPPID
8973         if [ -e $file ]; then
8974                 size=`stat -c%s $file`
8975                 [ $size -eq 0 ] && error "Fail to create core file $file"
8976         else
8977                 error "Fail to create core file $file"
8978         fi
8979         rm -f $file
8980         sysctl -w kernel.core_pattern=$save_pattern
8981         sysctl -w kernel.core_uses_pid=$save_uses_pid
8982         cd $CDIR
8983 }
8984 run_test 107 "Coredump on SIG"
8985
8986 test_110() {
8987         test_mkdir $DIR/$tdir
8988         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8989         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8990                 error "mkdir with 256 char should fail, but did not"
8991         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8992                 error "create with 255 char failed"
8993         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8994                 error "create with 256 char should fail, but did not"
8995
8996         ls -l $DIR/$tdir
8997         rm -rf $DIR/$tdir
8998 }
8999 run_test 110 "filename length checking"
9000
9001 #
9002 # Purpose: To verify dynamic thread (OSS) creation.
9003 #
9004 test_115() {
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9006         remote_ost_nodsh && skip "remote OST with nodsh"
9007
9008         # Lustre does not stop service threads once they are started.
9009         # Reset number of running threads to default.
9010         stopall
9011         setupall
9012
9013         local OSTIO_pre
9014         local save_params="$TMP/sanity-$TESTNAME.parameters"
9015
9016         # Get ll_ost_io count before I/O
9017         OSTIO_pre=$(do_facet ost1 \
9018                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9019         # Exit if lustre is not running (ll_ost_io not running).
9020         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9021
9022         echo "Starting with $OSTIO_pre threads"
9023         local thread_max=$((OSTIO_pre * 2))
9024         local rpc_in_flight=$((thread_max * 2))
9025         # Number of I/O Process proposed to be started.
9026         local nfiles
9027         local facets=$(get_facets OST)
9028
9029         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9030         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9031
9032         # Set in_flight to $rpc_in_flight
9033         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9034                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9035         nfiles=${rpc_in_flight}
9036         # Set ost thread_max to $thread_max
9037         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9038
9039         # 5 Minutes should be sufficient for max number of OSS
9040         # threads(thread_max) to be created.
9041         local timeout=300
9042
9043         # Start I/O.
9044         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9045         test_mkdir $DIR/$tdir
9046         for i in $(seq $nfiles); do
9047                 local file=$DIR/$tdir/${tfile}-$i
9048                 $LFS setstripe -c -1 -i 0 $file
9049                 ($WTL $file $timeout)&
9050         done
9051
9052         # I/O Started - Wait for thread_started to reach thread_max or report
9053         # error if thread_started is more than thread_max.
9054         echo "Waiting for thread_started to reach thread_max"
9055         local thread_started=0
9056         local end_time=$((SECONDS + timeout))
9057
9058         while [ $SECONDS -le $end_time ] ; do
9059                 echo -n "."
9060                 # Get ost i/o thread_started count.
9061                 thread_started=$(do_facet ost1 \
9062                         "$LCTL get_param \
9063                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9064                 # Break out if thread_started is equal/greater than thread_max
9065                 if [[ $thread_started -ge $thread_max ]]; then
9066                         echo ll_ost_io thread_started $thread_started, \
9067                                 equal/greater than thread_max $thread_max
9068                         break
9069                 fi
9070                 sleep 1
9071         done
9072
9073         # Cleanup - We have the numbers, Kill i/o jobs if running.
9074         jobcount=($(jobs -p))
9075         for i in $(seq 0 $((${#jobcount[@]}-1)))
9076         do
9077                 kill -9 ${jobcount[$i]}
9078                 if [ $? -ne 0 ] ; then
9079                         echo Warning: \
9080                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9081                 fi
9082         done
9083
9084         # Cleanup files left by WTL binary.
9085         for i in $(seq $nfiles); do
9086                 local file=$DIR/$tdir/${tfile}-$i
9087                 rm -rf $file
9088                 if [ $? -ne 0 ] ; then
9089                         echo "Warning: Failed to delete file $file"
9090                 fi
9091         done
9092
9093         restore_lustre_params <$save_params
9094         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9095
9096         # Error out if no new thread has started or Thread started is greater
9097         # than thread max.
9098         if [[ $thread_started -le $OSTIO_pre ||
9099                         $thread_started -gt $thread_max ]]; then
9100                 error "ll_ost_io: thread_started $thread_started" \
9101                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9102                       "No new thread started or thread started greater " \
9103                       "than thread_max."
9104         fi
9105 }
9106 run_test 115 "verify dynamic thread creation===================="
9107
9108 free_min_max () {
9109         wait_delete_completed
9110         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9111         echo "OST kbytes available: ${AVAIL[@]}"
9112         MAXV=${AVAIL[0]}
9113         MAXI=0
9114         MINV=${AVAIL[0]}
9115         MINI=0
9116         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9117                 #echo OST $i: ${AVAIL[i]}kb
9118                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9119                         MAXV=${AVAIL[i]}
9120                         MAXI=$i
9121                 fi
9122                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9123                         MINV=${AVAIL[i]}
9124                         MINI=$i
9125                 fi
9126         done
9127         echo "Min free space: OST $MINI: $MINV"
9128         echo "Max free space: OST $MAXI: $MAXV"
9129 }
9130
9131 test_116a() { # was previously test_116()
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9134         remote_mds_nodsh && skip "remote MDS with nodsh"
9135
9136         echo -n "Free space priority "
9137         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9138                 head -n1
9139         declare -a AVAIL
9140         free_min_max
9141
9142         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9143         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9144         trap simple_cleanup_common EXIT
9145
9146         # Check if we need to generate uneven OSTs
9147         test_mkdir -p $DIR/$tdir/OST${MINI}
9148         local FILL=$((MINV / 4))
9149         local DIFF=$((MAXV - MINV))
9150         local DIFF2=$((DIFF * 100 / MINV))
9151
9152         local threshold=$(do_facet $SINGLEMDS \
9153                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9154         threshold=${threshold%%%}
9155         echo -n "Check for uneven OSTs: "
9156         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9157
9158         if [[ $DIFF2 -gt $threshold ]]; then
9159                 echo "ok"
9160                 echo "Don't need to fill OST$MINI"
9161         else
9162                 # generate uneven OSTs. Write 2% over the QOS threshold value
9163                 echo "no"
9164                 DIFF=$((threshold - DIFF2 + 2))
9165                 DIFF2=$((MINV * DIFF / 100))
9166                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9167                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9168                         error "setstripe failed"
9169                 DIFF=$((DIFF2 / 2048))
9170                 i=0
9171                 while [ $i -lt $DIFF ]; do
9172                         i=$((i + 1))
9173                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9174                                 bs=2M count=1 2>/dev/null
9175                         echo -n .
9176                 done
9177                 echo .
9178                 sync
9179                 sleep_maxage
9180                 free_min_max
9181         fi
9182
9183         DIFF=$((MAXV - MINV))
9184         DIFF2=$((DIFF * 100 / MINV))
9185         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9186         if [ $DIFF2 -gt $threshold ]; then
9187                 echo "ok"
9188         else
9189                 echo "failed - QOS mode won't be used"
9190                 simple_cleanup_common
9191                 skip "QOS imbalance criteria not met"
9192         fi
9193
9194         MINI1=$MINI
9195         MINV1=$MINV
9196         MAXI1=$MAXI
9197         MAXV1=$MAXV
9198
9199         # now fill using QOS
9200         $LFS setstripe -c 1 $DIR/$tdir
9201         FILL=$((FILL / 200))
9202         if [ $FILL -gt 600 ]; then
9203                 FILL=600
9204         fi
9205         echo "writing $FILL files to QOS-assigned OSTs"
9206         i=0
9207         while [ $i -lt $FILL ]; do
9208                 i=$((i + 1))
9209                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9210                         count=1 2>/dev/null
9211                 echo -n .
9212         done
9213         echo "wrote $i 200k files"
9214         sync
9215         sleep_maxage
9216
9217         echo "Note: free space may not be updated, so measurements might be off"
9218         free_min_max
9219         DIFF2=$((MAXV - MINV))
9220         echo "free space delta: orig $DIFF final $DIFF2"
9221         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9222         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9223         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9224         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9225         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9226         if [[ $DIFF -gt 0 ]]; then
9227                 FILL=$((DIFF2 * 100 / DIFF - 100))
9228                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9229         fi
9230
9231         # Figure out which files were written where
9232         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9233                awk '/'$MINI1': / {print $2; exit}')
9234         echo $UUID
9235         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9236         echo "$MINC files created on smaller OST $MINI1"
9237         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9238                awk '/'$MAXI1': / {print $2; exit}')
9239         echo $UUID
9240         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9241         echo "$MAXC files created on larger OST $MAXI1"
9242         if [[ $MINC -gt 0 ]]; then
9243                 FILL=$((MAXC * 100 / MINC - 100))
9244                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9245         fi
9246         [[ $MAXC -gt $MINC ]] ||
9247                 error_ignore LU-9 "stripe QOS didn't balance free space"
9248         simple_cleanup_common
9249 }
9250 run_test 116a "stripe QOS: free space balance ==================="
9251
9252 test_116b() { # LU-2093
9253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9254         remote_mds_nodsh && skip "remote MDS with nodsh"
9255
9256 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9257         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9258                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9259         [ -z "$old_rr" ] && skip "no QOS"
9260         do_facet $SINGLEMDS lctl set_param \
9261                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9262         mkdir -p $DIR/$tdir
9263         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9264         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9265         do_facet $SINGLEMDS lctl set_param fail_loc=0
9266         rm -rf $DIR/$tdir
9267         do_facet $SINGLEMDS lctl set_param \
9268                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9269 }
9270 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9271
9272 test_117() # bug 10891
9273 {
9274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9275
9276         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9277         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9278         lctl set_param fail_loc=0x21e
9279         > $DIR/$tfile || error "truncate failed"
9280         lctl set_param fail_loc=0
9281         echo "Truncate succeeded."
9282         rm -f $DIR/$tfile
9283 }
9284 run_test 117 "verify osd extend =========="
9285
9286 NO_SLOW_RESENDCOUNT=4
9287 export OLD_RESENDCOUNT=""
9288 set_resend_count () {
9289         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9290         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9291         lctl set_param -n $PROC_RESENDCOUNT $1
9292         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9293 }
9294
9295 # for reduce test_118* time (b=14842)
9296 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9297
9298 # Reset async IO behavior after error case
9299 reset_async() {
9300         FILE=$DIR/reset_async
9301
9302         # Ensure all OSCs are cleared
9303         $LFS setstripe -c -1 $FILE
9304         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9305         sync
9306         rm $FILE
9307 }
9308
9309 test_118a() #bug 11710
9310 {
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312
9313         reset_async
9314
9315         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9316         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9317         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9318
9319         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9320                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9321                 return 1;
9322         fi
9323         rm -f $DIR/$tfile
9324 }
9325 run_test 118a "verify O_SYNC works =========="
9326
9327 test_118b()
9328 {
9329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9330         remote_ost_nodsh && skip "remote OST with nodsh"
9331
9332         reset_async
9333
9334         #define OBD_FAIL_SRV_ENOENT 0x217
9335         set_nodes_failloc "$(osts_nodes)" 0x217
9336         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9337         RC=$?
9338         set_nodes_failloc "$(osts_nodes)" 0
9339         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9340         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9341                     grep -c writeback)
9342
9343         if [[ $RC -eq 0 ]]; then
9344                 error "Must return error due to dropped pages, rc=$RC"
9345                 return 1;
9346         fi
9347
9348         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9349                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9350                 return 1;
9351         fi
9352
9353         echo "Dirty pages not leaked on ENOENT"
9354
9355         # Due to the above error the OSC will issue all RPCs syncronously
9356         # until a subsequent RPC completes successfully without error.
9357         $MULTIOP $DIR/$tfile Ow4096yc
9358         rm -f $DIR/$tfile
9359
9360         return 0
9361 }
9362 run_test 118b "Reclaim dirty pages on fatal error =========="
9363
9364 test_118c()
9365 {
9366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9367
9368         # for 118c, restore the original resend count, LU-1940
9369         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9370                                 set_resend_count $OLD_RESENDCOUNT
9371         remote_ost_nodsh && skip "remote OST with nodsh"
9372
9373         reset_async
9374
9375         #define OBD_FAIL_OST_EROFS               0x216
9376         set_nodes_failloc "$(osts_nodes)" 0x216
9377
9378         # multiop should block due to fsync until pages are written
9379         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9380         MULTIPID=$!
9381         sleep 1
9382
9383         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9384                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9385         fi
9386
9387         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9388                     grep -c writeback)
9389         if [[ $WRITEBACK -eq 0 ]]; then
9390                 error "No page in writeback, writeback=$WRITEBACK"
9391         fi
9392
9393         set_nodes_failloc "$(osts_nodes)" 0
9394         wait $MULTIPID
9395         RC=$?
9396         if [[ $RC -ne 0 ]]; then
9397                 error "Multiop fsync failed, rc=$RC"
9398         fi
9399
9400         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9401         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9402                     grep -c writeback)
9403         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9404                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9405         fi
9406
9407         rm -f $DIR/$tfile
9408         echo "Dirty pages flushed via fsync on EROFS"
9409         return 0
9410 }
9411 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9412
9413 # continue to use small resend count to reduce test_118* time (b=14842)
9414 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9415
9416 test_118d()
9417 {
9418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9419         remote_ost_nodsh && skip "remote OST with nodsh"
9420
9421         reset_async
9422
9423         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9424         set_nodes_failloc "$(osts_nodes)" 0x214
9425         # multiop should block due to fsync until pages are written
9426         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9427         MULTIPID=$!
9428         sleep 1
9429
9430         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9431                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9432         fi
9433
9434         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9435                     grep -c writeback)
9436         if [[ $WRITEBACK -eq 0 ]]; then
9437                 error "No page in writeback, writeback=$WRITEBACK"
9438         fi
9439
9440         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9441         set_nodes_failloc "$(osts_nodes)" 0
9442
9443         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9444         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9445                     grep -c writeback)
9446         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9447                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9448         fi
9449
9450         rm -f $DIR/$tfile
9451         echo "Dirty pages gaurenteed flushed via fsync"
9452         return 0
9453 }
9454 run_test 118d "Fsync validation inject a delay of the bulk =========="
9455
9456 test_118f() {
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458
9459         reset_async
9460
9461         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9462         lctl set_param fail_loc=0x8000040a
9463
9464         # Should simulate EINVAL error which is fatal
9465         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9466         RC=$?
9467         if [[ $RC -eq 0 ]]; then
9468                 error "Must return error due to dropped pages, rc=$RC"
9469         fi
9470
9471         lctl set_param fail_loc=0x0
9472
9473         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9474         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9475         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9476                     grep -c writeback)
9477         if [[ $LOCKED -ne 0 ]]; then
9478                 error "Locked pages remain in cache, locked=$LOCKED"
9479         fi
9480
9481         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9482                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9483         fi
9484
9485         rm -f $DIR/$tfile
9486         echo "No pages locked after fsync"
9487
9488         reset_async
9489         return 0
9490 }
9491 run_test 118f "Simulate unrecoverable OSC side error =========="
9492
9493 test_118g() {
9494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9495
9496         reset_async
9497
9498         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9499         lctl set_param fail_loc=0x406
9500
9501         # simulate local -ENOMEM
9502         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9503         RC=$?
9504
9505         lctl set_param fail_loc=0
9506         if [[ $RC -eq 0 ]]; then
9507                 error "Must return error due to dropped pages, rc=$RC"
9508         fi
9509
9510         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9511         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9512         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9513                         grep -c writeback)
9514         if [[ $LOCKED -ne 0 ]]; then
9515                 error "Locked pages remain in cache, locked=$LOCKED"
9516         fi
9517
9518         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9519                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9520         fi
9521
9522         rm -f $DIR/$tfile
9523         echo "No pages locked after fsync"
9524
9525         reset_async
9526         return 0
9527 }
9528 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9529
9530 test_118h() {
9531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9532         remote_ost_nodsh && skip "remote OST with nodsh"
9533
9534         reset_async
9535
9536         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9537         set_nodes_failloc "$(osts_nodes)" 0x20e
9538         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9539         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9540         RC=$?
9541
9542         set_nodes_failloc "$(osts_nodes)" 0
9543         if [[ $RC -eq 0 ]]; then
9544                 error "Must return error due to dropped pages, rc=$RC"
9545         fi
9546
9547         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9548         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9549         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9550                     grep -c writeback)
9551         if [[ $LOCKED -ne 0 ]]; then
9552                 error "Locked pages remain in cache, locked=$LOCKED"
9553         fi
9554
9555         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9556                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9557         fi
9558
9559         rm -f $DIR/$tfile
9560         echo "No pages locked after fsync"
9561
9562         return 0
9563 }
9564 run_test 118h "Verify timeout in handling recoverables errors  =========="
9565
9566 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9567
9568 test_118i() {
9569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9570         remote_ost_nodsh && skip "remote OST with nodsh"
9571
9572         reset_async
9573
9574         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9575         set_nodes_failloc "$(osts_nodes)" 0x20e
9576
9577         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9578         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9579         PID=$!
9580         sleep 5
9581         set_nodes_failloc "$(osts_nodes)" 0
9582
9583         wait $PID
9584         RC=$?
9585         if [[ $RC -ne 0 ]]; then
9586                 error "got error, but should be not, rc=$RC"
9587         fi
9588
9589         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9590         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9591         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9592         if [[ $LOCKED -ne 0 ]]; then
9593                 error "Locked pages remain in cache, locked=$LOCKED"
9594         fi
9595
9596         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9597                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9598         fi
9599
9600         rm -f $DIR/$tfile
9601         echo "No pages locked after fsync"
9602
9603         return 0
9604 }
9605 run_test 118i "Fix error before timeout in recoverable error  =========="
9606
9607 [ "$SLOW" = "no" ] && set_resend_count 4
9608
9609 test_118j() {
9610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9611         remote_ost_nodsh && skip "remote OST with nodsh"
9612
9613         reset_async
9614
9615         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9616         set_nodes_failloc "$(osts_nodes)" 0x220
9617
9618         # return -EIO from OST
9619         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9620         RC=$?
9621         set_nodes_failloc "$(osts_nodes)" 0x0
9622         if [[ $RC -eq 0 ]]; then
9623                 error "Must return error due to dropped pages, rc=$RC"
9624         fi
9625
9626         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9627         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9628         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9629         if [[ $LOCKED -ne 0 ]]; then
9630                 error "Locked pages remain in cache, locked=$LOCKED"
9631         fi
9632
9633         # in recoverable error on OST we want resend and stay until it finished
9634         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9635                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9636         fi
9637
9638         rm -f $DIR/$tfile
9639         echo "No pages locked after fsync"
9640
9641         return 0
9642 }
9643 run_test 118j "Simulate unrecoverable OST side error =========="
9644
9645 test_118k()
9646 {
9647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9648         remote_ost_nodsh && skip "remote OSTs with nodsh"
9649
9650         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9651         set_nodes_failloc "$(osts_nodes)" 0x20e
9652         test_mkdir $DIR/$tdir
9653
9654         for ((i=0;i<10;i++)); do
9655                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9656                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9657                 SLEEPPID=$!
9658                 sleep 0.500s
9659                 kill $SLEEPPID
9660                 wait $SLEEPPID
9661         done
9662
9663         set_nodes_failloc "$(osts_nodes)" 0
9664         rm -rf $DIR/$tdir
9665 }
9666 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9667
9668 test_118l() # LU-646
9669 {
9670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9671
9672         test_mkdir $DIR/$tdir
9673         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9674         rm -rf $DIR/$tdir
9675 }
9676 run_test 118l "fsync dir"
9677
9678 test_118m() # LU-3066
9679 {
9680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9681
9682         test_mkdir $DIR/$tdir
9683         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9684         rm -rf $DIR/$tdir
9685 }
9686 run_test 118m "fdatasync dir ========="
9687
9688 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9689
9690 test_118n()
9691 {
9692         local begin
9693         local end
9694
9695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9696         remote_ost_nodsh && skip "remote OSTs with nodsh"
9697
9698         # Sleep to avoid a cached response.
9699         #define OBD_STATFS_CACHE_SECONDS 1
9700         sleep 2
9701
9702         # Inject a 10 second delay in the OST_STATFS handler.
9703         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9704         set_nodes_failloc "$(osts_nodes)" 0x242
9705
9706         begin=$SECONDS
9707         stat --file-system $MOUNT > /dev/null
9708         end=$SECONDS
9709
9710         set_nodes_failloc "$(osts_nodes)" 0
9711
9712         if ((end - begin > 20)); then
9713             error "statfs took $((end - begin)) seconds, expected 10"
9714         fi
9715 }
9716 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9717
9718 test_119a() # bug 11737
9719 {
9720         BSIZE=$((512 * 1024))
9721         directio write $DIR/$tfile 0 1 $BSIZE
9722         # We ask to read two blocks, which is more than a file size.
9723         # directio will indicate an error when requested and actual
9724         # sizes aren't equeal (a normal situation in this case) and
9725         # print actual read amount.
9726         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9727         if [ "$NOB" != "$BSIZE" ]; then
9728                 error "read $NOB bytes instead of $BSIZE"
9729         fi
9730         rm -f $DIR/$tfile
9731 }
9732 run_test 119a "Short directIO read must return actual read amount"
9733
9734 test_119b() # bug 11737
9735 {
9736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9737
9738         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9739         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9740         sync
9741         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9742                 error "direct read failed"
9743         rm -f $DIR/$tfile
9744 }
9745 run_test 119b "Sparse directIO read must return actual read amount"
9746
9747 test_119c() # bug 13099
9748 {
9749         BSIZE=1048576
9750         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9751         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9752         rm -f $DIR/$tfile
9753 }
9754 run_test 119c "Testing for direct read hitting hole"
9755
9756 test_119d() # bug 15950
9757 {
9758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9759
9760         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9761         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9762         BSIZE=1048576
9763         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9764         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9765         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9766         lctl set_param fail_loc=0x40d
9767         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9768         pid_dio=$!
9769         sleep 1
9770         cat $DIR/$tfile > /dev/null &
9771         lctl set_param fail_loc=0
9772         pid_reads=$!
9773         wait $pid_dio
9774         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9775         sleep 2
9776         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9777         error "the read rpcs have not completed in 2s"
9778         rm -f $DIR/$tfile
9779         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9780 }
9781 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9782
9783 test_120a() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         remote_mds_nodsh && skip "remote MDS with nodsh"
9786         test_mkdir -i0 -c1 $DIR/$tdir
9787         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9788                 skip_env "no early lock cancel on server"
9789
9790         lru_resize_disable mdc
9791         lru_resize_disable osc
9792         cancel_lru_locks mdc
9793         # asynchronous object destroy at MDT could cause bl ast to client
9794         cancel_lru_locks osc
9795
9796         stat $DIR/$tdir > /dev/null
9797         can1=$(do_facet mds1 \
9798                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9799                awk '/ldlm_cancel/ {print $2}')
9800         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9801                awk '/ldlm_bl_callback/ {print $2}')
9802         test_mkdir -i0 -c1 $DIR/$tdir/d1
9803         can2=$(do_facet mds1 \
9804                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9805                awk '/ldlm_cancel/ {print $2}')
9806         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9807                awk '/ldlm_bl_callback/ {print $2}')
9808         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9809         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9810         lru_resize_enable mdc
9811         lru_resize_enable osc
9812 }
9813 run_test 120a "Early Lock Cancel: mkdir test"
9814
9815 test_120b() {
9816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9817         remote_mds_nodsh && skip "remote MDS with nodsh"
9818         test_mkdir $DIR/$tdir
9819         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9820                 skip_env "no early lock cancel on server"
9821
9822         lru_resize_disable mdc
9823         lru_resize_disable osc
9824         cancel_lru_locks mdc
9825         stat $DIR/$tdir > /dev/null
9826         can1=$(do_facet $SINGLEMDS \
9827                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9828                awk '/ldlm_cancel/ {print $2}')
9829         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9830                awk '/ldlm_bl_callback/ {print $2}')
9831         touch $DIR/$tdir/f1
9832         can2=$(do_facet $SINGLEMDS \
9833                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9834                awk '/ldlm_cancel/ {print $2}')
9835         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9836                awk '/ldlm_bl_callback/ {print $2}')
9837         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9838         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9839         lru_resize_enable mdc
9840         lru_resize_enable osc
9841 }
9842 run_test 120b "Early Lock Cancel: create test"
9843
9844 test_120c() {
9845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9846         remote_mds_nodsh && skip "remote MDS with nodsh"
9847         test_mkdir -i0 -c1 $DIR/$tdir
9848         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9849                 skip "no early lock cancel on server"
9850
9851         lru_resize_disable mdc
9852         lru_resize_disable osc
9853         test_mkdir -i0 -c1 $DIR/$tdir/d1
9854         test_mkdir -i0 -c1 $DIR/$tdir/d2
9855         touch $DIR/$tdir/d1/f1
9856         cancel_lru_locks mdc
9857         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9858         can1=$(do_facet mds1 \
9859                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9860                awk '/ldlm_cancel/ {print $2}')
9861         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9862                awk '/ldlm_bl_callback/ {print $2}')
9863         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9864         can2=$(do_facet mds1 \
9865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9866                awk '/ldlm_cancel/ {print $2}')
9867         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9868                awk '/ldlm_bl_callback/ {print $2}')
9869         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9870         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9871         lru_resize_enable mdc
9872         lru_resize_enable osc
9873 }
9874 run_test 120c "Early Lock Cancel: link test"
9875
9876 test_120d() {
9877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9878         remote_mds_nodsh && skip "remote MDS with nodsh"
9879         test_mkdir -i0 -c1 $DIR/$tdir
9880         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9881                 skip_env "no early lock cancel on server"
9882
9883         lru_resize_disable mdc
9884         lru_resize_disable osc
9885         touch $DIR/$tdir
9886         cancel_lru_locks mdc
9887         stat $DIR/$tdir > /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         chmod a+x $DIR/$tdir
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 120d "Early Lock Cancel: setattr test"
9905
9906 test_120e() {
9907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9908         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9909                 skip_env "no early lock cancel on server"
9910         remote_mds_nodsh && skip "remote MDS with nodsh"
9911
9912         local dlmtrace_set=false
9913
9914         test_mkdir -i0 -c1 $DIR/$tdir
9915         lru_resize_disable mdc
9916         lru_resize_disable osc
9917         ! $LCTL get_param debug | grep -q dlmtrace &&
9918                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9919         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9920         cancel_lru_locks mdc
9921         cancel_lru_locks osc
9922         dd if=$DIR/$tdir/f1 of=/dev/null
9923         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9924         # XXX client can not do early lock cancel of OST lock
9925         # during unlink (LU-4206), so cancel osc lock now.
9926         sleep 2
9927         cancel_lru_locks osc
9928         can1=$(do_facet mds1 \
9929                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9930                awk '/ldlm_cancel/ {print $2}')
9931         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9932                awk '/ldlm_bl_callback/ {print $2}')
9933         unlink $DIR/$tdir/f1
9934         sleep 5
9935         can2=$(do_facet mds1 \
9936                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9937                awk '/ldlm_cancel/ {print $2}')
9938         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9939                awk '/ldlm_bl_callback/ {print $2}')
9940         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9941                 $LCTL dk $TMP/cancel.debug.txt
9942         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9943                 $LCTL dk $TMP/blocking.debug.txt
9944         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9945         lru_resize_enable mdc
9946         lru_resize_enable osc
9947 }
9948 run_test 120e "Early Lock Cancel: unlink test"
9949
9950 test_120f() {
9951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9952         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9953                 skip_env "no early lock cancel on server"
9954         remote_mds_nodsh && skip "remote MDS with nodsh"
9955
9956         test_mkdir -i0 -c1 $DIR/$tdir
9957         lru_resize_disable mdc
9958         lru_resize_disable osc
9959         test_mkdir -i0 -c1 $DIR/$tdir/d1
9960         test_mkdir -i0 -c1 $DIR/$tdir/d2
9961         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9962         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9963         cancel_lru_locks mdc
9964         cancel_lru_locks osc
9965         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9966         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9967         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9968         # XXX client can not do early lock cancel of OST lock
9969         # during rename (LU-4206), so cancel osc lock now.
9970         sleep 2
9971         cancel_lru_locks osc
9972         can1=$(do_facet mds1 \
9973                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9974                awk '/ldlm_cancel/ {print $2}')
9975         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9976                awk '/ldlm_bl_callback/ {print $2}')
9977         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9978         sleep 5
9979         can2=$(do_facet mds1 \
9980                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9981                awk '/ldlm_cancel/ {print $2}')
9982         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9983                awk '/ldlm_bl_callback/ {print $2}')
9984         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9985         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9986         lru_resize_enable mdc
9987         lru_resize_enable osc
9988 }
9989 run_test 120f "Early Lock Cancel: rename test"
9990
9991 test_120g() {
9992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9993         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9994                 skip_env "no early lock cancel on server"
9995         remote_mds_nodsh && skip "remote MDS with nodsh"
9996
9997         lru_resize_disable mdc
9998         lru_resize_disable osc
9999         count=10000
10000         echo create $count files
10001         test_mkdir $DIR/$tdir
10002         cancel_lru_locks mdc
10003         cancel_lru_locks osc
10004         t0=$(date +%s)
10005
10006         can0=$(do_facet $SINGLEMDS \
10007                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10008                awk '/ldlm_cancel/ {print $2}')
10009         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10010                awk '/ldlm_bl_callback/ {print $2}')
10011         createmany -o $DIR/$tdir/f $count
10012         sync
10013         can1=$(do_facet $SINGLEMDS \
10014                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10015                awk '/ldlm_cancel/ {print $2}')
10016         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10017                awk '/ldlm_bl_callback/ {print $2}')
10018         t1=$(date +%s)
10019         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10020         echo rm $count files
10021         rm -r $DIR/$tdir
10022         sync
10023         can2=$(do_facet $SINGLEMDS \
10024                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10025                awk '/ldlm_cancel/ {print $2}')
10026         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10027                awk '/ldlm_bl_callback/ {print $2}')
10028         t2=$(date +%s)
10029         echo total: $count removes in $((t2-t1))
10030         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10031         sleep 2
10032         # wait for commitment of removal
10033         lru_resize_enable mdc
10034         lru_resize_enable osc
10035 }
10036 run_test 120g "Early Lock Cancel: performance test"
10037
10038 test_121() { #bug #10589
10039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10040
10041         rm -rf $DIR/$tfile
10042         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10043 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10044         lctl set_param fail_loc=0x310
10045         cancel_lru_locks osc > /dev/null
10046         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10047         lctl set_param fail_loc=0
10048         [[ $reads -eq $writes ]] ||
10049                 error "read $reads blocks, must be $writes blocks"
10050 }
10051 run_test 121 "read cancel race ========="
10052
10053 test_123a() { # was test 123, statahead(bug 11401)
10054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10055
10056         SLOWOK=0
10057         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10058                 log "testing UP system. Performance may be lower than expected."
10059                 SLOWOK=1
10060         fi
10061
10062         rm -rf $DIR/$tdir
10063         test_mkdir $DIR/$tdir
10064         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10065         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10066         MULT=10
10067         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10068                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10069
10070                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10071                 lctl set_param -n llite.*.statahead_max 0
10072                 lctl get_param llite.*.statahead_max
10073                 cancel_lru_locks mdc
10074                 cancel_lru_locks osc
10075                 stime=`date +%s`
10076                 time ls -l $DIR/$tdir | wc -l
10077                 etime=`date +%s`
10078                 delta=$((etime - stime))
10079                 log "ls $i files without statahead: $delta sec"
10080                 lctl set_param llite.*.statahead_max=$max
10081
10082                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10083                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10084                 cancel_lru_locks mdc
10085                 cancel_lru_locks osc
10086                 stime=`date +%s`
10087                 time ls -l $DIR/$tdir | wc -l
10088                 etime=`date +%s`
10089                 delta_sa=$((etime - stime))
10090                 log "ls $i files with statahead: $delta_sa sec"
10091                 lctl get_param -n llite.*.statahead_stats
10092                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10093
10094                 [[ $swrong -lt $ewrong ]] &&
10095                         log "statahead was stopped, maybe too many locks held!"
10096                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10097
10098                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10099                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10100                     lctl set_param -n llite.*.statahead_max 0
10101                     lctl get_param llite.*.statahead_max
10102                     cancel_lru_locks mdc
10103                     cancel_lru_locks osc
10104                     stime=`date +%s`
10105                     time ls -l $DIR/$tdir | wc -l
10106                     etime=`date +%s`
10107                     delta=$((etime - stime))
10108                     log "ls $i files again without statahead: $delta sec"
10109                     lctl set_param llite.*.statahead_max=$max
10110                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10111                         if [  $SLOWOK -eq 0 ]; then
10112                                 error "ls $i files is slower with statahead!"
10113                         else
10114                                 log "ls $i files is slower with statahead!"
10115                         fi
10116                         break
10117                     fi
10118                 fi
10119
10120                 [ $delta -gt 20 ] && break
10121                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10122                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10123         done
10124         log "ls done"
10125
10126         stime=`date +%s`
10127         rm -r $DIR/$tdir
10128         sync
10129         etime=`date +%s`
10130         delta=$((etime - stime))
10131         log "rm -r $DIR/$tdir/: $delta seconds"
10132         log "rm done"
10133         lctl get_param -n llite.*.statahead_stats
10134 }
10135 run_test 123a "verify statahead work"
10136
10137 test_123b () { # statahead(bug 15027)
10138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10139
10140         test_mkdir $DIR/$tdir
10141         createmany -o $DIR/$tdir/$tfile-%d 1000
10142
10143         cancel_lru_locks mdc
10144         cancel_lru_locks osc
10145
10146 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10147         lctl set_param fail_loc=0x80000803
10148         ls -lR $DIR/$tdir > /dev/null
10149         log "ls done"
10150         lctl set_param fail_loc=0x0
10151         lctl get_param -n llite.*.statahead_stats
10152         rm -r $DIR/$tdir
10153         sync
10154
10155 }
10156 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10157
10158 test_124a() {
10159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10160         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10161                 skip_env "no lru resize on server"
10162
10163         local NR=2000
10164
10165         test_mkdir $DIR/$tdir
10166
10167         log "create $NR files at $DIR/$tdir"
10168         createmany -o $DIR/$tdir/f $NR ||
10169                 error "failed to create $NR files in $DIR/$tdir"
10170
10171         cancel_lru_locks mdc
10172         ls -l $DIR/$tdir > /dev/null
10173
10174         local NSDIR=""
10175         local LRU_SIZE=0
10176         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10177                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10178                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10179                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10180                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10181                         log "NSDIR=$NSDIR"
10182                         log "NS=$(basename $NSDIR)"
10183                         break
10184                 fi
10185         done
10186
10187         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10188                 skip "Not enough cached locks created!"
10189         fi
10190         log "LRU=$LRU_SIZE"
10191
10192         local SLEEP=30
10193
10194         # We know that lru resize allows one client to hold $LIMIT locks
10195         # for 10h. After that locks begin to be killed by client.
10196         local MAX_HRS=10
10197         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10198         log "LIMIT=$LIMIT"
10199         if [ $LIMIT -lt $LRU_SIZE ]; then
10200                 skip "Limit is too small $LIMIT"
10201         fi
10202
10203         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10204         # killing locks. Some time was spent for creating locks. This means
10205         # that up to the moment of sleep finish we must have killed some of
10206         # them (10-100 locks). This depends on how fast ther were created.
10207         # Many of them were touched in almost the same moment and thus will
10208         # be killed in groups.
10209         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10210
10211         # Use $LRU_SIZE_B here to take into account real number of locks
10212         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10213         local LRU_SIZE_B=$LRU_SIZE
10214         log "LVF=$LVF"
10215         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10216         log "OLD_LVF=$OLD_LVF"
10217         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10218
10219         # Let's make sure that we really have some margin. Client checks
10220         # cached locks every 10 sec.
10221         SLEEP=$((SLEEP+20))
10222         log "Sleep ${SLEEP} sec"
10223         local SEC=0
10224         while ((SEC<$SLEEP)); do
10225                 echo -n "..."
10226                 sleep 5
10227                 SEC=$((SEC+5))
10228                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10229                 echo -n "$LRU_SIZE"
10230         done
10231         echo ""
10232         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10233         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10234
10235         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10236                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10237                 unlinkmany $DIR/$tdir/f $NR
10238                 return
10239         }
10240
10241         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10242         log "unlink $NR files at $DIR/$tdir"
10243         unlinkmany $DIR/$tdir/f $NR
10244 }
10245 run_test 124a "lru resize ======================================="
10246
10247 get_max_pool_limit()
10248 {
10249         local limit=$($LCTL get_param \
10250                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10251         local max=0
10252         for l in $limit; do
10253                 if [[ $l -gt $max ]]; then
10254                         max=$l
10255                 fi
10256         done
10257         echo $max
10258 }
10259
10260 test_124b() {
10261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10262         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10263                 skip_env "no lru resize on server"
10264
10265         LIMIT=$(get_max_pool_limit)
10266
10267         NR=$(($(default_lru_size)*20))
10268         if [[ $NR -gt $LIMIT ]]; then
10269                 log "Limit lock number by $LIMIT locks"
10270                 NR=$LIMIT
10271         fi
10272
10273         IFree=$(mdsrate_inodes_available)
10274         if [ $IFree -lt $NR ]; then
10275                 log "Limit lock number by $IFree inodes"
10276                 NR=$IFree
10277         fi
10278
10279         lru_resize_disable mdc
10280         test_mkdir -p $DIR/$tdir/disable_lru_resize
10281
10282         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10283         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10284         cancel_lru_locks mdc
10285         stime=`date +%s`
10286         PID=""
10287         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10288         PID="$PID $!"
10289         sleep 2
10290         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10291         PID="$PID $!"
10292         sleep 2
10293         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10294         PID="$PID $!"
10295         wait $PID
10296         etime=`date +%s`
10297         nolruresize_delta=$((etime-stime))
10298         log "ls -la time: $nolruresize_delta seconds"
10299         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10300         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10301
10302         lru_resize_enable mdc
10303         test_mkdir -p $DIR/$tdir/enable_lru_resize
10304
10305         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10306         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10307         cancel_lru_locks mdc
10308         stime=`date +%s`
10309         PID=""
10310         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10311         PID="$PID $!"
10312         sleep 2
10313         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10314         PID="$PID $!"
10315         sleep 2
10316         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10317         PID="$PID $!"
10318         wait $PID
10319         etime=`date +%s`
10320         lruresize_delta=$((etime-stime))
10321         log "ls -la time: $lruresize_delta seconds"
10322         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10323
10324         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10325                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10326         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10327                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10328         else
10329                 log "lru resize performs the same with no lru resize"
10330         fi
10331         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10332 }
10333 run_test 124b "lru resize (performance test) ======================="
10334
10335 test_124c() {
10336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10337         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10338                 skip_env "no lru resize on server"
10339
10340         # cache ununsed locks on client
10341         local nr=100
10342         cancel_lru_locks mdc
10343         test_mkdir $DIR/$tdir
10344         createmany -o $DIR/$tdir/f $nr ||
10345                 error "failed to create $nr files in $DIR/$tdir"
10346         ls -l $DIR/$tdir > /dev/null
10347
10348         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10349         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10350         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10351         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10352         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10353
10354         # set lru_max_age to 1 sec
10355         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10356         echo "sleep $((recalc_p * 2)) seconds..."
10357         sleep $((recalc_p * 2))
10358
10359         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10360         # restore lru_max_age
10361         $LCTL set_param -n $nsdir.lru_max_age $max_age
10362         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10363         unlinkmany $DIR/$tdir/f $nr
10364 }
10365 run_test 124c "LRUR cancel very aged locks"
10366
10367 test_125() { # 13358
10368         $LCTL get_param -n llite.*.client_type | grep -q local ||
10369                 skip "must run as local client"
10370         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10371                 skip_env "must have acl enabled"
10372         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10373
10374         test_mkdir $DIR/$tdir
10375         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10376         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10377         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10378 }
10379 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10380
10381 test_126() { # bug 12829/13455
10382         $GSS && skip_env "must run as gss disabled"
10383         $LCTL get_param -n llite.*.client_type | grep -q local ||
10384                 skip "must run as local client"
10385         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10386
10387         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10388         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10389         rm -f $DIR/$tfile
10390         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10391 }
10392 run_test 126 "check that the fsgid provided by the client is taken into account"
10393
10394 test_127a() { # bug 15521
10395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10396
10397         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10398         $LCTL set_param osc.*.stats=0
10399         FSIZE=$((2048 * 1024))
10400         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10401         cancel_lru_locks osc
10402         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10403
10404         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10405         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10406                 echo "got $COUNT $NAME"
10407                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10408                 eval $NAME=$COUNT || error "Wrong proc format"
10409
10410                 case $NAME in
10411                         read_bytes|write_bytes)
10412                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10413                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10414                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10415                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10416                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10417                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10418                                 error "sumsquare is too small: $SUMSQ"
10419                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10420                                 error "sumsquare is too big: $SUMSQ"
10421                         ;;
10422                         *) ;;
10423                 esac
10424         done < $DIR/${tfile}.tmp
10425
10426         #check that we actually got some stats
10427         [ "$read_bytes" ] || error "Missing read_bytes stats"
10428         [ "$write_bytes" ] || error "Missing write_bytes stats"
10429         [ "$read_bytes" != 0 ] || error "no read done"
10430         [ "$write_bytes" != 0 ] || error "no write done"
10431 }
10432 run_test 127a "verify the client stats are sane"
10433
10434 test_127b() { # bug LU-333
10435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10436         local name count samp unit min max sum sumsq
10437
10438         $LCTL set_param llite.*.stats=0
10439
10440         # perform 2 reads and writes so MAX is different from SUM.
10441         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10442         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10443         cancel_lru_locks osc
10444         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10445         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10446
10447         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10448         while read name count samp unit min max sum sumsq; do
10449                 echo "got $count $name"
10450                 eval $name=$count || error "Wrong proc format"
10451
10452                 case $name in
10453                 read_bytes)
10454                         [ $count -ne 2 ] && error "count is not 2: $count"
10455                         [ $min -ne $PAGE_SIZE ] &&
10456                                 error "min is not $PAGE_SIZE: $min"
10457                         [ $max -ne $PAGE_SIZE ] &&
10458                                 error "max is incorrect: $max"
10459                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10460                                 error "sum is wrong: $sum"
10461                         ;;
10462                 write_bytes)
10463                         [ $count -ne 2 ] && error "count is not 2: $count"
10464                         [ $min -ne $PAGE_SIZE ] &&
10465                                 error "min is not $PAGE_SIZE: $min"
10466                         [ $max -ne $PAGE_SIZE ] &&
10467                                 error "max is incorrect: $max"
10468                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10469                                 error "sum is wrong: $sum"
10470                         ;;
10471                 *) ;;
10472                 esac
10473         done < $TMP/$tfile.tmp
10474
10475         #check that we actually got some stats
10476         [ "$read_bytes" ] || error "Missing read_bytes stats"
10477         [ "$write_bytes" ] || error "Missing write_bytes stats"
10478         [ "$read_bytes" != 0 ] || error "no read done"
10479         [ "$write_bytes" != 0 ] || error "no write done"
10480
10481         rm -f $TMP/${tfile}.tmp
10482 }
10483 run_test 127b "verify the llite client stats are sane"
10484
10485 test_128() { # bug 15212
10486         touch $DIR/$tfile
10487         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10488                 find $DIR/$tfile
10489                 find $DIR/$tfile
10490         EOF
10491
10492         result=$(grep error $TMP/$tfile.log)
10493         rm -f $DIR/$tfile $TMP/$tfile.log
10494         [ -z "$result" ] ||
10495                 error "consecutive find's under interactive lfs failed"
10496 }
10497 run_test 128 "interactive lfs for 2 consecutive find's"
10498
10499 set_dir_limits () {
10500         local mntdev
10501         local canondev
10502         local node
10503
10504         local ldproc=/proc/fs/ldiskfs
10505         local facets=$(get_facets MDS)
10506
10507         for facet in ${facets//,/ }; do
10508                 canondev=$(ldiskfs_canon \
10509                            *.$(convert_facet2label $facet).mntdev $facet)
10510                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10511                         ldproc=/sys/fs/ldiskfs
10512                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10513                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10514         done
10515 }
10516
10517 check_mds_dmesg() {
10518         local facets=$(get_facets MDS)
10519         for facet in ${facets//,/ }; do
10520                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10521         done
10522         return 1
10523 }
10524
10525 test_129() {
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10528                 skip "Need MDS version with at least 2.5.56"
10529         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10530                 skip_env "ldiskfs only test"
10531         fi
10532         remote_mds_nodsh && skip "remote MDS with nodsh"
10533
10534         local ENOSPC=28
10535         local EFBIG=27
10536         local has_warning=false
10537
10538         rm -rf $DIR/$tdir
10539         mkdir -p $DIR/$tdir
10540
10541         # block size of mds1
10542         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10543         set_dir_limits $maxsize $maxsize
10544         local dirsize=$(stat -c%s "$DIR/$tdir")
10545         local nfiles=0
10546         while [[ $dirsize -le $maxsize ]]; do
10547                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10548                 rc=$?
10549                 if ! $has_warning; then
10550                         check_mds_dmesg '"is approaching"' && has_warning=true
10551                 fi
10552                 # check two errors:
10553                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10554                 # EFBIG for previous versions included in ldiskfs series
10555                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10556                         set_dir_limits 0 0
10557                         echo "return code $rc received as expected"
10558
10559                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10560                                 error_exit "create failed w/o dir size limit"
10561
10562                         check_mds_dmesg '"has reached"' ||
10563                                 error_exit "reached message should be output"
10564
10565                         [ $has_warning = "false" ] &&
10566                                 error_exit "warning message should be output"
10567
10568                         dirsize=$(stat -c%s "$DIR/$tdir")
10569
10570                         [[ $dirsize -ge $maxsize ]] && return 0
10571                         error_exit "current dir size $dirsize, " \
10572                                    "previous limit $maxsize"
10573                 elif [ $rc -ne 0 ]; then
10574                         set_dir_limits 0 0
10575                         error_exit "return $rc received instead of expected " \
10576                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10577                 fi
10578                 nfiles=$((nfiles + 1))
10579                 dirsize=$(stat -c%s "$DIR/$tdir")
10580         done
10581
10582         set_dir_limits 0 0
10583         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10584 }
10585 run_test 129 "test directory size limit ========================"
10586
10587 OLDIFS="$IFS"
10588 cleanup_130() {
10589         trap 0
10590         IFS="$OLDIFS"
10591 }
10592
10593 test_130a() {
10594         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10595         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10596
10597         trap cleanup_130 EXIT RETURN
10598
10599         local fm_file=$DIR/$tfile
10600         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10601         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10602                 error "dd failed for $fm_file"
10603
10604         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10605         filefrag -ves $fm_file
10606         RC=$?
10607         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10608                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10609         [ $RC != 0 ] && error "filefrag $fm_file failed"
10610
10611         filefrag_op=$(filefrag -ve -k $fm_file |
10612                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10613         lun=$($LFS getstripe -i $fm_file)
10614
10615         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10616         IFS=$'\n'
10617         tot_len=0
10618         for line in $filefrag_op
10619         do
10620                 frag_lun=`echo $line | cut -d: -f5`
10621                 ext_len=`echo $line | cut -d: -f4`
10622                 if (( $frag_lun != $lun )); then
10623                         cleanup_130
10624                         error "FIEMAP on 1-stripe file($fm_file) failed"
10625                         return
10626                 fi
10627                 (( tot_len += ext_len ))
10628         done
10629
10630         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10631                 cleanup_130
10632                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10633                 return
10634         fi
10635
10636         cleanup_130
10637
10638         echo "FIEMAP on single striped file succeeded"
10639 }
10640 run_test 130a "FIEMAP (1-stripe file)"
10641
10642 test_130b() {
10643         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10644
10645         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10646         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10647
10648         trap cleanup_130 EXIT RETURN
10649
10650         local fm_file=$DIR/$tfile
10651         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10652                         error "setstripe on $fm_file"
10653         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10654                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10655
10656         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10657                 error "dd failed on $fm_file"
10658
10659         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10660         filefrag_op=$(filefrag -ve -k $fm_file |
10661                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10662
10663         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10664                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10665
10666         IFS=$'\n'
10667         tot_len=0
10668         num_luns=1
10669         for line in $filefrag_op
10670         do
10671                 frag_lun=$(echo $line | cut -d: -f5 |
10672                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10673                 ext_len=$(echo $line | cut -d: -f4)
10674                 if (( $frag_lun != $last_lun )); then
10675                         if (( tot_len != 1024 )); then
10676                                 cleanup_130
10677                                 error "FIEMAP on $fm_file failed; returned " \
10678                                 "len $tot_len for OST $last_lun instead of 1024"
10679                                 return
10680                         else
10681                                 (( num_luns += 1 ))
10682                                 tot_len=0
10683                         fi
10684                 fi
10685                 (( tot_len += ext_len ))
10686                 last_lun=$frag_lun
10687         done
10688         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10689                 cleanup_130
10690                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10691                         "luns or wrong len for OST $last_lun"
10692                 return
10693         fi
10694
10695         cleanup_130
10696
10697         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10698 }
10699 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10700
10701 test_130c() {
10702         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10703
10704         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10705         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10706
10707         trap cleanup_130 EXIT RETURN
10708
10709         local fm_file=$DIR/$tfile
10710         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10711         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10712                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10713
10714         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10715                         error "dd failed on $fm_file"
10716
10717         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10718         filefrag_op=$(filefrag -ve -k $fm_file |
10719                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10720
10721         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10722                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10723
10724         IFS=$'\n'
10725         tot_len=0
10726         num_luns=1
10727         for line in $filefrag_op
10728         do
10729                 frag_lun=$(echo $line | cut -d: -f5 |
10730                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10731                 ext_len=$(echo $line | cut -d: -f4)
10732                 if (( $frag_lun != $last_lun )); then
10733                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10734                         if (( logical != 512 )); then
10735                                 cleanup_130
10736                                 error "FIEMAP on $fm_file failed; returned " \
10737                                 "logical start for lun $logical instead of 512"
10738                                 return
10739                         fi
10740                         if (( tot_len != 512 )); then
10741                                 cleanup_130
10742                                 error "FIEMAP on $fm_file failed; returned " \
10743                                 "len $tot_len for OST $last_lun instead of 1024"
10744                                 return
10745                         else
10746                                 (( num_luns += 1 ))
10747                                 tot_len=0
10748                         fi
10749                 fi
10750                 (( tot_len += ext_len ))
10751                 last_lun=$frag_lun
10752         done
10753         if (( num_luns != 2 || tot_len != 512 )); then
10754                 cleanup_130
10755                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10756                         "luns or wrong len for OST $last_lun"
10757                 return
10758         fi
10759
10760         cleanup_130
10761
10762         echo "FIEMAP on 2-stripe file with hole succeeded"
10763 }
10764 run_test 130c "FIEMAP (2-stripe file with hole)"
10765
10766 test_130d() {
10767         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10768
10769         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10770         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10771
10772         trap cleanup_130 EXIT RETURN
10773
10774         local fm_file=$DIR/$tfile
10775         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10776                         error "setstripe on $fm_file"
10777         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10778                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10779
10780         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10781         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10782                 error "dd failed on $fm_file"
10783
10784         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10785         filefrag_op=$(filefrag -ve -k $fm_file |
10786                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10787
10788         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10789                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10790
10791         IFS=$'\n'
10792         tot_len=0
10793         num_luns=1
10794         for line in $filefrag_op
10795         do
10796                 frag_lun=$(echo $line | cut -d: -f5 |
10797                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10798                 ext_len=$(echo $line | cut -d: -f4)
10799                 if (( $frag_lun != $last_lun )); then
10800                         if (( tot_len != 1024 )); then
10801                                 cleanup_130
10802                                 error "FIEMAP on $fm_file failed; returned " \
10803                                 "len $tot_len for OST $last_lun instead of 1024"
10804                                 return
10805                         else
10806                                 (( num_luns += 1 ))
10807                                 tot_len=0
10808                         fi
10809                 fi
10810                 (( tot_len += ext_len ))
10811                 last_lun=$frag_lun
10812         done
10813         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10814                 cleanup_130
10815                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10816                         "luns or wrong len for OST $last_lun"
10817                 return
10818         fi
10819
10820         cleanup_130
10821
10822         echo "FIEMAP on N-stripe file succeeded"
10823 }
10824 run_test 130d "FIEMAP (N-stripe file)"
10825
10826 test_130e() {
10827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10828
10829         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10830         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10831
10832         trap cleanup_130 EXIT RETURN
10833
10834         local fm_file=$DIR/$tfile
10835         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10836         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10837                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10838
10839         NUM_BLKS=512
10840         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10841         for ((i = 0; i < $NUM_BLKS; i++))
10842         do
10843                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10844         done
10845
10846         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10847         filefrag_op=$(filefrag -ve -k $fm_file |
10848                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10849
10850         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10851                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10852
10853         IFS=$'\n'
10854         tot_len=0
10855         num_luns=1
10856         for line in $filefrag_op
10857         do
10858                 frag_lun=$(echo $line | cut -d: -f5 |
10859                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10860                 ext_len=$(echo $line | cut -d: -f4)
10861                 if (( $frag_lun != $last_lun )); then
10862                         if (( tot_len != $EXPECTED_LEN )); then
10863                                 cleanup_130
10864                                 error "FIEMAP on $fm_file failed; returned " \
10865                                 "len $tot_len for OST $last_lun instead " \
10866                                 "of $EXPECTED_LEN"
10867                                 return
10868                         else
10869                                 (( num_luns += 1 ))
10870                                 tot_len=0
10871                         fi
10872                 fi
10873                 (( tot_len += ext_len ))
10874                 last_lun=$frag_lun
10875         done
10876         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10877                 cleanup_130
10878                 error "FIEMAP on $fm_file failed; returned wrong number " \
10879                         "of luns or wrong len for OST $last_lun"
10880                 return
10881         fi
10882
10883         cleanup_130
10884
10885         echo "FIEMAP with continuation calls succeeded"
10886 }
10887 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10888
10889 test_130f() {
10890         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10891         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10892
10893         local fm_file=$DIR/$tfile
10894         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10895                 error "multiop create with lov_delay_create on $fm_file"
10896
10897         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10898         filefrag_extents=$(filefrag -vek $fm_file |
10899                            awk '/extents? found/ { print $2 }')
10900         if [[ "$filefrag_extents" != "0" ]]; then
10901                 error "FIEMAP on $fm_file failed; " \
10902                       "returned $filefrag_extents expected 0"
10903         fi
10904
10905         rm -f $fm_file
10906 }
10907 run_test 130f "FIEMAP (unstriped file)"
10908
10909 # Test for writev/readv
10910 test_131a() {
10911         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10912                 error "writev test failed"
10913         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10914                 error "readv failed"
10915         rm -f $DIR/$tfile
10916 }
10917 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10918
10919 test_131b() {
10920         local fsize=$((524288 + 1048576 + 1572864))
10921         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10922                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10923                         error "append writev test failed"
10924
10925         ((fsize += 1572864 + 1048576))
10926         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10927                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10928                         error "append writev test failed"
10929         rm -f $DIR/$tfile
10930 }
10931 run_test 131b "test append writev"
10932
10933 test_131c() {
10934         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10935         error "NOT PASS"
10936 }
10937 run_test 131c "test read/write on file w/o objects"
10938
10939 test_131d() {
10940         rwv -f $DIR/$tfile -w -n 1 1572864
10941         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10942         if [ "$NOB" != 1572864 ]; then
10943                 error "Short read filed: read $NOB bytes instead of 1572864"
10944         fi
10945         rm -f $DIR/$tfile
10946 }
10947 run_test 131d "test short read"
10948
10949 test_131e() {
10950         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10951         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10952         error "read hitting hole failed"
10953         rm -f $DIR/$tfile
10954 }
10955 run_test 131e "test read hitting hole"
10956
10957 check_stats() {
10958         local facet=$1
10959         local op=$2
10960         local want=${3:-0}
10961         local res
10962
10963         case $facet in
10964         mds*) res=$(do_facet $facet \
10965                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10966                  ;;
10967         ost*) res=$(do_facet $facet \
10968                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10969                  ;;
10970         *) error "Wrong facet '$facet'" ;;
10971         esac
10972         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10973         # if the argument $3 is zero, it means any stat increment is ok.
10974         if [[ $want -gt 0 ]]; then
10975                 local count=$(echo $res | awk '{ print $2 }')
10976                 [[ $count -ne $want ]] &&
10977                         error "The $op counter on $facet is $count, not $want"
10978         fi
10979 }
10980
10981 test_133a() {
10982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10983         remote_ost_nodsh && skip "remote OST with nodsh"
10984         remote_mds_nodsh && skip "remote MDS with nodsh"
10985         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10986                 skip_env "MDS doesn't support rename stats"
10987
10988         local testdir=$DIR/${tdir}/stats_testdir
10989
10990         mkdir -p $DIR/${tdir}
10991
10992         # clear stats.
10993         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10994         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10995
10996         # verify mdt stats first.
10997         mkdir ${testdir} || error "mkdir failed"
10998         check_stats $SINGLEMDS "mkdir" 1
10999         touch ${testdir}/${tfile} || error "touch failed"
11000         check_stats $SINGLEMDS "open" 1
11001         check_stats $SINGLEMDS "close" 1
11002         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11003                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11004                 check_stats $SINGLEMDS "mknod" 2
11005         }
11006         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11007         check_stats $SINGLEMDS "unlink" 1
11008         rm -f ${testdir}/${tfile} || error "file remove failed"
11009         check_stats $SINGLEMDS "unlink" 2
11010
11011         # remove working dir and check mdt stats again.
11012         rmdir ${testdir} || error "rmdir failed"
11013         check_stats $SINGLEMDS "rmdir" 1
11014
11015         local testdir1=$DIR/${tdir}/stats_testdir1
11016         mkdir -p ${testdir}
11017         mkdir -p ${testdir1}
11018         touch ${testdir1}/test1
11019         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11020         check_stats $SINGLEMDS "crossdir_rename" 1
11021
11022         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11023         check_stats $SINGLEMDS "samedir_rename" 1
11024
11025         rm -rf $DIR/${tdir}
11026 }
11027 run_test 133a "Verifying MDT stats ========================================"
11028
11029 test_133b() {
11030         local res
11031
11032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11033         remote_ost_nodsh && skip "remote OST with nodsh"
11034         remote_mds_nodsh && skip "remote MDS with nodsh"
11035
11036         local testdir=$DIR/${tdir}/stats_testdir
11037
11038         mkdir -p ${testdir} || error "mkdir failed"
11039         touch ${testdir}/${tfile} || error "touch failed"
11040         cancel_lru_locks mdc
11041
11042         # clear stats.
11043         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11044         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11045
11046         # extra mdt stats verification.
11047         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11048         check_stats $SINGLEMDS "setattr" 1
11049         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11050         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11051         then            # LU-1740
11052                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11053                 check_stats $SINGLEMDS "getattr" 1
11054         fi
11055         rm -rf $DIR/${tdir}
11056
11057         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11058         # so the check below is not reliable
11059         [ $MDSCOUNT -eq 1 ] || return 0
11060
11061         # Sleep to avoid a cached response.
11062         #define OBD_STATFS_CACHE_SECONDS 1
11063         sleep 2
11064         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11065         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11066         $LFS df || error "lfs failed"
11067         check_stats $SINGLEMDS "statfs" 1
11068
11069         # check aggregated statfs (LU-10018)
11070         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11071                 return 0
11072         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11073                 return 0
11074         sleep 2
11075         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11076         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11077         df $DIR
11078         check_stats $SINGLEMDS "statfs" 1
11079
11080         # We want to check that the client didn't send OST_STATFS to
11081         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11082         # extra care is needed here.
11083         if remote_mds; then
11084                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11085                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11086
11087                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11088                 [ "$res" ] && error "OST got STATFS"
11089         fi
11090
11091         return 0
11092 }
11093 run_test 133b "Verifying extra MDT stats =================================="
11094
11095 test_133c() {
11096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11097         remote_ost_nodsh && skip "remote OST with nodsh"
11098         remote_mds_nodsh && skip "remote MDS with nodsh"
11099
11100         local testdir=$DIR/$tdir/stats_testdir
11101
11102         test_mkdir -p $testdir
11103
11104         # verify obdfilter stats.
11105         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11106         sync
11107         cancel_lru_locks osc
11108         wait_delete_completed
11109
11110         # clear stats.
11111         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11112         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11113
11114         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11115                 error "dd failed"
11116         sync
11117         cancel_lru_locks osc
11118         check_stats ost1 "write" 1
11119
11120         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11121         check_stats ost1 "read" 1
11122
11123         > $testdir/$tfile || error "truncate failed"
11124         check_stats ost1 "punch" 1
11125
11126         rm -f $testdir/$tfile || error "file remove failed"
11127         wait_delete_completed
11128         check_stats ost1 "destroy" 1
11129
11130         rm -rf $DIR/$tdir
11131 }
11132 run_test 133c "Verifying OST stats ========================================"
11133
11134 order_2() {
11135         local value=$1
11136         local orig=$value
11137         local order=1
11138
11139         while [ $value -ge 2 ]; do
11140                 order=$((order*2))
11141                 value=$((value/2))
11142         done
11143
11144         if [ $orig -gt $order ]; then
11145                 order=$((order*2))
11146         fi
11147         echo $order
11148 }
11149
11150 size_in_KMGT() {
11151     local value=$1
11152     local size=('K' 'M' 'G' 'T');
11153     local i=0
11154     local size_string=$value
11155
11156     while [ $value -ge 1024 ]; do
11157         if [ $i -gt 3 ]; then
11158             #T is the biggest unit we get here, if that is bigger,
11159             #just return XXXT
11160             size_string=${value}T
11161             break
11162         fi
11163         value=$((value >> 10))
11164         if [ $value -lt 1024 ]; then
11165             size_string=${value}${size[$i]}
11166             break
11167         fi
11168         i=$((i + 1))
11169     done
11170
11171     echo $size_string
11172 }
11173
11174 get_rename_size() {
11175         local size=$1
11176         local context=${2:-.}
11177         local sample=$(do_facet $SINGLEMDS $LCTL \
11178                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11179                 grep -A1 $context |
11180                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11181         echo $sample
11182 }
11183
11184 test_133d() {
11185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11186         remote_ost_nodsh && skip "remote OST with nodsh"
11187         remote_mds_nodsh && skip "remote MDS with nodsh"
11188         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11189                 skip_env "MDS doesn't support rename stats"
11190
11191         local testdir1=$DIR/${tdir}/stats_testdir1
11192         local testdir2=$DIR/${tdir}/stats_testdir2
11193         mkdir -p $DIR/${tdir}
11194
11195         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11196
11197         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11198         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11199
11200         createmany -o $testdir1/test 512 || error "createmany failed"
11201
11202         # check samedir rename size
11203         mv ${testdir1}/test0 ${testdir1}/test_0
11204
11205         local testdir1_size=$(ls -l $DIR/${tdir} |
11206                 awk '/stats_testdir1/ {print $5}')
11207         local testdir2_size=$(ls -l $DIR/${tdir} |
11208                 awk '/stats_testdir2/ {print $5}')
11209
11210         testdir1_size=$(order_2 $testdir1_size)
11211         testdir2_size=$(order_2 $testdir2_size)
11212
11213         testdir1_size=$(size_in_KMGT $testdir1_size)
11214         testdir2_size=$(size_in_KMGT $testdir2_size)
11215
11216         echo "source rename dir size: ${testdir1_size}"
11217         echo "target rename dir size: ${testdir2_size}"
11218
11219         local cmd="do_facet $SINGLEMDS $LCTL "
11220         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11221
11222         eval $cmd || error "$cmd failed"
11223         local samedir=$($cmd | grep 'same_dir')
11224         local same_sample=$(get_rename_size $testdir1_size)
11225         [ -z "$samedir" ] && error "samedir_rename_size count error"
11226         [[ $same_sample -eq 1 ]] ||
11227                 error "samedir_rename_size error $same_sample"
11228         echo "Check same dir rename stats success"
11229
11230         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11231
11232         # check crossdir rename size
11233         mv ${testdir1}/test_0 ${testdir2}/test_0
11234
11235         testdir1_size=$(ls -l $DIR/${tdir} |
11236                 awk '/stats_testdir1/ {print $5}')
11237         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         eval $cmd || error "$cmd failed"
11250         local crossdir=$($cmd | grep 'crossdir')
11251         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11252         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11253         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11254         [[ $src_sample -eq 1 ]] ||
11255                 error "crossdir_rename_size error $src_sample"
11256         [[ $tgt_sample -eq 1 ]] ||
11257                 error "crossdir_rename_size error $tgt_sample"
11258         echo "Check cross dir rename stats success"
11259         rm -rf $DIR/${tdir}
11260 }
11261 run_test 133d "Verifying rename_stats ========================================"
11262
11263 test_133e() {
11264         remote_mds_nodsh && skip "remote MDS with nodsh"
11265         remote_ost_nodsh && skip "remote OST with nodsh"
11266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11267
11268         local testdir=$DIR/${tdir}/stats_testdir
11269         local ctr f0 f1 bs=32768 count=42 sum
11270
11271         mkdir -p ${testdir} || error "mkdir failed"
11272
11273         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11274
11275         for ctr in {write,read}_bytes; do
11276                 sync
11277                 cancel_lru_locks osc
11278
11279                 do_facet ost1 $LCTL set_param -n \
11280                         "obdfilter.*.exports.clear=clear"
11281
11282                 if [ $ctr = write_bytes ]; then
11283                         f0=/dev/zero
11284                         f1=${testdir}/${tfile}
11285                 else
11286                         f0=${testdir}/${tfile}
11287                         f1=/dev/null
11288                 fi
11289
11290                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11291                         error "dd failed"
11292                 sync
11293                 cancel_lru_locks osc
11294
11295                 sum=$(do_facet ost1 $LCTL get_param \
11296                         "obdfilter.*.exports.*.stats" |
11297                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11298                                 $1 == ctr { sum += $7 }
11299                                 END { printf("%0.0f", sum) }')
11300
11301                 if ((sum != bs * count)); then
11302                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11303                 fi
11304         done
11305
11306         rm -rf $DIR/${tdir}
11307 }
11308 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11309
11310 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11311
11312 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11313 # not honor the -ignore_readdir_race option correctly. So we call
11314 # error_ignore() rather than error() in these cases. See LU-11152.
11315 error_133() {
11316         if (find --version; do_facet mds1 find --version) |
11317                 grep -q '\b4\.5\.1[1-4]\b'; then
11318                 error_ignore LU-11152 "$@"
11319         else
11320                 error "$@"
11321         fi
11322 }
11323
11324 test_133f() {
11325         # First without trusting modes.
11326         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11327         echo "proc_dirs='$proc_dirs'"
11328         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11329         find $proc_dirs -exec cat '{}' \; &> /dev/null
11330
11331         # Second verifying readability.
11332         $LCTL get_param -R '*' &> /dev/null
11333
11334         # Verifing writability with badarea_io.
11335         find $proc_dirs \
11336                 -ignore_readdir_race \
11337                 -type f \
11338                 -not -name force_lbug \
11339                 -not -name changelog_mask \
11340                 -exec badarea_io '{}' \; ||
11341                         error_133 "find $proc_dirs failed"
11342 }
11343 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11344
11345 test_133g() {
11346         remote_mds_nodsh && skip "remote MDS with nodsh"
11347         remote_ost_nodsh && skip "remote OST with nodsh"
11348
11349         # eventually, this can also be replaced with "lctl get_param -R",
11350         # but not until that option is always available on the server
11351         local facet
11352         for facet in mds1 ost1; do
11353                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11354                         skip_noexit "Too old lustre on $facet"
11355                 local facet_proc_dirs=$(do_facet $facet \
11356                                         \\\ls -d $proc_regexp 2>/dev/null)
11357                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11358                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11359                 do_facet $facet find $facet_proc_dirs \
11360                         ! -name req_history \
11361                         -exec cat '{}' \\\; &> /dev/null
11362
11363                 do_facet $facet find $facet_proc_dirs \
11364                         ! -name req_history \
11365                         -type f \
11366                         -exec cat '{}' \\\; &> /dev/null ||
11367                                 error "proc file read failed"
11368
11369                 do_facet $facet find $facet_proc_dirs \
11370                         -ignore_readdir_race \
11371                         -type f \
11372                         -not -name force_lbug \
11373                         -not -name changelog_mask \
11374                         -exec badarea_io '{}' \\\; ||
11375                                 error_133 "$facet find $facet_proc_dirs failed"
11376         done
11377
11378         # remount the FS in case writes/reads /proc break the FS
11379         cleanup || error "failed to unmount"
11380         setup || error "failed to setup"
11381         true
11382 }
11383 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11384
11385 test_133h() {
11386         remote_mds_nodsh && skip "remote MDS with nodsh"
11387         remote_ost_nodsh && skip "remote OST with nodsh"
11388         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11389                 skip "Need MDS version at least 2.9.54"
11390
11391         local facet
11392
11393         for facet in client mds1 ost1; do
11394                 local facet_proc_dirs=$(do_facet $facet \
11395                                         \\\ls -d $proc_regexp 2> /dev/null)
11396                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11397                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11398                 # Get the list of files that are missing the terminating newline
11399                 local missing=($(do_facet $facet \
11400                         find ${facet_proc_dirs} -type f \|              \
11401                                 while read F\; do                       \
11402                                         awk -v FS='\v' -v RS='\v\v'     \
11403                                         "'END { if(NR>0 &&              \
11404                                         \\\$NF !~ /.*\\\n\$/)           \
11405                                                 print FILENAME}'"       \
11406                                         '\$F'\;                         \
11407                                 done 2>/dev/null))
11408                 [ ${#missing[*]} -eq 0 ] ||
11409                         error "files do not end with newline: ${missing[*]}"
11410         done
11411 }
11412 run_test 133h "Proc files should end with newlines"
11413
11414 test_134a() {
11415         remote_mds_nodsh && skip "remote MDS with nodsh"
11416         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11417                 skip "Need MDS version at least 2.7.54"
11418
11419         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11420         cancel_lru_locks mdc
11421
11422         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11423         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11424         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11425
11426         local nr=1000
11427         createmany -o $DIR/$tdir/f $nr ||
11428                 error "failed to create $nr files in $DIR/$tdir"
11429         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11430
11431         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11432         do_facet mds1 $LCTL set_param fail_loc=0x327
11433         do_facet mds1 $LCTL set_param fail_val=500
11434         touch $DIR/$tdir/m
11435
11436         echo "sleep 10 seconds ..."
11437         sleep 10
11438         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11439
11440         do_facet mds1 $LCTL set_param fail_loc=0
11441         do_facet mds1 $LCTL set_param fail_val=0
11442         [ $lck_cnt -lt $unused ] ||
11443                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11444
11445         rm $DIR/$tdir/m
11446         unlinkmany $DIR/$tdir/f $nr
11447 }
11448 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11449
11450 test_134b() {
11451         remote_mds_nodsh && skip "remote MDS with nodsh"
11452         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11453                 skip "Need MDS version at least 2.7.54"
11454
11455         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11456         cancel_lru_locks mdc
11457
11458         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11459                         ldlm.lock_reclaim_threshold_mb)
11460         # disable reclaim temporarily
11461         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11462
11463         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11464         do_facet mds1 $LCTL set_param fail_loc=0x328
11465         do_facet mds1 $LCTL set_param fail_val=500
11466
11467         $LCTL set_param debug=+trace
11468
11469         local nr=600
11470         createmany -o $DIR/$tdir/f $nr &
11471         local create_pid=$!
11472
11473         echo "Sleep $TIMEOUT seconds ..."
11474         sleep $TIMEOUT
11475         if ! ps -p $create_pid  > /dev/null 2>&1; then
11476                 do_facet mds1 $LCTL set_param fail_loc=0
11477                 do_facet mds1 $LCTL set_param fail_val=0
11478                 do_facet mds1 $LCTL set_param \
11479                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11480                 error "createmany finished incorrectly!"
11481         fi
11482         do_facet mds1 $LCTL set_param fail_loc=0
11483         do_facet mds1 $LCTL set_param fail_val=0
11484         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11485         wait $create_pid || return 1
11486
11487         unlinkmany $DIR/$tdir/f $nr
11488 }
11489 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11490
11491 test_140() { #bug-17379
11492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11493
11494         test_mkdir $DIR/$tdir
11495         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11496         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11497
11498         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11499         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11500         local i=0
11501         while i=$((i + 1)); do
11502                 test_mkdir $i
11503                 cd $i || error "Changing to $i"
11504                 ln -s ../stat stat || error "Creating stat symlink"
11505                 # Read the symlink until ELOOP present,
11506                 # not LBUGing the system is considered success,
11507                 # we didn't overrun the stack.
11508                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11509                 if [ $ret -ne 0 ]; then
11510                         if [ $ret -eq 40 ]; then
11511                                 break  # -ELOOP
11512                         else
11513                                 error "Open stat symlink"
11514                                         return
11515                         fi
11516                 fi
11517         done
11518         i=$((i - 1))
11519         echo "The symlink depth = $i"
11520         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11521                 error "Invalid symlink depth"
11522
11523         # Test recursive symlink
11524         ln -s symlink_self symlink_self
11525         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11526         echo "open symlink_self returns $ret"
11527         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11528 }
11529 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11530
11531 test_150() {
11532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11533
11534         local TF="$TMP/$tfile"
11535
11536         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11537         cp $TF $DIR/$tfile
11538         cancel_lru_locks $OSC
11539         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11540         remount_client $MOUNT
11541         df -P $MOUNT
11542         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11543
11544         $TRUNCATE $TF 6000
11545         $TRUNCATE $DIR/$tfile 6000
11546         cancel_lru_locks $OSC
11547         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11548
11549         echo "12345" >>$TF
11550         echo "12345" >>$DIR/$tfile
11551         cancel_lru_locks $OSC
11552         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11553
11554         echo "12345" >>$TF
11555         echo "12345" >>$DIR/$tfile
11556         cancel_lru_locks $OSC
11557         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11558
11559         rm -f $TF
11560         true
11561 }
11562 run_test 150 "truncate/append tests"
11563
11564 #LU-2902 roc_hit was not able to read all values from lproc
11565 function roc_hit_init() {
11566         local list=$(comma_list $(osts_nodes))
11567         local dir=$DIR/$tdir-check
11568         local file=$dir/$tfile
11569         local BEFORE
11570         local AFTER
11571         local idx
11572
11573         test_mkdir $dir
11574         #use setstripe to do a write to every ost
11575         for i in $(seq 0 $((OSTCOUNT-1))); do
11576                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11577                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11578                 idx=$(printf %04x $i)
11579                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11580                         awk '$1 == "cache_access" {sum += $7}
11581                                 END { printf("%0.0f", sum) }')
11582
11583                 cancel_lru_locks osc
11584                 cat $file >/dev/null
11585
11586                 AFTER=$(get_osd_param $list *OST*$idx stats |
11587                         awk '$1 == "cache_access" {sum += $7}
11588                                 END { printf("%0.0f", sum) }')
11589
11590                 echo BEFORE:$BEFORE AFTER:$AFTER
11591                 if ! let "AFTER - BEFORE == 4"; then
11592                         rm -rf $dir
11593                         error "roc_hit is not safe to use"
11594                 fi
11595                 rm $file
11596         done
11597
11598         rm -rf $dir
11599 }
11600
11601 function roc_hit() {
11602         local list=$(comma_list $(osts_nodes))
11603         echo $(get_osd_param $list '' stats |
11604                 awk '$1 == "cache_hit" {sum += $7}
11605                         END { printf("%0.0f", sum) }')
11606 }
11607
11608 function set_cache() {
11609         local on=1
11610
11611         if [ "$2" == "off" ]; then
11612                 on=0;
11613         fi
11614         local list=$(comma_list $(osts_nodes))
11615         set_osd_param $list '' $1_cache_enable $on
11616
11617         cancel_lru_locks osc
11618 }
11619
11620 test_151() {
11621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11622         remote_ost_nodsh && skip "remote OST with nodsh"
11623
11624         local CPAGES=3
11625         local list=$(comma_list $(osts_nodes))
11626
11627         # check whether obdfilter is cache capable at all
11628         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11629                 skip "not cache-capable obdfilter"
11630         fi
11631
11632         # check cache is enabled on all obdfilters
11633         if get_osd_param $list '' read_cache_enable | grep 0; then
11634                 skip "oss cache is disabled"
11635         fi
11636
11637         set_osd_param $list '' writethrough_cache_enable 1
11638
11639         # check write cache is enabled on all obdfilters
11640         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11641                 skip "oss write cache is NOT enabled"
11642         fi
11643
11644         roc_hit_init
11645
11646         #define OBD_FAIL_OBD_NO_LRU  0x609
11647         do_nodes $list $LCTL set_param fail_loc=0x609
11648
11649         # pages should be in the case right after write
11650         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11651                 error "dd failed"
11652
11653         local BEFORE=$(roc_hit)
11654         cancel_lru_locks osc
11655         cat $DIR/$tfile >/dev/null
11656         local AFTER=$(roc_hit)
11657
11658         do_nodes $list $LCTL set_param fail_loc=0
11659
11660         if ! let "AFTER - BEFORE == CPAGES"; then
11661                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11662         fi
11663
11664         # the following read invalidates the cache
11665         cancel_lru_locks osc
11666         set_osd_param $list '' read_cache_enable 0
11667         cat $DIR/$tfile >/dev/null
11668
11669         # now data shouldn't be found in the cache
11670         BEFORE=$(roc_hit)
11671         cancel_lru_locks osc
11672         cat $DIR/$tfile >/dev/null
11673         AFTER=$(roc_hit)
11674         if let "AFTER - BEFORE != 0"; then
11675                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11676         fi
11677
11678         set_osd_param $list '' read_cache_enable 1
11679         rm -f $DIR/$tfile
11680 }
11681 run_test 151 "test cache on oss and controls ==============================="
11682
11683 test_152() {
11684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11685
11686         local TF="$TMP/$tfile"
11687
11688         # simulate ENOMEM during write
11689 #define OBD_FAIL_OST_NOMEM      0x226
11690         lctl set_param fail_loc=0x80000226
11691         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11692         cp $TF $DIR/$tfile
11693         sync || error "sync failed"
11694         lctl set_param fail_loc=0
11695
11696         # discard client's cache
11697         cancel_lru_locks osc
11698
11699         # simulate ENOMEM during read
11700         lctl set_param fail_loc=0x80000226
11701         cmp $TF $DIR/$tfile || error "cmp failed"
11702         lctl set_param fail_loc=0
11703
11704         rm -f $TF
11705 }
11706 run_test 152 "test read/write with enomem ============================"
11707
11708 test_153() {
11709         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11710 }
11711 run_test 153 "test if fdatasync does not crash ======================="
11712
11713 dot_lustre_fid_permission_check() {
11714         local fid=$1
11715         local ffid=$MOUNT/.lustre/fid/$fid
11716         local test_dir=$2
11717
11718         echo "stat fid $fid"
11719         stat $ffid > /dev/null || error "stat $ffid failed."
11720         echo "touch fid $fid"
11721         touch $ffid || error "touch $ffid failed."
11722         echo "write to fid $fid"
11723         cat /etc/hosts > $ffid || error "write $ffid failed."
11724         echo "read fid $fid"
11725         diff /etc/hosts $ffid || error "read $ffid failed."
11726         echo "append write to fid $fid"
11727         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11728         echo "rename fid $fid"
11729         mv $ffid $test_dir/$tfile.1 &&
11730                 error "rename $ffid to $tfile.1 should fail."
11731         touch $test_dir/$tfile.1
11732         mv $test_dir/$tfile.1 $ffid &&
11733                 error "rename $tfile.1 to $ffid should fail."
11734         rm -f $test_dir/$tfile.1
11735         echo "truncate fid $fid"
11736         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11737         echo "link fid $fid"
11738         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11739         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11740                 echo "setfacl fid $fid"
11741                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11742                 echo "getfacl fid $fid"
11743                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11744         fi
11745         echo "unlink fid $fid"
11746         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11747         echo "mknod fid $fid"
11748         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11749
11750         fid=[0xf00000400:0x1:0x0]
11751         ffid=$MOUNT/.lustre/fid/$fid
11752
11753         echo "stat non-exist fid $fid"
11754         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11755         echo "write to non-exist fid $fid"
11756         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11757         echo "link new fid $fid"
11758         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11759
11760         mkdir -p $test_dir/$tdir
11761         touch $test_dir/$tdir/$tfile
11762         fid=$($LFS path2fid $test_dir/$tdir)
11763         rc=$?
11764         [ $rc -ne 0 ] &&
11765                 error "error: could not get fid for $test_dir/$dir/$tfile."
11766
11767         ffid=$MOUNT/.lustre/fid/$fid
11768
11769         echo "ls $fid"
11770         ls $ffid > /dev/null || error "ls $ffid failed."
11771         echo "touch $fid/$tfile.1"
11772         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11773
11774         echo "touch $MOUNT/.lustre/fid/$tfile"
11775         touch $MOUNT/.lustre/fid/$tfile && \
11776                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11777
11778         echo "setxattr to $MOUNT/.lustre/fid"
11779         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11780
11781         echo "listxattr for $MOUNT/.lustre/fid"
11782         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11783
11784         echo "delxattr from $MOUNT/.lustre/fid"
11785         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11786
11787         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11788         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11789                 error "touch invalid fid should fail."
11790
11791         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11792         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11793                 error "touch non-normal fid should fail."
11794
11795         echo "rename $tdir to $MOUNT/.lustre/fid"
11796         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11797                 error "rename to $MOUNT/.lustre/fid should fail."
11798
11799         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11800         then            # LU-3547
11801                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11802                 local new_obf_mode=777
11803
11804                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11805                 chmod $new_obf_mode $DIR/.lustre/fid ||
11806                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11807
11808                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11809                 [ $obf_mode -eq $new_obf_mode ] ||
11810                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11811
11812                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11813                 chmod $old_obf_mode $DIR/.lustre/fid ||
11814                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11815         fi
11816
11817         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11818         fid=$($LFS path2fid $test_dir/$tfile-2)
11819
11820         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11821         then # LU-5424
11822                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11823                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11824                         error "create lov data thru .lustre failed"
11825         fi
11826         echo "cp /etc/passwd $test_dir/$tfile-2"
11827         cp /etc/passwd $test_dir/$tfile-2 ||
11828                 error "copy to $test_dir/$tfile-2 failed."
11829         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11830         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11831                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11832
11833         rm -rf $test_dir/tfile.lnk
11834         rm -rf $test_dir/$tfile-2
11835 }
11836
11837 test_154A() {
11838         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11839                 skip "Need MDS version at least 2.4.1"
11840
11841         local tf=$DIR/$tfile
11842         touch $tf
11843
11844         local fid=$($LFS path2fid $tf)
11845         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11846
11847         # check that we get the same pathname back
11848         local found=$($LFS fid2path $MOUNT "$fid")
11849         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11850         [ "$found" == "$tf" ] ||
11851                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11852 }
11853 run_test 154A "lfs path2fid and fid2path basic checks"
11854
11855 test_154B() {
11856         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11857                 skip "Need MDS version at least 2.4.1"
11858
11859         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11860         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11861         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11862         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11863
11864         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11865         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11866
11867         # check that we get the same pathname
11868         echo "PFID: $PFID, name: $name"
11869         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11870         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11871         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11872                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11873
11874         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11875 }
11876 run_test 154B "verify the ll_decode_linkea tool"
11877
11878 test_154a() {
11879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11880         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11881         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11882                 skip "Need MDS version at least 2.2.51"
11883         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11884
11885         cp /etc/hosts $DIR/$tfile
11886
11887         fid=$($LFS path2fid $DIR/$tfile)
11888         rc=$?
11889         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11890
11891         dot_lustre_fid_permission_check "$fid" $DIR ||
11892                 error "dot lustre permission check $fid failed"
11893
11894         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11895
11896         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11897
11898         touch $MOUNT/.lustre/file &&
11899                 error "creation is not allowed under .lustre"
11900
11901         mkdir $MOUNT/.lustre/dir &&
11902                 error "mkdir is not allowed under .lustre"
11903
11904         rm -rf $DIR/$tfile
11905 }
11906 run_test 154a "Open-by-FID"
11907
11908 test_154b() {
11909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11910         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11912         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11913                 skip "Need MDS version at least 2.2.51"
11914
11915         local remote_dir=$DIR/$tdir/remote_dir
11916         local MDTIDX=1
11917         local rc=0
11918
11919         mkdir -p $DIR/$tdir
11920         $LFS mkdir -i $MDTIDX $remote_dir ||
11921                 error "create remote directory failed"
11922
11923         cp /etc/hosts $remote_dir/$tfile
11924
11925         fid=$($LFS path2fid $remote_dir/$tfile)
11926         rc=$?
11927         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11928
11929         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11930                 error "dot lustre permission check $fid failed"
11931         rm -rf $DIR/$tdir
11932 }
11933 run_test 154b "Open-by-FID for remote directory"
11934
11935 test_154c() {
11936         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11937                 skip "Need MDS version at least 2.4.1"
11938
11939         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11940         local FID1=$($LFS path2fid $DIR/$tfile.1)
11941         local FID2=$($LFS path2fid $DIR/$tfile.2)
11942         local FID3=$($LFS path2fid $DIR/$tfile.3)
11943
11944         local N=1
11945         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11946                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11947                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11948                 local want=FID$N
11949                 [ "$FID" = "${!want}" ] ||
11950                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11951                 N=$((N + 1))
11952         done
11953
11954         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11955         do
11956                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11957                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11958                 N=$((N + 1))
11959         done
11960 }
11961 run_test 154c "lfs path2fid and fid2path multiple arguments"
11962
11963 test_154d() {
11964         remote_mds_nodsh && skip "remote MDS with nodsh"
11965         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11966                 skip "Need MDS version at least 2.5.53"
11967
11968         if remote_mds; then
11969                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11970         else
11971                 nid="0@lo"
11972         fi
11973         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11974         local fd
11975         local cmd
11976
11977         rm -f $DIR/$tfile
11978         touch $DIR/$tfile
11979
11980         local fid=$($LFS path2fid $DIR/$tfile)
11981         # Open the file
11982         fd=$(free_fd)
11983         cmd="exec $fd<$DIR/$tfile"
11984         eval $cmd
11985         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11986         echo "$fid_list" | grep "$fid"
11987         rc=$?
11988
11989         cmd="exec $fd>/dev/null"
11990         eval $cmd
11991         if [ $rc -ne 0 ]; then
11992                 error "FID $fid not found in open files list $fid_list"
11993         fi
11994 }
11995 run_test 154d "Verify open file fid"
11996
11997 test_154e()
11998 {
11999         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12000                 skip "Need MDS version at least 2.6.50"
12001
12002         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12003                 error ".lustre returned by readdir"
12004         fi
12005 }
12006 run_test 154e ".lustre is not returned by readdir"
12007
12008 test_154f() {
12009         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12010
12011         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12012         test_mkdir -p -c1 $DIR/$tdir/d
12013         # test dirs inherit from its stripe
12014         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12015         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12016         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12017         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12018         touch $DIR/f
12019
12020         # get fid of parents
12021         local FID0=$($LFS path2fid $DIR/$tdir/d)
12022         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12023         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12024         local FID3=$($LFS path2fid $DIR)
12025
12026         # check that path2fid --parents returns expected <parent_fid>/name
12027         # 1) test for a directory (single parent)
12028         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12029         [ "$parent" == "$FID0/foo1" ] ||
12030                 error "expected parent: $FID0/foo1, got: $parent"
12031
12032         # 2) test for a file with nlink > 1 (multiple parents)
12033         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12034         echo "$parent" | grep -F "$FID1/$tfile" ||
12035                 error "$FID1/$tfile not returned in parent list"
12036         echo "$parent" | grep -F "$FID2/link" ||
12037                 error "$FID2/link not returned in parent list"
12038
12039         # 3) get parent by fid
12040         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12041         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12042         echo "$parent" | grep -F "$FID1/$tfile" ||
12043                 error "$FID1/$tfile not returned in parent list (by fid)"
12044         echo "$parent" | grep -F "$FID2/link" ||
12045                 error "$FID2/link not returned in parent list (by fid)"
12046
12047         # 4) test for entry in root directory
12048         parent=$($LFS path2fid --parents $DIR/f)
12049         echo "$parent" | grep -F "$FID3/f" ||
12050                 error "$FID3/f not returned in parent list"
12051
12052         # 5) test it on root directory
12053         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12054                 error "$MOUNT should not have parents"
12055
12056         # enable xattr caching and check that linkea is correctly updated
12057         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12058         save_lustre_params client "llite.*.xattr_cache" > $save
12059         lctl set_param llite.*.xattr_cache 1
12060
12061         # 6.1) linkea update on rename
12062         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12063
12064         # get parents by fid
12065         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12066         # foo1 should no longer be returned in parent list
12067         echo "$parent" | grep -F "$FID1" &&
12068                 error "$FID1 should no longer be in parent list"
12069         # the new path should appear
12070         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12071                 error "$FID2/$tfile.moved is not in parent list"
12072
12073         # 6.2) linkea update on unlink
12074         rm -f $DIR/$tdir/d/foo2/link
12075         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12076         # foo2/link should no longer be returned in parent list
12077         echo "$parent" | grep -F "$FID2/link" &&
12078                 error "$FID2/link should no longer be in parent list"
12079         true
12080
12081         rm -f $DIR/f
12082         restore_lustre_params < $save
12083         rm -f $save
12084 }
12085 run_test 154f "get parent fids by reading link ea"
12086
12087 test_154g()
12088 {
12089         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12090         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12091            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12092                 skip "Need MDS version at least 2.6.92"
12093
12094         mkdir -p $DIR/$tdir
12095         llapi_fid_test -d $DIR/$tdir
12096 }
12097 run_test 154g "various llapi FID tests"
12098
12099 test_155_small_load() {
12100     local temp=$TMP/$tfile
12101     local file=$DIR/$tfile
12102
12103     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12104         error "dd of=$temp bs=6096 count=1 failed"
12105     cp $temp $file
12106     cancel_lru_locks $OSC
12107     cmp $temp $file || error "$temp $file differ"
12108
12109     $TRUNCATE $temp 6000
12110     $TRUNCATE $file 6000
12111     cmp $temp $file || error "$temp $file differ (truncate1)"
12112
12113     echo "12345" >>$temp
12114     echo "12345" >>$file
12115     cmp $temp $file || error "$temp $file differ (append1)"
12116
12117     echo "12345" >>$temp
12118     echo "12345" >>$file
12119     cmp $temp $file || error "$temp $file differ (append2)"
12120
12121     rm -f $temp $file
12122     true
12123 }
12124
12125 test_155_big_load() {
12126         remote_ost_nodsh && skip "remote OST with nodsh"
12127
12128         local temp=$TMP/$tfile
12129         local file=$DIR/$tfile
12130
12131         free_min_max
12132         local cache_size=$(do_facet ost$((MAXI+1)) \
12133                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12134         local large_file_size=$((cache_size * 2))
12135
12136         echo "OSS cache size: $cache_size KB"
12137         echo "Large file size: $large_file_size KB"
12138
12139         [ $MAXV -le $large_file_size ] &&
12140                 skip_env "max available OST size needs > $large_file_size KB"
12141
12142         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12143
12144         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12145                 error "dd of=$temp bs=$large_file_size count=1k failed"
12146         cp $temp $file
12147         ls -lh $temp $file
12148         cancel_lru_locks osc
12149         cmp $temp $file || error "$temp $file differ"
12150
12151         rm -f $temp $file
12152         true
12153 }
12154
12155 save_writethrough() {
12156         local facets=$(get_facets OST)
12157
12158         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12159 }
12160
12161 test_155a() {
12162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12163
12164         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12165
12166         save_writethrough $p
12167
12168         set_cache read on
12169         set_cache writethrough on
12170         test_155_small_load
12171         restore_lustre_params < $p
12172         rm -f $p
12173 }
12174 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12175
12176 test_155b() {
12177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12178
12179         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12180
12181         save_writethrough $p
12182
12183         set_cache read on
12184         set_cache writethrough off
12185         test_155_small_load
12186         restore_lustre_params < $p
12187         rm -f $p
12188 }
12189 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12190
12191 test_155c() {
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 off
12199         set_cache writethrough on
12200         test_155_small_load
12201         restore_lustre_params < $p
12202         rm -f $p
12203 }
12204 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12205
12206 test_155d() {
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 off
12214         set_cache writethrough off
12215         test_155_small_load
12216         restore_lustre_params < $p
12217         rm -f $p
12218 }
12219 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12220
12221 test_155e() {
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 on
12229         set_cache writethrough on
12230         test_155_big_load
12231         restore_lustre_params < $p
12232         rm -f $p
12233 }
12234 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12235
12236 test_155f() {
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 on
12244         set_cache writethrough off
12245         test_155_big_load
12246         restore_lustre_params < $p
12247         rm -f $p
12248 }
12249 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12250
12251 test_155g() {
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 off
12259         set_cache writethrough on
12260         test_155_big_load
12261         restore_lustre_params < $p
12262         rm -f $p
12263 }
12264 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12265
12266 test_155h() {
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 off
12274         set_cache writethrough off
12275         test_155_big_load
12276         restore_lustre_params < $p
12277         rm -f $p
12278 }
12279 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12280
12281 test_156() {
12282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12283         remote_ost_nodsh && skip "remote OST with nodsh"
12284         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12285                 skip "stats not implemented on old servers"
12286         [ "$ost1_FSTYPE" = "zfs" ] &&
12287                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12288
12289         local CPAGES=3
12290         local BEFORE
12291         local AFTER
12292         local file="$DIR/$tfile"
12293         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12294
12295         save_writethrough $p
12296         roc_hit_init
12297
12298         log "Turn on read and write cache"
12299         set_cache read on
12300         set_cache writethrough on
12301
12302         log "Write data and read it back."
12303         log "Read should be satisfied from the cache."
12304         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12305         BEFORE=$(roc_hit)
12306         cancel_lru_locks osc
12307         cat $file >/dev/null
12308         AFTER=$(roc_hit)
12309         if ! let "AFTER - BEFORE == CPAGES"; then
12310                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12311         else
12312                 log "cache hits:: before: $BEFORE, after: $AFTER"
12313         fi
12314
12315         log "Read again; it should be satisfied from the cache."
12316         BEFORE=$AFTER
12317         cancel_lru_locks osc
12318         cat $file >/dev/null
12319         AFTER=$(roc_hit)
12320         if ! let "AFTER - BEFORE == CPAGES"; then
12321                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12322         else
12323                 log "cache hits:: before: $BEFORE, after: $AFTER"
12324         fi
12325
12326         log "Turn off the read cache and turn on the write cache"
12327         set_cache read off
12328         set_cache writethrough on
12329
12330         log "Read again; it should be satisfied from the cache."
12331         BEFORE=$(roc_hit)
12332         cancel_lru_locks osc
12333         cat $file >/dev/null
12334         AFTER=$(roc_hit)
12335         if ! let "AFTER - BEFORE == CPAGES"; then
12336                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12337         else
12338                 log "cache hits:: before: $BEFORE, after: $AFTER"
12339         fi
12340
12341         log "Read again; it should not be satisfied from the cache."
12342         BEFORE=$AFTER
12343         cancel_lru_locks osc
12344         cat $file >/dev/null
12345         AFTER=$(roc_hit)
12346         if ! let "AFTER - BEFORE == 0"; then
12347                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12348         else
12349                 log "cache hits:: before: $BEFORE, after: $AFTER"
12350         fi
12351
12352         log "Write data and read it back."
12353         log "Read should be satisfied from the cache."
12354         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12355         BEFORE=$(roc_hit)
12356         cancel_lru_locks osc
12357         cat $file >/dev/null
12358         AFTER=$(roc_hit)
12359         if ! let "AFTER - BEFORE == CPAGES"; then
12360                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12361         else
12362                 log "cache hits:: before: $BEFORE, after: $AFTER"
12363         fi
12364
12365         log "Read again; it should not be satisfied from the cache."
12366         BEFORE=$AFTER
12367         cancel_lru_locks osc
12368         cat $file >/dev/null
12369         AFTER=$(roc_hit)
12370         if ! let "AFTER - BEFORE == 0"; then
12371                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12372         else
12373                 log "cache hits:: before: $BEFORE, after: $AFTER"
12374         fi
12375
12376         log "Turn off read and write cache"
12377         set_cache read off
12378         set_cache writethrough off
12379
12380         log "Write data and read it back"
12381         log "It should not be satisfied from the cache."
12382         rm -f $file
12383         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12384         cancel_lru_locks osc
12385         BEFORE=$(roc_hit)
12386         cat $file >/dev/null
12387         AFTER=$(roc_hit)
12388         if ! let "AFTER - BEFORE == 0"; then
12389                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12390         else
12391                 log "cache hits:: before: $BEFORE, after: $AFTER"
12392         fi
12393
12394         log "Turn on the read cache and turn off the write cache"
12395         set_cache read on
12396         set_cache writethrough off
12397
12398         log "Write data and read it back"
12399         log "It should not be satisfied from the cache."
12400         rm -f $file
12401         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12402         BEFORE=$(roc_hit)
12403         cancel_lru_locks osc
12404         cat $file >/dev/null
12405         AFTER=$(roc_hit)
12406         if ! let "AFTER - BEFORE == 0"; then
12407                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12408         else
12409                 log "cache hits:: before: $BEFORE, after: $AFTER"
12410         fi
12411
12412         log "Read again; it should be satisfied from the cache."
12413         BEFORE=$(roc_hit)
12414         cancel_lru_locks osc
12415         cat $file >/dev/null
12416         AFTER=$(roc_hit)
12417         if ! let "AFTER - BEFORE == CPAGES"; then
12418                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12419         else
12420                 log "cache hits:: before: $BEFORE, after: $AFTER"
12421         fi
12422
12423         restore_lustre_params < $p
12424         rm -f $p $file
12425 }
12426 run_test 156 "Verification of tunables"
12427
12428 test_160a() {
12429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12430         remote_mds_nodsh && skip "remote MDS with nodsh"
12431         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12432                 skip "Need MDS version at least 2.2.0"
12433
12434         changelog_register || error "changelog_register failed"
12435         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12436         changelog_users $SINGLEMDS | grep -q $cl_user ||
12437                 error "User $cl_user not found in changelog_users"
12438
12439         # change something
12440         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12441         changelog_clear 0 || error "changelog_clear failed"
12442         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12443         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12444         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12445         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12446         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12447         rm $DIR/$tdir/pics/desktop.jpg
12448
12449         changelog_dump | tail -10
12450
12451         echo "verifying changelog mask"
12452         changelog_chmask "-MKDIR"
12453         changelog_chmask "-CLOSE"
12454
12455         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12456         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12457
12458         changelog_chmask "+MKDIR"
12459         changelog_chmask "+CLOSE"
12460
12461         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12462         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12463
12464         changelog_dump | tail -10
12465         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12466         CLOSES=$(changelog_dump | grep -c "CLOSE")
12467         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12468         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12469
12470         # verify contents
12471         echo "verifying target fid"
12472         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12473         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12474         [ "$fidc" == "$fidf" ] ||
12475                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12476         echo "verifying parent fid"
12477         # The FID returned from the Changelog may be the directory shard on
12478         # a different MDT, and not the FID returned by path2fid on the parent.
12479         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12480         # since this is what will matter when recreating this file in the tree.
12481         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12482         local pathp=$($LFS fid2path $MOUNT "$fidp")
12483         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12484                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12485
12486         echo "getting records for $cl_user"
12487         changelog_users $SINGLEMDS
12488         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12489         local nclr=3
12490         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12491                 error "changelog_clear failed"
12492         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12493         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12494         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12495                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12496
12497         local min0_rec=$(changelog_users $SINGLEMDS |
12498                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12499         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12500                           awk '{ print $1; exit; }')
12501
12502         changelog_dump | tail -n 5
12503         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12504         [ $first_rec == $((min0_rec + 1)) ] ||
12505                 error "first index should be $min0_rec + 1 not $first_rec"
12506
12507         # LU-3446 changelog index reset on MDT restart
12508         local cur_rec1=$(changelog_users $SINGLEMDS |
12509                          awk '/^current.index:/ { print $NF }')
12510         changelog_clear 0 ||
12511                 error "clear all changelog records for $cl_user failed"
12512         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12513         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12514                 error "Fail to start $SINGLEMDS"
12515         local cur_rec2=$(changelog_users $SINGLEMDS |
12516                          awk '/^current.index:/ { print $NF }')
12517         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12518         [ $cur_rec1 == $cur_rec2 ] ||
12519                 error "current index should be $cur_rec1 not $cur_rec2"
12520
12521         echo "verifying users from this test are deregistered"
12522         changelog_deregister || error "changelog_deregister failed"
12523         changelog_users $SINGLEMDS | grep -q $cl_user &&
12524                 error "User '$cl_user' still in changelog_users"
12525
12526         # lctl get_param -n mdd.*.changelog_users
12527         # current index: 144
12528         # ID    index (idle seconds)
12529         # cl3   144 (2)
12530         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12531                 # this is the normal case where all users were deregistered
12532                 # make sure no new records are added when no users are present
12533                 local last_rec1=$(changelog_users $SINGLEMDS |
12534                                   awk '/^current.index:/ { print $NF }')
12535                 touch $DIR/$tdir/chloe
12536                 local last_rec2=$(changelog_users $SINGLEMDS |
12537                                   awk '/^current.index:/ { print $NF }')
12538                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12539                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12540         else
12541                 # any changelog users must be leftovers from a previous test
12542                 changelog_users $SINGLEMDS
12543                 echo "other changelog users; can't verify off"
12544         fi
12545 }
12546 run_test 160a "changelog sanity"
12547
12548 test_160b() { # LU-3587
12549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12550         remote_mds_nodsh && skip "remote MDS with nodsh"
12551         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12552                 skip "Need MDS version at least 2.2.0"
12553
12554         changelog_register || error "changelog_register failed"
12555         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12556         changelog_users $SINGLEMDS | grep -q $cl_user ||
12557                 error "User '$cl_user' not found in changelog_users"
12558
12559         local longname1=$(str_repeat a 255)
12560         local longname2=$(str_repeat b 255)
12561
12562         cd $DIR
12563         echo "creating very long named file"
12564         touch $longname1 || error "create of '$longname1' failed"
12565         echo "renaming very long named file"
12566         mv $longname1 $longname2
12567
12568         changelog_dump | grep RENME | tail -n 5
12569         rm -f $longname2
12570 }
12571 run_test 160b "Verify that very long rename doesn't crash in changelog"
12572
12573 test_160c() {
12574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12575         remote_mds_nodsh && skip "remote MDS with nodsh"
12576
12577         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12578                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12579                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12580                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12581
12582         local rc=0
12583
12584         # Registration step
12585         changelog_register || error "changelog_register failed"
12586
12587         rm -rf $DIR/$tdir
12588         mkdir -p $DIR/$tdir
12589         $MCREATE $DIR/$tdir/foo_160c
12590         changelog_chmask "-TRUNC"
12591         $TRUNCATE $DIR/$tdir/foo_160c 200
12592         changelog_chmask "+TRUNC"
12593         $TRUNCATE $DIR/$tdir/foo_160c 199
12594         changelog_dump | tail -n 5
12595         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12596         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12597 }
12598 run_test 160c "verify that changelog log catch the truncate event"
12599
12600 test_160d() {
12601         remote_mds_nodsh && skip "remote MDS with nodsh"
12602         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12604         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12605                 skip "Need MDS version at least 2.7.60"
12606
12607         # Registration step
12608         changelog_register || error "changelog_register failed"
12609
12610         mkdir -p $DIR/$tdir/migrate_dir
12611         changelog_clear 0 || error "changelog_clear failed"
12612
12613         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12614         changelog_dump | tail -n 5
12615         local migrates=$(changelog_dump | grep -c "MIGRT")
12616         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12617 }
12618 run_test 160d "verify that changelog log catch the migrate event"
12619
12620 test_160e() {
12621         remote_mds_nodsh && skip "remote MDS with nodsh"
12622
12623         # Create a user
12624         changelog_register || error "changelog_register failed"
12625
12626         # Delete a future user (expect fail)
12627         local MDT0=$(facet_svc $SINGLEMDS)
12628         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12629         local rc=$?
12630
12631         if [ $rc -eq 0 ]; then
12632                 error "Deleted non-existant user cl77"
12633         elif [ $rc -ne 2 ]; then
12634                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12635         fi
12636
12637         # Clear to a bad index (1 billion should be safe)
12638         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12639         rc=$?
12640
12641         if [ $rc -eq 0 ]; then
12642                 error "Successfully cleared to invalid CL index"
12643         elif [ $rc -ne 22 ]; then
12644                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12645         fi
12646 }
12647 run_test 160e "changelog negative testing (should return errors)"
12648
12649 test_160f() {
12650         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12651         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12652                 skip "Need MDS version at least 2.10.56"
12653
12654         local mdts=$(comma_list $(mdts_nodes))
12655
12656         # Create a user
12657         changelog_register || error "first changelog_register failed"
12658         changelog_register || error "second changelog_register failed"
12659         local cl_users
12660         declare -A cl_user1
12661         declare -A cl_user2
12662         local user_rec1
12663         local user_rec2
12664         local i
12665
12666         # generate some changelog records to accumulate on each MDT
12667         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12668         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12669                 error "create $DIR/$tdir/$tfile failed"
12670
12671         # check changelogs have been generated
12672         local nbcl=$(changelog_dump | wc -l)
12673         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12674
12675         for param in "changelog_max_idle_time=10" \
12676                      "changelog_gc=1" \
12677                      "changelog_min_gc_interval=2" \
12678                      "changelog_min_free_cat_entries=3"; do
12679                 local MDT0=$(facet_svc $SINGLEMDS)
12680                 local var="${param%=*}"
12681                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12682
12683                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12684                 do_nodes $mdts $LCTL set_param mdd.*.$param
12685         done
12686
12687         # force cl_user2 to be idle (1st part)
12688         sleep 9
12689
12690         # simulate changelog catalog almost full
12691         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12692         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12693
12694         for i in $(seq $MDSCOUNT); do
12695                 cl_users=(${CL_USERS[mds$i]})
12696                 cl_user1[mds$i]="${cl_users[0]}"
12697                 cl_user2[mds$i]="${cl_users[1]}"
12698
12699                 [ -n "${cl_user1[mds$i]}" ] ||
12700                         error "mds$i: no user registered"
12701                 [ -n "${cl_user2[mds$i]}" ] ||
12702                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12703
12704                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12705                 [ -n "$user_rec1" ] ||
12706                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12707                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12708                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12709                 [ -n "$user_rec2" ] ||
12710                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12711                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12712                      "$user_rec1 + 2 == $user_rec2"
12713                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12714                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12715                               "$user_rec1 + 2, but is $user_rec2"
12716                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12717                 [ -n "$user_rec2" ] ||
12718                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12719                 [ $user_rec1 == $user_rec2 ] ||
12720                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12721                               "$user_rec1, but is $user_rec2"
12722         done
12723
12724         # force cl_user2 to be idle (2nd part) and to reach
12725         # changelog_max_idle_time
12726         sleep 2
12727
12728         # generate one more changelog to trigger fail_loc
12729         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12730                 error "create $DIR/$tdir/${tfile}bis failed"
12731
12732         # ensure gc thread is done
12733         for i in $(mdts_nodes); do
12734                 wait_update $i \
12735                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12736                         error "$i: GC-thread not done"
12737         done
12738
12739         local first_rec
12740         for i in $(seq $MDSCOUNT); do
12741                 # check cl_user1 still registered
12742                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12743                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12744                 # check cl_user2 unregistered
12745                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12746                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12747
12748                 # check changelogs are present and starting at $user_rec1 + 1
12749                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12750                 [ -n "$user_rec1" ] ||
12751                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12752                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12753                             awk '{ print $1; exit; }')
12754
12755                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12756                 [ $((user_rec1 + 1)) == $first_rec ] ||
12757                         error "mds$i: first index should be $user_rec1 + 1, " \
12758                               "but is $first_rec"
12759         done
12760 }
12761 run_test 160f "changelog garbage collect (timestamped users)"
12762
12763 test_160g() {
12764         remote_mds_nodsh && skip "remote MDS with nodsh"
12765         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12766                 skip "Need MDS version at least 2.10.56"
12767
12768         local mdts=$(comma_list $(mdts_nodes))
12769
12770         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12771         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12772
12773         # Create a user
12774         changelog_register || error "first changelog_register failed"
12775         changelog_register || error "second changelog_register failed"
12776         local cl_users
12777         declare -A cl_user1
12778         declare -A cl_user2
12779         local user_rec1
12780         local user_rec2
12781         local i
12782
12783         # generate some changelog records to accumulate on each MDT
12784         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12785         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12786                 error "create $DIR/$tdir/$tfile failed"
12787
12788         # check changelogs have been generated
12789         local nbcl=$(changelog_dump | wc -l)
12790         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12791
12792         # reduce the max_idle_indexes value to make sure we exceed it
12793         max_ndx=$((nbcl / 2 - 1))
12794
12795         for param in "changelog_max_idle_indexes=$max_ndx" \
12796                      "changelog_gc=1" \
12797                      "changelog_min_gc_interval=2" \
12798                      "changelog_min_free_cat_entries=3"; do
12799                 local MDT0=$(facet_svc $SINGLEMDS)
12800                 local var="${param%=*}"
12801                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12802
12803                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12804                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12805                         error "unable to set mdd.*.$param"
12806         done
12807
12808         # simulate changelog catalog almost full
12809         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12810         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12811
12812         for i in $(seq $MDSCOUNT); do
12813                 cl_users=(${CL_USERS[mds$i]})
12814                 cl_user1[mds$i]="${cl_users[0]}"
12815                 cl_user2[mds$i]="${cl_users[1]}"
12816
12817                 [ -n "${cl_user1[mds$i]}" ] ||
12818                         error "mds$i: no user registered"
12819                 [ -n "${cl_user2[mds$i]}" ] ||
12820                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12821
12822                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12823                 [ -n "$user_rec1" ] ||
12824                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12825                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12826                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12827                 [ -n "$user_rec2" ] ||
12828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12829                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12830                      "$user_rec1 + 2 == $user_rec2"
12831                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12832                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12833                               "$user_rec1 + 2, but is $user_rec2"
12834                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12835                 [ -n "$user_rec2" ] ||
12836                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12837                 [ $user_rec1 == $user_rec2 ] ||
12838                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12839                               "$user_rec1, but is $user_rec2"
12840         done
12841
12842         # ensure we are past the previous changelog_min_gc_interval set above
12843         sleep 2
12844
12845         # generate one more changelog to trigger fail_loc
12846         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12847                 error "create $DIR/$tdir/${tfile}bis failed"
12848
12849         # ensure gc thread is done
12850         for i in $(mdts_nodes); do
12851                 wait_update $i \
12852                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12853                         error "$i: GC-thread not done"
12854         done
12855
12856         local first_rec
12857         for i in $(seq $MDSCOUNT); do
12858                 # check cl_user1 still registered
12859                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12860                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12861                 # check cl_user2 unregistered
12862                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12863                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12864
12865                 # check changelogs are present and starting at $user_rec1 + 1
12866                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12867                 [ -n "$user_rec1" ] ||
12868                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12869                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12870                             awk '{ print $1; exit; }')
12871
12872                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12873                 [ $((user_rec1 + 1)) == $first_rec ] ||
12874                         error "mds$i: first index should be $user_rec1 + 1, " \
12875                               "but is $first_rec"
12876         done
12877 }
12878 run_test 160g "changelog garbage collect (old users)"
12879
12880 test_160h() {
12881         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12882         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12883                 skip "Need MDS version at least 2.10.56"
12884
12885         local mdts=$(comma_list $(mdts_nodes))
12886
12887         # Create a user
12888         changelog_register || error "first changelog_register failed"
12889         changelog_register || error "second changelog_register failed"
12890         local cl_users
12891         declare -A cl_user1
12892         declare -A cl_user2
12893         local user_rec1
12894         local user_rec2
12895         local i
12896
12897         # generate some changelog records to accumulate on each MDT
12898         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12899         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12900                 error "create $DIR/$tdir/$tfile failed"
12901
12902         # check changelogs have been generated
12903         local nbcl=$(changelog_dump | wc -l)
12904         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12905
12906         for param in "changelog_max_idle_time=10" \
12907                      "changelog_gc=1" \
12908                      "changelog_min_gc_interval=2"; do
12909                 local MDT0=$(facet_svc $SINGLEMDS)
12910                 local var="${param%=*}"
12911                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12912
12913                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12914                 do_nodes $mdts $LCTL set_param mdd.*.$param
12915         done
12916
12917         # force cl_user2 to be idle (1st part)
12918         sleep 9
12919
12920         for i in $(seq $MDSCOUNT); do
12921                 cl_users=(${CL_USERS[mds$i]})
12922                 cl_user1[mds$i]="${cl_users[0]}"
12923                 cl_user2[mds$i]="${cl_users[1]}"
12924
12925                 [ -n "${cl_user1[mds$i]}" ] ||
12926                         error "mds$i: no user registered"
12927                 [ -n "${cl_user2[mds$i]}" ] ||
12928                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12929
12930                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12931                 [ -n "$user_rec1" ] ||
12932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12933                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12934                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12935                 [ -n "$user_rec2" ] ||
12936                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12937                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12938                      "$user_rec1 + 2 == $user_rec2"
12939                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12940                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12941                               "$user_rec1 + 2, but is $user_rec2"
12942                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12943                 [ -n "$user_rec2" ] ||
12944                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12945                 [ $user_rec1 == $user_rec2 ] ||
12946                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12947                               "$user_rec1, but is $user_rec2"
12948         done
12949
12950         # force cl_user2 to be idle (2nd part) and to reach
12951         # changelog_max_idle_time
12952         sleep 2
12953
12954         # force each GC-thread start and block then
12955         # one per MDT/MDD, set fail_val accordingly
12956         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12957         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12958
12959         # generate more changelogs to trigger fail_loc
12960         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12961                 error "create $DIR/$tdir/${tfile}bis failed"
12962
12963         # stop MDT to stop GC-thread, should be done in back-ground as it will
12964         # block waiting for the thread to be released and exit
12965         declare -A stop_pids
12966         for i in $(seq $MDSCOUNT); do
12967                 stop mds$i &
12968                 stop_pids[mds$i]=$!
12969         done
12970
12971         for i in $(mdts_nodes); do
12972                 local facet
12973                 local nb=0
12974                 local facets=$(facets_up_on_host $i)
12975
12976                 for facet in ${facets//,/ }; do
12977                         if [[ $facet == mds* ]]; then
12978                                 nb=$((nb + 1))
12979                         fi
12980                 done
12981                 # ensure each MDS's gc threads are still present and all in "R"
12982                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12983                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12984                         error "$i: expected $nb GC-thread"
12985                 wait_update $i \
12986                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12987                         "R" 20 ||
12988                         error "$i: GC-thread not found in R-state"
12989                 # check umounts of each MDT on MDS have reached kthread_stop()
12990                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12991                         error "$i: expected $nb umount"
12992                 wait_update $i \
12993                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12994                         error "$i: umount not found in D-state"
12995         done
12996
12997         # release all GC-threads
12998         do_nodes $mdts $LCTL set_param fail_loc=0
12999
13000         # wait for MDT stop to complete
13001         for i in $(seq $MDSCOUNT); do
13002                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13003         done
13004
13005         # XXX
13006         # may try to check if any orphan changelog records are present
13007         # via ldiskfs/zfs and llog_reader...
13008
13009         # re-start/mount MDTs
13010         for i in $(seq $MDSCOUNT); do
13011                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13012                         error "Fail to start mds$i"
13013         done
13014
13015         local first_rec
13016         for i in $(seq $MDSCOUNT); do
13017                 # check cl_user1 still registered
13018                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13019                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13020                 # check cl_user2 unregistered
13021                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13022                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13023
13024                 # check changelogs are present and starting at $user_rec1 + 1
13025                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13026                 [ -n "$user_rec1" ] ||
13027                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13028                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13029                             awk '{ print $1; exit; }')
13030
13031                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13032                 [ $((user_rec1 + 1)) == $first_rec ] ||
13033                         error "mds$i: first index should be $user_rec1 + 1, " \
13034                               "but is $first_rec"
13035         done
13036 }
13037 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13038               "during mount"
13039
13040 test_160i() {
13041
13042         local mdts=$(comma_list $(mdts_nodes))
13043
13044         changelog_register || error "first changelog_register failed"
13045
13046         # generate some changelog records to accumulate on each MDT
13047         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13048         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13049                 error "create $DIR/$tdir/$tfile failed"
13050
13051         # check changelogs have been generated
13052         local nbcl=$(changelog_dump | wc -l)
13053         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13054
13055         # simulate race between register and unregister
13056         # XXX as fail_loc is set per-MDS, with DNE configs the race
13057         # simulation will only occur for one MDT per MDS and for the
13058         # others the normal race scenario will take place
13059         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13060         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13061         do_nodes $mdts $LCTL set_param fail_val=1
13062
13063         # unregister 1st user
13064         changelog_deregister &
13065         local pid1=$!
13066         # wait some time for deregister work to reach race rdv
13067         sleep 2
13068         # register 2nd user
13069         changelog_register || error "2nd user register failed"
13070
13071         wait $pid1 || error "1st user deregister failed"
13072
13073         local i
13074         local last_rec
13075         declare -A LAST_REC
13076         for i in $(seq $MDSCOUNT); do
13077                 if changelog_users mds$i | grep "^cl"; then
13078                         # make sure new records are added with one user present
13079                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13080                                           awk '/^current.index:/ { print $NF }')
13081                 else
13082                         error "mds$i has no user registered"
13083                 fi
13084         done
13085
13086         # generate more changelog records to accumulate on each MDT
13087         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13088                 error "create $DIR/$tdir/${tfile}bis failed"
13089
13090         for i in $(seq $MDSCOUNT); do
13091                 last_rec=$(changelog_users $SINGLEMDS |
13092                            awk '/^current.index:/ { print $NF }')
13093                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13094                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13095                         error "changelogs are off on mds$i"
13096         done
13097 }
13098 run_test 160i "changelog user register/unregister race"
13099
13100 test_161a() {
13101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13102
13103         test_mkdir -c1 $DIR/$tdir
13104         cp /etc/hosts $DIR/$tdir/$tfile
13105         test_mkdir -c1 $DIR/$tdir/foo1
13106         test_mkdir -c1 $DIR/$tdir/foo2
13107         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13108         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13109         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13110         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13111         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13112         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13113                 $LFS fid2path $DIR $FID
13114                 error "bad link ea"
13115         fi
13116         # middle
13117         rm $DIR/$tdir/foo2/zachary
13118         # last
13119         rm $DIR/$tdir/foo2/thor
13120         # first
13121         rm $DIR/$tdir/$tfile
13122         # rename
13123         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13124         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13125                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13126         rm $DIR/$tdir/foo2/maggie
13127
13128         # overflow the EA
13129         local longname=$tfile.avg_len_is_thirty_two_
13130         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13131                 error_noexit 'failed to unlink many hardlinks'" EXIT
13132         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13133                 error "failed to hardlink many files"
13134         links=$($LFS fid2path $DIR $FID | wc -l)
13135         echo -n "${links}/1000 links in link EA"
13136         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13137 }
13138 run_test 161a "link ea sanity"
13139
13140 test_161b() {
13141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13142         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13143
13144         local MDTIDX=1
13145         local remote_dir=$DIR/$tdir/remote_dir
13146
13147         mkdir -p $DIR/$tdir
13148         $LFS mkdir -i $MDTIDX $remote_dir ||
13149                 error "create remote directory failed"
13150
13151         cp /etc/hosts $remote_dir/$tfile
13152         mkdir -p $remote_dir/foo1
13153         mkdir -p $remote_dir/foo2
13154         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13155         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13156         ln $remote_dir/$tfile $remote_dir/foo1/luna
13157         ln $remote_dir/$tfile $remote_dir/foo2/thor
13158
13159         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13160                      tr -d ']')
13161         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13162                 $LFS fid2path $DIR $FID
13163                 error "bad link ea"
13164         fi
13165         # middle
13166         rm $remote_dir/foo2/zachary
13167         # last
13168         rm $remote_dir/foo2/thor
13169         # first
13170         rm $remote_dir/$tfile
13171         # rename
13172         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13173         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13174         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13175                 $LFS fid2path $DIR $FID
13176                 error "bad link rename"
13177         fi
13178         rm $remote_dir/foo2/maggie
13179
13180         # overflow the EA
13181         local longname=filename_avg_len_is_thirty_two_
13182         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13183                 error "failed to hardlink many files"
13184         links=$($LFS fid2path $DIR $FID | wc -l)
13185         echo -n "${links}/1000 links in link EA"
13186         [[ ${links} -gt 60 ]] ||
13187                 error "expected at least 60 links in link EA"
13188         unlinkmany $remote_dir/foo2/$longname 1000 ||
13189         error "failed to unlink many hardlinks"
13190 }
13191 run_test 161b "link ea sanity under remote directory"
13192
13193 test_161c() {
13194         remote_mds_nodsh && skip "remote MDS with nodsh"
13195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13196         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13197                 skip "Need MDS version at least 2.1.5"
13198
13199         # define CLF_RENAME_LAST 0x0001
13200         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13201         changelog_register || error "changelog_register failed"
13202
13203         rm -rf $DIR/$tdir
13204         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13205         touch $DIR/$tdir/foo_161c
13206         touch $DIR/$tdir/bar_161c
13207         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13208         changelog_dump | grep RENME | tail -n 5
13209         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13210         changelog_clear 0 || error "changelog_clear failed"
13211         if [ x$flags != "x0x1" ]; then
13212                 error "flag $flags is not 0x1"
13213         fi
13214
13215         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13216         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13217         touch $DIR/$tdir/foo_161c
13218         touch $DIR/$tdir/bar_161c
13219         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13221         changelog_dump | grep RENME | tail -n 5
13222         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13223         changelog_clear 0 || error "changelog_clear failed"
13224         if [ x$flags != "x0x0" ]; then
13225                 error "flag $flags is not 0x0"
13226         fi
13227         echo "rename overwrite a target having nlink > 1," \
13228                 "changelog record has flags of $flags"
13229
13230         # rename doesn't overwrite a target (changelog flag 0x0)
13231         touch $DIR/$tdir/foo_161c
13232         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13233         changelog_dump | grep RENME | tail -n 5
13234         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13235         changelog_clear 0 || error "changelog_clear failed"
13236         if [ x$flags != "x0x0" ]; then
13237                 error "flag $flags is not 0x0"
13238         fi
13239         echo "rename doesn't overwrite a target," \
13240                 "changelog record has flags of $flags"
13241
13242         # define CLF_UNLINK_LAST 0x0001
13243         # unlink a file having nlink = 1 (changelog flag 0x1)
13244         rm -f $DIR/$tdir/foo2_161c
13245         changelog_dump | grep UNLNK | tail -n 5
13246         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13247         changelog_clear 0 || error "changelog_clear failed"
13248         if [ x$flags != "x0x1" ]; then
13249                 error "flag $flags is not 0x1"
13250         fi
13251         echo "unlink a file having nlink = 1," \
13252                 "changelog record has flags of $flags"
13253
13254         # unlink a file having nlink > 1 (changelog flag 0x0)
13255         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13256         rm -f $DIR/$tdir/foobar_161c
13257         changelog_dump | grep UNLNK | tail -n 5
13258         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13259         changelog_clear 0 || error "changelog_clear failed"
13260         if [ x$flags != "x0x0" ]; then
13261                 error "flag $flags is not 0x0"
13262         fi
13263         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13264 }
13265 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13266
13267 test_161d() {
13268         remote_mds_nodsh && skip "remote MDS with nodsh"
13269         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13270
13271         local pid
13272         local fid
13273
13274         changelog_register || error "changelog_register failed"
13275
13276         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13277         # interfer with $MOUNT/.lustre/fid/ access
13278         mkdir $DIR/$tdir
13279         [[ $? -eq 0 ]] || error "mkdir failed"
13280
13281         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13282         $LCTL set_param fail_loc=0x8000140c
13283         # 5s pause
13284         $LCTL set_param fail_val=5
13285
13286         # create file
13287         echo foofoo > $DIR/$tdir/$tfile &
13288         pid=$!
13289
13290         # wait for create to be delayed
13291         sleep 2
13292
13293         ps -p $pid
13294         [[ $? -eq 0 ]] || error "create should be blocked"
13295
13296         local tempfile=$(mktemp)
13297         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13298         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13299         # some delay may occur during ChangeLog publishing and file read just
13300         # above, that could allow file write to happen finally
13301         [[ -s $tempfile ]] && echo "file should be empty"
13302
13303         $LCTL set_param fail_loc=0
13304
13305         wait $pid
13306         [[ $? -eq 0 ]] || error "create failed"
13307 }
13308 run_test 161d "create with concurrent .lustre/fid access"
13309
13310 check_path() {
13311         local expected="$1"
13312         shift
13313         local fid="$2"
13314
13315         local path
13316         path=$($LFS fid2path "$@")
13317         local rc=$?
13318
13319         if [ $rc -ne 0 ]; then
13320                 error "path looked up of '$expected' failed: rc=$rc"
13321         elif [ "$path" != "$expected" ]; then
13322                 error "path looked up '$path' instead of '$expected'"
13323         else
13324                 echo "FID '$fid' resolves to path '$path' as expected"
13325         fi
13326 }
13327
13328 test_162a() { # was test_162
13329         test_mkdir -p -c1 $DIR/$tdir/d2
13330         touch $DIR/$tdir/d2/$tfile
13331         touch $DIR/$tdir/d2/x1
13332         touch $DIR/$tdir/d2/x2
13333         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13334         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13335         # regular file
13336         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13337         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13338
13339         # softlink
13340         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13341         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13342         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13343
13344         # softlink to wrong file
13345         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13346         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13347         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13348
13349         # hardlink
13350         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13351         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13352         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13353         # fid2path dir/fsname should both work
13354         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13355         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13356
13357         # hardlink count: check that there are 2 links
13358         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13359         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13360
13361         # hardlink indexing: remove the first link
13362         rm $DIR/$tdir/d2/p/q/r/hlink
13363         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13364 }
13365 run_test 162a "path lookup sanity"
13366
13367 test_162b() {
13368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13370
13371         mkdir $DIR/$tdir
13372         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13373                                 error "create striped dir failed"
13374
13375         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13376                                         tail -n 1 | awk '{print $2}')
13377         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13378
13379         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13380         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13381
13382         # regular file
13383         for ((i=0;i<5;i++)); do
13384                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13385                         error "get fid for f$i failed"
13386                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13387
13388                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13389                         error "get fid for d$i failed"
13390                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13391         done
13392
13393         return 0
13394 }
13395 run_test 162b "striped directory path lookup sanity"
13396
13397 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13398 test_162c() {
13399         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13400                 skip "Need MDS version at least 2.7.51"
13401
13402         local lpath=$tdir.local
13403         local rpath=$tdir.remote
13404
13405         test_mkdir $DIR/$lpath
13406         test_mkdir $DIR/$rpath
13407
13408         for ((i = 0; i <= 101; i++)); do
13409                 lpath="$lpath/$i"
13410                 mkdir $DIR/$lpath
13411                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13412                         error "get fid for local directory $DIR/$lpath failed"
13413                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13414
13415                 rpath="$rpath/$i"
13416                 test_mkdir $DIR/$rpath
13417                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13418                         error "get fid for remote directory $DIR/$rpath failed"
13419                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13420         done
13421
13422         return 0
13423 }
13424 run_test 162c "fid2path works with paths 100 or more directories deep"
13425
13426 test_169() {
13427         # do directio so as not to populate the page cache
13428         log "creating a 10 Mb file"
13429         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13430         log "starting reads"
13431         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13432         log "truncating the file"
13433         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13434         log "killing dd"
13435         kill %+ || true # reads might have finished
13436         echo "wait until dd is finished"
13437         wait
13438         log "removing the temporary file"
13439         rm -rf $DIR/$tfile || error "tmp file removal failed"
13440 }
13441 run_test 169 "parallel read and truncate should not deadlock"
13442
13443 test_170() {
13444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13445
13446         $LCTL clear     # bug 18514
13447         $LCTL debug_daemon start $TMP/${tfile}_log_good
13448         touch $DIR/$tfile
13449         $LCTL debug_daemon stop
13450         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13451                 error "sed failed to read log_good"
13452
13453         $LCTL debug_daemon start $TMP/${tfile}_log_good
13454         rm -rf $DIR/$tfile
13455         $LCTL debug_daemon stop
13456
13457         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13458                error "lctl df log_bad failed"
13459
13460         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13461         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13462
13463         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13464         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13465
13466         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13467                 error "bad_line good_line1 good_line2 are empty"
13468
13469         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13470         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13471         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13472
13473         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13474         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13475         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13476
13477         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13478                 error "bad_line_new good_line_new are empty"
13479
13480         local expected_good=$((good_line1 + good_line2*2))
13481
13482         rm -f $TMP/${tfile}*
13483         # LU-231, short malformed line may not be counted into bad lines
13484         if [ $bad_line -ne $bad_line_new ] &&
13485                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13486                 error "expected $bad_line bad lines, but got $bad_line_new"
13487                 return 1
13488         fi
13489
13490         if [ $expected_good -ne $good_line_new ]; then
13491                 error "expected $expected_good good lines, but got $good_line_new"
13492                 return 2
13493         fi
13494         true
13495 }
13496 run_test 170 "test lctl df to handle corrupted log ====================="
13497
13498 test_171() { # bug20592
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500
13501         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13502         $LCTL set_param fail_loc=0x50e
13503         $LCTL set_param fail_val=3000
13504         multiop_bg_pause $DIR/$tfile O_s || true
13505         local MULTIPID=$!
13506         kill -USR1 $MULTIPID
13507         # cause log dump
13508         sleep 3
13509         wait $MULTIPID
13510         if dmesg | grep "recursive fault"; then
13511                 error "caught a recursive fault"
13512         fi
13513         $LCTL set_param fail_loc=0
13514         true
13515 }
13516 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13517
13518 # it would be good to share it with obdfilter-survey/iokit-libecho code
13519 setup_obdecho_osc () {
13520         local rc=0
13521         local ost_nid=$1
13522         local obdfilter_name=$2
13523         echo "Creating new osc for $obdfilter_name on $ost_nid"
13524         # make sure we can find loopback nid
13525         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13526
13527         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13528                            ${obdfilter_name}_osc_UUID || rc=2; }
13529         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13530                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13531         return $rc
13532 }
13533
13534 cleanup_obdecho_osc () {
13535         local obdfilter_name=$1
13536         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13537         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13538         return 0
13539 }
13540
13541 obdecho_test() {
13542         local OBD=$1
13543         local node=$2
13544         local pages=${3:-64}
13545         local rc=0
13546         local id
13547
13548         local count=10
13549         local obd_size=$(get_obd_size $node $OBD)
13550         local page_size=$(get_page_size $node)
13551         if [[ -n "$obd_size" ]]; then
13552                 local new_count=$((obd_size / (pages * page_size / 1024)))
13553                 [[ $new_count -ge $count ]] || count=$new_count
13554         fi
13555
13556         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13557         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13558                            rc=2; }
13559         if [ $rc -eq 0 ]; then
13560             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13561             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13562         fi
13563         echo "New object id is $id"
13564         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13565                            rc=4; }
13566         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13567                            "test_brw $count w v $pages $id" || rc=4; }
13568         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13569                            rc=4; }
13570         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13571                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13572         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13573                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13574         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13575         return $rc
13576 }
13577
13578 test_180a() {
13579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13580
13581         if ! module_loaded obdecho; then
13582                 load_module obdecho/obdecho &&
13583                         stack_trap "rmmod obdecho" EXIT ||
13584                         error "unable to load obdecho on client"
13585         fi
13586
13587         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13588         local host=$($LCTL get_param -n osc.$osc.import |
13589                      awk '/current_connection:/ { print $2 }' )
13590         local target=$($LCTL get_param -n osc.$osc.import |
13591                        awk '/target:/ { print $2 }' )
13592         target=${target%_UUID}
13593
13594         if [ -n "$target" ]; then
13595                 setup_obdecho_osc $host $target &&
13596                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13597                         { error "obdecho setup failed with $?"; return; }
13598
13599                 obdecho_test ${target}_osc client ||
13600                         error "obdecho_test failed on ${target}_osc"
13601         else
13602                 $LCTL get_param osc.$osc.import
13603                 error "there is no osc.$osc.import target"
13604         fi
13605 }
13606 run_test 180a "test obdecho on osc"
13607
13608 test_180b() {
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610         remote_ost_nodsh && skip "remote OST with nodsh"
13611
13612         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13613                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13614                 error "failed to load module obdecho"
13615
13616         local target=$(do_facet ost1 $LCTL dl |
13617                        awk '/obdfilter/ { print $4; exit; }')
13618
13619         if [ -n "$target" ]; then
13620                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13621         else
13622                 do_facet ost1 $LCTL dl
13623                 error "there is no obdfilter target on ost1"
13624         fi
13625 }
13626 run_test 180b "test obdecho directly on obdfilter"
13627
13628 test_180c() { # LU-2598
13629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13630         remote_ost_nodsh && skip "remote OST with nodsh"
13631         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13632                 skip "Need MDS version at least 2.4.0"
13633
13634         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13635                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13636                 error "failed to load module obdecho"
13637
13638         local target=$(do_facet ost1 $LCTL dl |
13639                        awk '/obdfilter/ { print $4; exit; }')
13640
13641         if [ -n "$target" ]; then
13642                 local pages=16384 # 64MB bulk I/O RPC size
13643
13644                 obdecho_test "$target" ost1 "$pages" ||
13645                         error "obdecho_test with pages=$pages failed with $?"
13646         else
13647                 do_facet ost1 $LCTL dl
13648                 error "there is no obdfilter target on ost1"
13649         fi
13650 }
13651 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13652
13653 test_181() { # bug 22177
13654         test_mkdir $DIR/$tdir
13655         # create enough files to index the directory
13656         createmany -o $DIR/$tdir/foobar 4000
13657         # print attributes for debug purpose
13658         lsattr -d .
13659         # open dir
13660         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13661         MULTIPID=$!
13662         # remove the files & current working dir
13663         unlinkmany $DIR/$tdir/foobar 4000
13664         rmdir $DIR/$tdir
13665         kill -USR1 $MULTIPID
13666         wait $MULTIPID
13667         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13668         return 0
13669 }
13670 run_test 181 "Test open-unlinked dir ========================"
13671
13672 test_182() {
13673         local fcount=1000
13674         local tcount=10
13675
13676         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13677
13678         $LCTL set_param mdc.*.rpc_stats=clear
13679
13680         for (( i = 0; i < $tcount; i++ )) ; do
13681                 mkdir $DIR/$tdir/$i
13682         done
13683
13684         for (( i = 0; i < $tcount; i++ )) ; do
13685                 createmany -o $DIR/$tdir/$i/f- $fcount &
13686         done
13687         wait
13688
13689         for (( i = 0; i < $tcount; i++ )) ; do
13690                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13691         done
13692         wait
13693
13694         $LCTL get_param mdc.*.rpc_stats
13695
13696         rm -rf $DIR/$tdir
13697 }
13698 run_test 182 "Test parallel modify metadata operations ================"
13699
13700 test_183() { # LU-2275
13701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13702         remote_mds_nodsh && skip "remote MDS with nodsh"
13703         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13704                 skip "Need MDS version at least 2.3.56"
13705
13706         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13707         echo aaa > $DIR/$tdir/$tfile
13708
13709 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13710         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13711
13712         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13713         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13714
13715         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13716
13717         # Flush negative dentry cache
13718         touch $DIR/$tdir/$tfile
13719
13720         # We are not checking for any leaked references here, they'll
13721         # become evident next time we do cleanup with module unload.
13722         rm -rf $DIR/$tdir
13723 }
13724 run_test 183 "No crash or request leak in case of strange dispositions ========"
13725
13726 # test suite 184 is for LU-2016, LU-2017
13727 test_184a() {
13728         check_swap_layouts_support
13729
13730         dir0=$DIR/$tdir/$testnum
13731         test_mkdir -p -c1 $dir0
13732         ref1=/etc/passwd
13733         ref2=/etc/group
13734         file1=$dir0/f1
13735         file2=$dir0/f2
13736         $LFS setstripe -c1 $file1
13737         cp $ref1 $file1
13738         $LFS setstripe -c2 $file2
13739         cp $ref2 $file2
13740         gen1=$($LFS getstripe -g $file1)
13741         gen2=$($LFS getstripe -g $file2)
13742
13743         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13744         gen=$($LFS getstripe -g $file1)
13745         [[ $gen1 != $gen ]] ||
13746                 "Layout generation on $file1 does not change"
13747         gen=$($LFS getstripe -g $file2)
13748         [[ $gen2 != $gen ]] ||
13749                 "Layout generation on $file2 does not change"
13750
13751         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13752         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13753
13754         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13755 }
13756 run_test 184a "Basic layout swap"
13757
13758 test_184b() {
13759         check_swap_layouts_support
13760
13761         dir0=$DIR/$tdir/$testnum
13762         mkdir -p $dir0 || error "creating dir $dir0"
13763         file1=$dir0/f1
13764         file2=$dir0/f2
13765         file3=$dir0/f3
13766         dir1=$dir0/d1
13767         dir2=$dir0/d2
13768         mkdir $dir1 $dir2
13769         $LFS setstripe -c1 $file1
13770         $LFS setstripe -c2 $file2
13771         $LFS setstripe -c1 $file3
13772         chown $RUNAS_ID $file3
13773         gen1=$($LFS getstripe -g $file1)
13774         gen2=$($LFS getstripe -g $file2)
13775
13776         $LFS swap_layouts $dir1 $dir2 &&
13777                 error "swap of directories layouts should fail"
13778         $LFS swap_layouts $dir1 $file1 &&
13779                 error "swap of directory and file layouts should fail"
13780         $RUNAS $LFS swap_layouts $file1 $file2 &&
13781                 error "swap of file we cannot write should fail"
13782         $LFS swap_layouts $file1 $file3 &&
13783                 error "swap of file with different owner should fail"
13784         /bin/true # to clear error code
13785 }
13786 run_test 184b "Forbidden layout swap (will generate errors)"
13787
13788 test_184c() {
13789         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13790         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13791         check_swap_layouts_support
13792
13793         local dir0=$DIR/$tdir/$testnum
13794         mkdir -p $dir0 || error "creating dir $dir0"
13795
13796         local ref1=$dir0/ref1
13797         local ref2=$dir0/ref2
13798         local file1=$dir0/file1
13799         local file2=$dir0/file2
13800         # create a file large enough for the concurrent test
13801         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13802         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13803         echo "ref file size: ref1($(stat -c %s $ref1))," \
13804              "ref2($(stat -c %s $ref2))"
13805
13806         cp $ref2 $file2
13807         dd if=$ref1 of=$file1 bs=16k &
13808         local DD_PID=$!
13809
13810         # Make sure dd starts to copy file
13811         while [ ! -f $file1 ]; do sleep 0.1; done
13812
13813         $LFS swap_layouts $file1 $file2
13814         local rc=$?
13815         wait $DD_PID
13816         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13817         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13818
13819         # how many bytes copied before swapping layout
13820         local copied=$(stat -c %s $file2)
13821         local remaining=$(stat -c %s $ref1)
13822         remaining=$((remaining - copied))
13823         echo "Copied $copied bytes before swapping layout..."
13824
13825         cmp -n $copied $file1 $ref2 | grep differ &&
13826                 error "Content mismatch [0, $copied) of ref2 and file1"
13827         cmp -n $copied $file2 $ref1 ||
13828                 error "Content mismatch [0, $copied) of ref1 and file2"
13829         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13830                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13831
13832         # clean up
13833         rm -f $ref1 $ref2 $file1 $file2
13834 }
13835 run_test 184c "Concurrent write and layout swap"
13836
13837 test_184d() {
13838         check_swap_layouts_support
13839         [ -z "$(which getfattr 2>/dev/null)" ] &&
13840                 skip_env "no getfattr command"
13841
13842         local file1=$DIR/$tdir/$tfile-1
13843         local file2=$DIR/$tdir/$tfile-2
13844         local file3=$DIR/$tdir/$tfile-3
13845         local lovea1
13846         local lovea2
13847
13848         mkdir -p $DIR/$tdir
13849         touch $file1 || error "create $file1 failed"
13850         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13851                 error "create $file2 failed"
13852         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13853                 error "create $file3 failed"
13854         lovea1=$(get_layout_param $file1)
13855
13856         $LFS swap_layouts $file2 $file3 ||
13857                 error "swap $file2 $file3 layouts failed"
13858         $LFS swap_layouts $file1 $file2 ||
13859                 error "swap $file1 $file2 layouts failed"
13860
13861         lovea2=$(get_layout_param $file2)
13862         echo "$lovea1"
13863         echo "$lovea2"
13864         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13865
13866         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13867         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13868 }
13869 run_test 184d "allow stripeless layouts swap"
13870
13871 test_184e() {
13872         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13873                 skip "Need MDS version at least 2.6.94"
13874         check_swap_layouts_support
13875         [ -z "$(which getfattr 2>/dev/null)" ] &&
13876                 skip_env "no getfattr command"
13877
13878         local file1=$DIR/$tdir/$tfile-1
13879         local file2=$DIR/$tdir/$tfile-2
13880         local file3=$DIR/$tdir/$tfile-3
13881         local lovea
13882
13883         mkdir -p $DIR/$tdir
13884         touch $file1 || error "create $file1 failed"
13885         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13886                 error "create $file2 failed"
13887         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13888                 error "create $file3 failed"
13889
13890         $LFS swap_layouts $file1 $file2 ||
13891                 error "swap $file1 $file2 layouts failed"
13892
13893         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13894         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13895
13896         echo 123 > $file1 || error "Should be able to write into $file1"
13897
13898         $LFS swap_layouts $file1 $file3 ||
13899                 error "swap $file1 $file3 layouts failed"
13900
13901         echo 123 > $file1 || error "Should be able to write into $file1"
13902
13903         rm -rf $file1 $file2 $file3
13904 }
13905 run_test 184e "Recreate layout after stripeless layout swaps"
13906
13907 test_184f() {
13908         # Create a file with name longer than sizeof(struct stat) ==
13909         # 144 to see if we can get chars from the file name to appear
13910         # in the returned striping. Note that 'f' == 0x66.
13911         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13912
13913         mkdir -p $DIR/$tdir
13914         mcreate $DIR/$tdir/$file
13915         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13916                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13917         fi
13918 }
13919 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13920
13921 test_185() { # LU-2441
13922         # LU-3553 - no volatile file support in old servers
13923         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13924                 skip "Need MDS version at least 2.3.60"
13925
13926         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13927         touch $DIR/$tdir/spoo
13928         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13929         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13930                 error "cannot create/write a volatile file"
13931         [ "$FILESET" == "" ] &&
13932         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13933                 error "FID is still valid after close"
13934
13935         multiop_bg_pause $DIR/$tdir vVw4096_c
13936         local multi_pid=$!
13937
13938         local OLD_IFS=$IFS
13939         IFS=":"
13940         local fidv=($fid)
13941         IFS=$OLD_IFS
13942         # assume that the next FID for this client is sequential, since stdout
13943         # is unfortunately eaten by multiop_bg_pause
13944         local n=$((${fidv[1]} + 1))
13945         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13946         if [ "$FILESET" == "" ]; then
13947                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13948                         error "FID is missing before close"
13949         fi
13950         kill -USR1 $multi_pid
13951         # 1 second delay, so if mtime change we will see it
13952         sleep 1
13953         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13954         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13955 }
13956 run_test 185 "Volatile file support"
13957
13958 test_187a() {
13959         remote_mds_nodsh && skip "remote MDS with nodsh"
13960         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13961                 skip "Need MDS version at least 2.3.0"
13962
13963         local dir0=$DIR/$tdir/$testnum
13964         mkdir -p $dir0 || error "creating dir $dir0"
13965
13966         local file=$dir0/file1
13967         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13968         local dv1=$($LFS data_version $file)
13969         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13970         local dv2=$($LFS data_version $file)
13971         [[ $dv1 != $dv2 ]] ||
13972                 error "data version did not change on write $dv1 == $dv2"
13973
13974         # clean up
13975         rm -f $file1
13976 }
13977 run_test 187a "Test data version change"
13978
13979 test_187b() {
13980         remote_mds_nodsh && skip "remote MDS with nodsh"
13981         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13982                 skip "Need MDS version at least 2.3.0"
13983
13984         local dir0=$DIR/$tdir/$testnum
13985         mkdir -p $dir0 || error "creating dir $dir0"
13986
13987         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13988         [[ ${DV[0]} != ${DV[1]} ]] ||
13989                 error "data version did not change on write"\
13990                       " ${DV[0]} == ${DV[1]}"
13991
13992         # clean up
13993         rm -f $file1
13994 }
13995 run_test 187b "Test data version change on volatile file"
13996
13997 test_200() {
13998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13999         remote_mgs_nodsh && skip "remote MGS with nodsh"
14000         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14001
14002         local POOL=${POOL:-cea1}
14003         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14004         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14005         # Pool OST targets
14006         local first_ost=0
14007         local last_ost=$(($OSTCOUNT - 1))
14008         local ost_step=2
14009         local ost_list=$(seq $first_ost $ost_step $last_ost)
14010         local ost_range="$first_ost $last_ost $ost_step"
14011         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14012         local file_dir=$POOL_ROOT/file_tst
14013         local subdir=$test_path/subdir
14014         local rc=0
14015
14016         if ! combined_mgs_mds ; then
14017                 mount_mgs_client
14018         fi
14019
14020         while : ; do
14021                 # former test_200a test_200b
14022                 pool_add $POOL                          || { rc=$? ; break; }
14023                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14024                 # former test_200c test_200d
14025                 mkdir -p $test_path
14026                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14027                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14028                 mkdir -p $subdir
14029                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14030                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14031                                                         || { rc=$? ; break; }
14032                 # former test_200e test_200f
14033                 local files=$((OSTCOUNT*3))
14034                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14035                                                         || { rc=$? ; break; }
14036                 pool_create_files $POOL $file_dir $files "$ost_list" \
14037                                                         || { rc=$? ; break; }
14038                 # former test_200g test_200h
14039                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14040                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14041
14042                 # former test_201a test_201b test_201c
14043                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14044
14045                 local f=$test_path/$tfile
14046                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14047                 pool_remove $POOL $f                    || { rc=$? ; break; }
14048                 break
14049         done
14050
14051         destroy_test_pools
14052
14053         if ! combined_mgs_mds ; then
14054                 umount_mgs_client
14055         fi
14056         return $rc
14057 }
14058 run_test 200 "OST pools"
14059
14060 # usage: default_attr <count | size | offset>
14061 default_attr() {
14062         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14063 }
14064
14065 # usage: check_default_stripe_attr
14066 check_default_stripe_attr() {
14067         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14068         case $1 in
14069         --stripe-count|-c)
14070                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14071         --stripe-size|-S)
14072                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14073         --stripe-index|-i)
14074                 EXPECTED=-1;;
14075         *)
14076                 error "unknown getstripe attr '$1'"
14077         esac
14078
14079         [ $ACTUAL == $EXPECTED ] ||
14080                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14081 }
14082
14083 test_204a() {
14084         test_mkdir $DIR/$tdir
14085         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14086
14087         check_default_stripe_attr --stripe-count
14088         check_default_stripe_attr --stripe-size
14089         check_default_stripe_attr --stripe-index
14090 }
14091 run_test 204a "Print default stripe attributes"
14092
14093 test_204b() {
14094         test_mkdir $DIR/$tdir
14095         $LFS setstripe --stripe-count 1 $DIR/$tdir
14096
14097         check_default_stripe_attr --stripe-size
14098         check_default_stripe_attr --stripe-index
14099 }
14100 run_test 204b "Print default stripe size and offset"
14101
14102 test_204c() {
14103         test_mkdir $DIR/$tdir
14104         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14105
14106         check_default_stripe_attr --stripe-count
14107         check_default_stripe_attr --stripe-index
14108 }
14109 run_test 204c "Print default stripe count and offset"
14110
14111 test_204d() {
14112         test_mkdir $DIR/$tdir
14113         $LFS setstripe --stripe-index 0 $DIR/$tdir
14114
14115         check_default_stripe_attr --stripe-count
14116         check_default_stripe_attr --stripe-size
14117 }
14118 run_test 204d "Print default stripe count and size"
14119
14120 test_204e() {
14121         test_mkdir $DIR/$tdir
14122         $LFS setstripe -d $DIR/$tdir
14123
14124         check_default_stripe_attr --stripe-count --raw
14125         check_default_stripe_attr --stripe-size --raw
14126         check_default_stripe_attr --stripe-index --raw
14127 }
14128 run_test 204e "Print raw stripe attributes"
14129
14130 test_204f() {
14131         test_mkdir $DIR/$tdir
14132         $LFS setstripe --stripe-count 1 $DIR/$tdir
14133
14134         check_default_stripe_attr --stripe-size --raw
14135         check_default_stripe_attr --stripe-index --raw
14136 }
14137 run_test 204f "Print raw stripe size and offset"
14138
14139 test_204g() {
14140         test_mkdir $DIR/$tdir
14141         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14142
14143         check_default_stripe_attr --stripe-count --raw
14144         check_default_stripe_attr --stripe-index --raw
14145 }
14146 run_test 204g "Print raw stripe count and offset"
14147
14148 test_204h() {
14149         test_mkdir $DIR/$tdir
14150         $LFS setstripe --stripe-index 0 $DIR/$tdir
14151
14152         check_default_stripe_attr --stripe-count --raw
14153         check_default_stripe_attr --stripe-size --raw
14154 }
14155 run_test 204h "Print raw stripe count and size"
14156
14157 # Figure out which job scheduler is being used, if any,
14158 # or use a fake one
14159 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14160         JOBENV=SLURM_JOB_ID
14161 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14162         JOBENV=LSB_JOBID
14163 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14164         JOBENV=PBS_JOBID
14165 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14166         JOBENV=LOADL_STEP_ID
14167 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14168         JOBENV=JOB_ID
14169 else
14170         $LCTL list_param jobid_name > /dev/null 2>&1
14171         if [ $? -eq 0 ]; then
14172                 JOBENV=nodelocal
14173         else
14174                 JOBENV=FAKE_JOBID
14175         fi
14176 fi
14177 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14178
14179 verify_jobstats() {
14180         local cmd=($1)
14181         shift
14182         local facets="$@"
14183
14184 # we don't really need to clear the stats for this test to work, since each
14185 # command has a unique jobid, but it makes debugging easier if needed.
14186 #       for facet in $facets; do
14187 #               local dev=$(convert_facet2label $facet)
14188 #               # clear old jobstats
14189 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14190 #       done
14191
14192         # use a new JobID for each test, or we might see an old one
14193         [ "$JOBENV" = "FAKE_JOBID" ] &&
14194                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14195
14196         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14197
14198         [ "$JOBENV" = "nodelocal" ] && {
14199                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14200                 $LCTL set_param jobid_name=$FAKE_JOBID
14201                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14202         }
14203
14204         log "Test: ${cmd[*]}"
14205         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14206
14207         if [ $JOBENV = "FAKE_JOBID" ]; then
14208                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14209         else
14210                 ${cmd[*]}
14211         fi
14212
14213         # all files are created on OST0000
14214         for facet in $facets; do
14215                 local stats="*.$(convert_facet2label $facet).job_stats"
14216
14217                 # strip out libtool wrappers for in-tree executables
14218                 if [ $(do_facet $facet lctl get_param $stats |
14219                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14220                         do_facet $facet lctl get_param $stats
14221                         error "No jobstats for $JOBVAL found on $facet::$stats"
14222                 fi
14223         done
14224 }
14225
14226 jobstats_set() {
14227         local new_jobenv=$1
14228
14229         set_persistent_param_and_check client "jobid_var" \
14230                 "$FSNAME.sys.jobid_var" $new_jobenv
14231 }
14232
14233 test_205() { # Job stats
14234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14235         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14236                 skip "Need MDS version with at least 2.7.1"
14237         remote_mgs_nodsh && skip "remote MGS with nodsh"
14238         remote_mds_nodsh && skip "remote MDS with nodsh"
14239         remote_ost_nodsh && skip "remote OST with nodsh"
14240         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14241                 skip "Server doesn't support jobstats"
14242         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14243
14244         local old_jobenv=$($LCTL get_param -n jobid_var)
14245         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14246
14247         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14248                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14249         else
14250                 stack_trap "do_facet mgs $PERM_CMD \
14251                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14252         fi
14253         changelog_register
14254
14255         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14256                                 mdt.*.job_cleanup_interval | head -n 1)
14257         local new_interval=5
14258         do_facet $SINGLEMDS \
14259                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14260         stack_trap "do_facet $SINGLEMDS \
14261                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14262         local start=$SECONDS
14263
14264         local cmd
14265         # mkdir
14266         cmd="mkdir $DIR/$tdir"
14267         verify_jobstats "$cmd" "$SINGLEMDS"
14268         # rmdir
14269         cmd="rmdir $DIR/$tdir"
14270         verify_jobstats "$cmd" "$SINGLEMDS"
14271         # mkdir on secondary MDT
14272         if [ $MDSCOUNT -gt 1 ]; then
14273                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14274                 verify_jobstats "$cmd" "mds2"
14275         fi
14276         # mknod
14277         cmd="mknod $DIR/$tfile c 1 3"
14278         verify_jobstats "$cmd" "$SINGLEMDS"
14279         # unlink
14280         cmd="rm -f $DIR/$tfile"
14281         verify_jobstats "$cmd" "$SINGLEMDS"
14282         # create all files on OST0000 so verify_jobstats can find OST stats
14283         # open & close
14284         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14285         verify_jobstats "$cmd" "$SINGLEMDS"
14286         # setattr
14287         cmd="touch $DIR/$tfile"
14288         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14289         # write
14290         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14291         verify_jobstats "$cmd" "ost1"
14292         # read
14293         cancel_lru_locks osc
14294         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14295         verify_jobstats "$cmd" "ost1"
14296         # truncate
14297         cmd="$TRUNCATE $DIR/$tfile 0"
14298         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14299         # rename
14300         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14301         verify_jobstats "$cmd" "$SINGLEMDS"
14302         # jobstats expiry - sleep until old stats should be expired
14303         local left=$((new_interval + 5 - (SECONDS - start)))
14304         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14305                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14306                         "0" $left
14307         cmd="mkdir $DIR/$tdir.expire"
14308         verify_jobstats "$cmd" "$SINGLEMDS"
14309         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14310             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14311
14312         # Ensure that jobid are present in changelog (if supported by MDS)
14313         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14314                 changelog_dump | tail -10
14315                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14316                 [ $jobids -eq 9 ] ||
14317                         error "Wrong changelog jobid count $jobids != 9"
14318
14319                 # LU-5862
14320                 JOBENV="disable"
14321                 jobstats_set $JOBENV
14322                 touch $DIR/$tfile
14323                 changelog_dump | grep $tfile
14324                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14325                 [ $jobids -eq 0 ] ||
14326                         error "Unexpected jobids when jobid_var=$JOBENV"
14327         fi
14328
14329         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14330         JOBENV="JOBCOMPLEX"
14331         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14332
14333         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14334 }
14335 run_test 205 "Verify job stats"
14336
14337 # LU-1480, LU-1773 and LU-1657
14338 test_206() {
14339         mkdir -p $DIR/$tdir
14340         $LFS setstripe -c -1 $DIR/$tdir
14341 #define OBD_FAIL_LOV_INIT 0x1403
14342         $LCTL set_param fail_loc=0xa0001403
14343         $LCTL set_param fail_val=1
14344         touch $DIR/$tdir/$tfile || true
14345 }
14346 run_test 206 "fail lov_init_raid0() doesn't lbug"
14347
14348 test_207a() {
14349         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14350         local fsz=`stat -c %s $DIR/$tfile`
14351         cancel_lru_locks mdc
14352
14353         # do not return layout in getattr intent
14354 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14355         $LCTL set_param fail_loc=0x170
14356         local sz=`stat -c %s $DIR/$tfile`
14357
14358         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14359
14360         rm -rf $DIR/$tfile
14361 }
14362 run_test 207a "can refresh layout at glimpse"
14363
14364 test_207b() {
14365         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14366         local cksum=`md5sum $DIR/$tfile`
14367         local fsz=`stat -c %s $DIR/$tfile`
14368         cancel_lru_locks mdc
14369         cancel_lru_locks osc
14370
14371         # do not return layout in getattr intent
14372 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14373         $LCTL set_param fail_loc=0x171
14374
14375         # it will refresh layout after the file is opened but before read issues
14376         echo checksum is "$cksum"
14377         echo "$cksum" |md5sum -c --quiet || error "file differs"
14378
14379         rm -rf $DIR/$tfile
14380 }
14381 run_test 207b "can refresh layout at open"
14382
14383 test_208() {
14384         # FIXME: in this test suite, only RD lease is used. This is okay
14385         # for now as only exclusive open is supported. After generic lease
14386         # is done, this test suite should be revised. - Jinshan
14387
14388         remote_mds_nodsh && skip "remote MDS with nodsh"
14389         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14390                 skip "Need MDS version at least 2.4.52"
14391
14392         echo "==== test 1: verify get lease work"
14393         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14394
14395         echo "==== test 2: verify lease can be broken by upcoming open"
14396         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14397         local PID=$!
14398         sleep 1
14399
14400         $MULTIOP $DIR/$tfile oO_RDONLY:c
14401         kill -USR1 $PID && wait $PID || error "break lease error"
14402
14403         echo "==== test 3: verify lease can't be granted if an open already exists"
14404         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14405         local PID=$!
14406         sleep 1
14407
14408         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14409         kill -USR1 $PID && wait $PID || error "open file error"
14410
14411         echo "==== test 4: lease can sustain over recovery"
14412         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14413         PID=$!
14414         sleep 1
14415
14416         fail mds1
14417
14418         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14419
14420         echo "==== test 5: lease broken can't be regained by replay"
14421         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14422         PID=$!
14423         sleep 1
14424
14425         # open file to break lease and then recovery
14426         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14427         fail mds1
14428
14429         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14430
14431         rm -f $DIR/$tfile
14432 }
14433 run_test 208 "Exclusive open"
14434
14435 test_209() {
14436         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14437                 skip_env "must have disp_stripe"
14438
14439         touch $DIR/$tfile
14440         sync; sleep 5; sync;
14441
14442         echo 3 > /proc/sys/vm/drop_caches
14443         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14444
14445         # open/close 500 times
14446         for i in $(seq 500); do
14447                 cat $DIR/$tfile
14448         done
14449
14450         echo 3 > /proc/sys/vm/drop_caches
14451         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14452
14453         echo "before: $req_before, after: $req_after"
14454         [ $((req_after - req_before)) -ge 300 ] &&
14455                 error "open/close requests are not freed"
14456         return 0
14457 }
14458 run_test 209 "read-only open/close requests should be freed promptly"
14459
14460 test_212() {
14461         size=`date +%s`
14462         size=$((size % 8192 + 1))
14463         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14464         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14465         rm -f $DIR/f212 $DIR/f212.xyz
14466 }
14467 run_test 212 "Sendfile test ============================================"
14468
14469 test_213() {
14470         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14471         cancel_lru_locks osc
14472         lctl set_param fail_loc=0x8000040f
14473         # generate a read lock
14474         cat $DIR/$tfile > /dev/null
14475         # write to the file, it will try to cancel the above read lock.
14476         cat /etc/hosts >> $DIR/$tfile
14477 }
14478 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14479
14480 test_214() { # for bug 20133
14481         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14482         for (( i=0; i < 340; i++ )) ; do
14483                 touch $DIR/$tdir/d214c/a$i
14484         done
14485
14486         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14487         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14488         ls $DIR/d214c || error "ls $DIR/d214c failed"
14489         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14490         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14491 }
14492 run_test 214 "hash-indexed directory test - bug 20133"
14493
14494 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14495 create_lnet_proc_files() {
14496         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14497 }
14498
14499 # counterpart of create_lnet_proc_files
14500 remove_lnet_proc_files() {
14501         rm -f $TMP/lnet_$1.sys
14502 }
14503
14504 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14505 # 3rd arg as regexp for body
14506 check_lnet_proc_stats() {
14507         local l=$(cat "$TMP/lnet_$1" |wc -l)
14508         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14509
14510         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14511 }
14512
14513 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14514 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14515 # optional and can be regexp for 2nd line (lnet.routes case)
14516 check_lnet_proc_entry() {
14517         local blp=2          # blp stands for 'position of 1st line of body'
14518         [ -z "$5" ] || blp=3 # lnet.routes case
14519
14520         local l=$(cat "$TMP/lnet_$1" |wc -l)
14521         # subtracting one from $blp because the body can be empty
14522         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14523
14524         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14525                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14526
14527         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14528                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14529
14530         # bail out if any unexpected line happened
14531         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14532         [ "$?" != 0 ] || error "$2 misformatted"
14533 }
14534
14535 test_215() { # for bugs 18102, 21079, 21517
14536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14537
14538         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14539         local P='[1-9][0-9]*'           # positive numeric
14540         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14541         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14542         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14543         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14544
14545         local L1 # regexp for 1st line
14546         local L2 # regexp for 2nd line (optional)
14547         local BR # regexp for the rest (body)
14548
14549         # lnet.stats should look as 11 space-separated non-negative numerics
14550         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14551         create_lnet_proc_files "stats"
14552         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14553         remove_lnet_proc_files "stats"
14554
14555         # lnet.routes should look like this:
14556         # Routing disabled/enabled
14557         # net hops priority state router
14558         # where net is a string like tcp0, hops > 0, priority >= 0,
14559         # state is up/down,
14560         # router is a string like 192.168.1.1@tcp2
14561         L1="^Routing (disabled|enabled)$"
14562         L2="^net +hops +priority +state +router$"
14563         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14564         create_lnet_proc_files "routes"
14565         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14566         remove_lnet_proc_files "routes"
14567
14568         # lnet.routers should look like this:
14569         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14570         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14571         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14572         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14573         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14574         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14575         create_lnet_proc_files "routers"
14576         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14577         remove_lnet_proc_files "routers"
14578
14579         # lnet.peers should look like this:
14580         # nid refs state last max rtr min tx min queue
14581         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14582         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14583         # numeric (0 or >0 or <0), queue >= 0.
14584         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14585         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14586         create_lnet_proc_files "peers"
14587         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14588         remove_lnet_proc_files "peers"
14589
14590         # lnet.buffers  should look like this:
14591         # pages count credits min
14592         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14593         L1="^pages +count +credits +min$"
14594         BR="^ +$N +$N +$I +$I$"
14595         create_lnet_proc_files "buffers"
14596         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14597         remove_lnet_proc_files "buffers"
14598
14599         # lnet.nis should look like this:
14600         # nid status alive refs peer rtr max tx min
14601         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14602         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14603         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14604         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14605         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14606         create_lnet_proc_files "nis"
14607         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14608         remove_lnet_proc_files "nis"
14609
14610         # can we successfully write to lnet.stats?
14611         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14612 }
14613 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14614
14615 test_216() { # bug 20317
14616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14617         remote_ost_nodsh && skip "remote OST with nodsh"
14618
14619         local node
14620         local facets=$(get_facets OST)
14621         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14622
14623         save_lustre_params client "osc.*.contention_seconds" > $p
14624         save_lustre_params $facets \
14625                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14626         save_lustre_params $facets \
14627                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14628         save_lustre_params $facets \
14629                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14630         clear_stats osc.*.osc_stats
14631
14632         # agressive lockless i/o settings
14633         do_nodes $(comma_list $(osts_nodes)) \
14634                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14635                         ldlm.namespaces.filter-*.contended_locks=0 \
14636                         ldlm.namespaces.filter-*.contention_seconds=60"
14637         lctl set_param -n osc.*.contention_seconds=60
14638
14639         $DIRECTIO write $DIR/$tfile 0 10 4096
14640         $CHECKSTAT -s 40960 $DIR/$tfile
14641
14642         # disable lockless i/o
14643         do_nodes $(comma_list $(osts_nodes)) \
14644                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14645                         ldlm.namespaces.filter-*.contended_locks=32 \
14646                         ldlm.namespaces.filter-*.contention_seconds=0"
14647         lctl set_param -n osc.*.contention_seconds=0
14648         clear_stats osc.*.osc_stats
14649
14650         dd if=/dev/zero of=$DIR/$tfile count=0
14651         $CHECKSTAT -s 0 $DIR/$tfile
14652
14653         restore_lustre_params <$p
14654         rm -f $p
14655         rm $DIR/$tfile
14656 }
14657 run_test 216 "check lockless direct write updates file size and kms correctly"
14658
14659 test_217() { # bug 22430
14660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14661
14662         local node
14663         local nid
14664
14665         for node in $(nodes_list); do
14666                 nid=$(host_nids_address $node $NETTYPE)
14667                 if [[ $nid = *-* ]] ; then
14668                         echo "lctl ping $(h2nettype $nid)"
14669                         lctl ping $(h2nettype $nid)
14670                 else
14671                         echo "skipping $node (no hyphen detected)"
14672                 fi
14673         done
14674 }
14675 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14676
14677 test_218() {
14678        # do directio so as not to populate the page cache
14679        log "creating a 10 Mb file"
14680        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14681        log "starting reads"
14682        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14683        log "truncating the file"
14684        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14685        log "killing dd"
14686        kill %+ || true # reads might have finished
14687        echo "wait until dd is finished"
14688        wait
14689        log "removing the temporary file"
14690        rm -rf $DIR/$tfile || error "tmp file removal failed"
14691 }
14692 run_test 218 "parallel read and truncate should not deadlock"
14693
14694 test_219() {
14695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14696
14697         # write one partial page
14698         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14699         # set no grant so vvp_io_commit_write will do sync write
14700         $LCTL set_param fail_loc=0x411
14701         # write a full page at the end of file
14702         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14703
14704         $LCTL set_param fail_loc=0
14705         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14706         $LCTL set_param fail_loc=0x411
14707         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14708
14709         # LU-4201
14710         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14711         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14712 }
14713 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14714
14715 test_220() { #LU-325
14716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14717         remote_ost_nodsh && skip "remote OST with nodsh"
14718         remote_mds_nodsh && skip "remote MDS with nodsh"
14719         remote_mgs_nodsh && skip "remote MGS with nodsh"
14720
14721         local OSTIDX=0
14722
14723         # create on MDT0000 so the last_id and next_id are correct
14724         mkdir $DIR/$tdir
14725         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14726         OST=${OST%_UUID}
14727
14728         # on the mdt's osc
14729         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14730         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14731                         osc.$mdtosc_proc1.prealloc_last_id)
14732         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14733                         osc.$mdtosc_proc1.prealloc_next_id)
14734
14735         $LFS df -i
14736
14737         if ! combined_mgs_mds ; then
14738                 mount_mgs_client
14739         fi
14740
14741         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14742         #define OBD_FAIL_OST_ENOINO              0x229
14743         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14744         create_pool $FSNAME.$TESTNAME || return 1
14745         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14746
14747         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14748
14749         MDSOBJS=$((last_id - next_id))
14750         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14751
14752         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14753         echo "OST still has $count kbytes free"
14754
14755         echo "create $MDSOBJS files @next_id..."
14756         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14757
14758         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14759                         osc.$mdtosc_proc1.prealloc_last_id)
14760         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14761                         osc.$mdtosc_proc1.prealloc_next_id)
14762
14763         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14764         $LFS df -i
14765
14766         echo "cleanup..."
14767
14768         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14769         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14770
14771         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14772                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14773         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14774                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14775         echo "unlink $MDSOBJS files @$next_id..."
14776         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14777
14778         if ! combined_mgs_mds ; then
14779                 umount_mgs_client
14780         fi
14781 }
14782 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14783
14784 test_221() {
14785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14786
14787         dd if=`which date` of=$MOUNT/date oflag=sync
14788         chmod +x $MOUNT/date
14789
14790         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14791         $LCTL set_param fail_loc=0x80001401
14792
14793         $MOUNT/date > /dev/null
14794         rm -f $MOUNT/date
14795 }
14796 run_test 221 "make sure fault and truncate race to not cause OOM"
14797
14798 test_222a () {
14799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14800
14801         rm -rf $DIR/$tdir
14802         test_mkdir $DIR/$tdir
14803         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14804         createmany -o $DIR/$tdir/$tfile 10
14805         cancel_lru_locks mdc
14806         cancel_lru_locks osc
14807         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14808         $LCTL set_param fail_loc=0x31a
14809         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14810         $LCTL set_param fail_loc=0
14811         rm -r $DIR/$tdir
14812 }
14813 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14814
14815 test_222b () {
14816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14817
14818         rm -rf $DIR/$tdir
14819         test_mkdir $DIR/$tdir
14820         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14821         createmany -o $DIR/$tdir/$tfile 10
14822         cancel_lru_locks mdc
14823         cancel_lru_locks osc
14824         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14825         $LCTL set_param fail_loc=0x31a
14826         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14827         $LCTL set_param fail_loc=0
14828 }
14829 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14830
14831 test_223 () {
14832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14833
14834         rm -rf $DIR/$tdir
14835         test_mkdir $DIR/$tdir
14836         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14837         createmany -o $DIR/$tdir/$tfile 10
14838         cancel_lru_locks mdc
14839         cancel_lru_locks osc
14840         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14841         $LCTL set_param fail_loc=0x31b
14842         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14843         $LCTL set_param fail_loc=0
14844         rm -r $DIR/$tdir
14845 }
14846 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14847
14848 test_224a() { # LU-1039, MRP-303
14849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14850
14851         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14852         $LCTL set_param fail_loc=0x508
14853         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14854         $LCTL set_param fail_loc=0
14855         df $DIR
14856 }
14857 run_test 224a "Don't panic on bulk IO failure"
14858
14859 test_224b() { # LU-1039, MRP-303
14860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14861
14862         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14863         cancel_lru_locks osc
14864         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14865         $LCTL set_param fail_loc=0x515
14866         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14867         $LCTL set_param fail_loc=0
14868         df $DIR
14869 }
14870 run_test 224b "Don't panic on bulk IO failure"
14871
14872 test_224c() { # LU-6441
14873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14874         remote_mds_nodsh && skip "remote MDS with nodsh"
14875
14876         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14877         save_writethrough $p
14878         set_cache writethrough on
14879
14880         local pages_per_rpc=$($LCTL get_param \
14881                                 osc.*.max_pages_per_rpc)
14882         local at_max=$($LCTL get_param -n at_max)
14883         local timeout=$($LCTL get_param -n timeout)
14884         local test_at="at_max"
14885         local param_at="$FSNAME.sys.at_max"
14886         local test_timeout="timeout"
14887         local param_timeout="$FSNAME.sys.timeout"
14888
14889         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14890
14891         set_persistent_param_and_check client "$test_at" "$param_at" 0
14892         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14893
14894         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14895         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14896         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14897         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14898         sync
14899         do_facet ost1 "$LCTL set_param fail_loc=0"
14900
14901         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14902         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14903                 $timeout
14904
14905         $LCTL set_param -n $pages_per_rpc
14906         restore_lustre_params < $p
14907         rm -f $p
14908 }
14909 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14910
14911 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14912 test_225a () {
14913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14914         if [ -z ${MDSSURVEY} ]; then
14915                 skip_env "mds-survey not found"
14916         fi
14917         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14918                 skip "Need MDS version at least 2.2.51"
14919
14920         local mds=$(facet_host $SINGLEMDS)
14921         local target=$(do_nodes $mds 'lctl dl' |
14922                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14923
14924         local cmd1="file_count=1000 thrhi=4"
14925         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14926         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14927         local cmd="$cmd1 $cmd2 $cmd3"
14928
14929         rm -f ${TMP}/mds_survey*
14930         echo + $cmd
14931         eval $cmd || error "mds-survey with zero-stripe failed"
14932         cat ${TMP}/mds_survey*
14933         rm -f ${TMP}/mds_survey*
14934 }
14935 run_test 225a "Metadata survey sanity with zero-stripe"
14936
14937 test_225b () {
14938         if [ -z ${MDSSURVEY} ]; then
14939                 skip_env "mds-survey not found"
14940         fi
14941         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14942                 skip "Need MDS version at least 2.2.51"
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944         remote_mds_nodsh && skip "remote MDS with nodsh"
14945         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14946                 skip_env "Need to mount OST to test"
14947         fi
14948
14949         local mds=$(facet_host $SINGLEMDS)
14950         local target=$(do_nodes $mds 'lctl dl' |
14951                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14952
14953         local cmd1="file_count=1000 thrhi=4"
14954         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14955         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14956         local cmd="$cmd1 $cmd2 $cmd3"
14957
14958         rm -f ${TMP}/mds_survey*
14959         echo + $cmd
14960         eval $cmd || error "mds-survey with stripe_count failed"
14961         cat ${TMP}/mds_survey*
14962         rm -f ${TMP}/mds_survey*
14963 }
14964 run_test 225b "Metadata survey sanity with stripe_count = 1"
14965
14966 mcreate_path2fid () {
14967         local mode=$1
14968         local major=$2
14969         local minor=$3
14970         local name=$4
14971         local desc=$5
14972         local path=$DIR/$tdir/$name
14973         local fid
14974         local rc
14975         local fid_path
14976
14977         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14978                 error "cannot create $desc"
14979
14980         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14981         rc=$?
14982         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14983
14984         fid_path=$($LFS fid2path $MOUNT $fid)
14985         rc=$?
14986         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14987
14988         [ "$path" == "$fid_path" ] ||
14989                 error "fid2path returned $fid_path, expected $path"
14990
14991         echo "pass with $path and $fid"
14992 }
14993
14994 test_226a () {
14995         rm -rf $DIR/$tdir
14996         mkdir -p $DIR/$tdir
14997
14998         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14999         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15000         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15001         mcreate_path2fid 0040666 0 0 dir "directory"
15002         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15003         mcreate_path2fid 0100666 0 0 file "regular file"
15004         mcreate_path2fid 0120666 0 0 link "symbolic link"
15005         mcreate_path2fid 0140666 0 0 sock "socket"
15006 }
15007 run_test 226a "call path2fid and fid2path on files of all type"
15008
15009 test_226b () {
15010         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15011
15012         local MDTIDX=1
15013
15014         rm -rf $DIR/$tdir
15015         mkdir -p $DIR/$tdir
15016         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15017                 error "create remote directory failed"
15018         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15019         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15020                                 "character special file (null)"
15021         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15022                                 "character special file (no device)"
15023         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15024         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15025                                 "block special file (loop)"
15026         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15027         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15028         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15029 }
15030 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15031
15032 # LU-1299 Executing or running ldd on a truncated executable does not
15033 # cause an out-of-memory condition.
15034 test_227() {
15035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15036         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15037
15038         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15039         chmod +x $MOUNT/date
15040
15041         $MOUNT/date > /dev/null
15042         ldd $MOUNT/date > /dev/null
15043         rm -f $MOUNT/date
15044 }
15045 run_test 227 "running truncated executable does not cause OOM"
15046
15047 # LU-1512 try to reuse idle OI blocks
15048 test_228a() {
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050         remote_mds_nodsh && skip "remote MDS with nodsh"
15051         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15052
15053         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15054         local myDIR=$DIR/$tdir
15055
15056         mkdir -p $myDIR
15057         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15058         $LCTL set_param fail_loc=0x80001002
15059         createmany -o $myDIR/t- 10000
15060         $LCTL set_param fail_loc=0
15061         # The guard is current the largest FID holder
15062         touch $myDIR/guard
15063         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15064                     tr -d '[')
15065         local IDX=$(($SEQ % 64))
15066
15067         do_facet $SINGLEMDS sync
15068         # Make sure journal flushed.
15069         sleep 6
15070         local blk1=$(do_facet $SINGLEMDS \
15071                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15072                      grep Blockcount | awk '{print $4}')
15073
15074         # Remove old files, some OI blocks will become idle.
15075         unlinkmany $myDIR/t- 10000
15076         # Create new files, idle OI blocks should be reused.
15077         createmany -o $myDIR/t- 2000
15078         do_facet $SINGLEMDS sync
15079         # Make sure journal flushed.
15080         sleep 6
15081         local blk2=$(do_facet $SINGLEMDS \
15082                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15083                      grep Blockcount | awk '{print $4}')
15084
15085         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15086 }
15087 run_test 228a "try to reuse idle OI blocks"
15088
15089 test_228b() {
15090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15091         remote_mds_nodsh && skip "remote MDS with nodsh"
15092         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15093
15094         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15095         local myDIR=$DIR/$tdir
15096
15097         mkdir -p $myDIR
15098         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15099         $LCTL set_param fail_loc=0x80001002
15100         createmany -o $myDIR/t- 10000
15101         $LCTL set_param fail_loc=0
15102         # The guard is current the largest FID holder
15103         touch $myDIR/guard
15104         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15105                     tr -d '[')
15106         local IDX=$(($SEQ % 64))
15107
15108         do_facet $SINGLEMDS sync
15109         # Make sure journal flushed.
15110         sleep 6
15111         local blk1=$(do_facet $SINGLEMDS \
15112                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15113                      grep Blockcount | awk '{print $4}')
15114
15115         # Remove old files, some OI blocks will become idle.
15116         unlinkmany $myDIR/t- 10000
15117
15118         # stop the MDT
15119         stop $SINGLEMDS || error "Fail to stop MDT."
15120         # remount the MDT
15121         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15122
15123         df $MOUNT || error "Fail to df."
15124         # Create new files, idle OI blocks should be reused.
15125         createmany -o $myDIR/t- 2000
15126         do_facet $SINGLEMDS sync
15127         # Make sure journal flushed.
15128         sleep 6
15129         local blk2=$(do_facet $SINGLEMDS \
15130                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15131                      grep Blockcount | awk '{print $4}')
15132
15133         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15134 }
15135 run_test 228b "idle OI blocks can be reused after MDT restart"
15136
15137 #LU-1881
15138 test_228c() {
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140         remote_mds_nodsh && skip "remote MDS with nodsh"
15141         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15142
15143         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15144         local myDIR=$DIR/$tdir
15145
15146         mkdir -p $myDIR
15147         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15148         $LCTL set_param fail_loc=0x80001002
15149         # 20000 files can guarantee there are index nodes in the OI file
15150         createmany -o $myDIR/t- 20000
15151         $LCTL set_param fail_loc=0
15152         # The guard is current the largest FID holder
15153         touch $myDIR/guard
15154         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15155                     tr -d '[')
15156         local IDX=$(($SEQ % 64))
15157
15158         do_facet $SINGLEMDS sync
15159         # Make sure journal flushed.
15160         sleep 6
15161         local blk1=$(do_facet $SINGLEMDS \
15162                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15163                      grep Blockcount | awk '{print $4}')
15164
15165         # Remove old files, some OI blocks will become idle.
15166         unlinkmany $myDIR/t- 20000
15167         rm -f $myDIR/guard
15168         # The OI file should become empty now
15169
15170         # Create new files, idle OI blocks should be reused.
15171         createmany -o $myDIR/t- 2000
15172         do_facet $SINGLEMDS sync
15173         # Make sure journal flushed.
15174         sleep 6
15175         local blk2=$(do_facet $SINGLEMDS \
15176                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15177                      grep Blockcount | awk '{print $4}')
15178
15179         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15180 }
15181 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15182
15183 test_229() { # LU-2482, LU-3448
15184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15185         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15186         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15187                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15188
15189         rm -f $DIR/$tfile
15190
15191         # Create a file with a released layout and stripe count 2.
15192         $MULTIOP $DIR/$tfile H2c ||
15193                 error "failed to create file with released layout"
15194
15195         $LFS getstripe -v $DIR/$tfile
15196
15197         local pattern=$($LFS getstripe -L $DIR/$tfile)
15198         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15199
15200         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15201                 error "getstripe"
15202         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15203         stat $DIR/$tfile || error "failed to stat released file"
15204
15205         chown $RUNAS_ID $DIR/$tfile ||
15206                 error "chown $RUNAS_ID $DIR/$tfile failed"
15207
15208         chgrp $RUNAS_ID $DIR/$tfile ||
15209                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15210
15211         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15212         rm $DIR/$tfile || error "failed to remove released file"
15213 }
15214 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15215
15216 test_230a() {
15217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15219         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15220                 skip "Need MDS version at least 2.11.52"
15221
15222         local MDTIDX=1
15223
15224         test_mkdir $DIR/$tdir
15225         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15226         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15227         [ $mdt_idx -ne 0 ] &&
15228                 error "create local directory on wrong MDT $mdt_idx"
15229
15230         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15231                         error "create remote directory failed"
15232         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15233         [ $mdt_idx -ne $MDTIDX ] &&
15234                 error "create remote directory on wrong MDT $mdt_idx"
15235
15236         createmany -o $DIR/$tdir/test_230/t- 10 ||
15237                 error "create files on remote directory failed"
15238         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15239         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15240         rm -r $DIR/$tdir || error "unlink remote directory failed"
15241 }
15242 run_test 230a "Create remote directory and files under the remote directory"
15243
15244 test_230b() {
15245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15247         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15248                 skip "Need MDS version at least 2.11.52"
15249
15250         local MDTIDX=1
15251         local mdt_index
15252         local i
15253         local file
15254         local pid
15255         local stripe_count
15256         local migrate_dir=$DIR/$tdir/migrate_dir
15257         local other_dir=$DIR/$tdir/other_dir
15258
15259         test_mkdir $DIR/$tdir
15260         test_mkdir -i0 -c1 $migrate_dir
15261         test_mkdir -i0 -c1 $other_dir
15262         for ((i=0; i<10; i++)); do
15263                 mkdir -p $migrate_dir/dir_${i}
15264                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15265                         error "create files under remote dir failed $i"
15266         done
15267
15268         cp /etc/passwd $migrate_dir/$tfile
15269         cp /etc/passwd $other_dir/$tfile
15270         chattr +SAD $migrate_dir
15271         chattr +SAD $migrate_dir/$tfile
15272
15273         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15274         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15275         local old_dir_mode=$(stat -c%f $migrate_dir)
15276         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15277
15278         mkdir -p $migrate_dir/dir_default_stripe2
15279         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15280         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15281
15282         mkdir -p $other_dir
15283         ln $migrate_dir/$tfile $other_dir/luna
15284         ln $migrate_dir/$tfile $migrate_dir/sofia
15285         ln $other_dir/$tfile $migrate_dir/david
15286         ln -s $migrate_dir/$tfile $other_dir/zachary
15287         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15288         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15289
15290         $LFS migrate -m $MDTIDX $migrate_dir ||
15291                 error "fails on migrating remote dir to MDT1"
15292
15293         echo "migratate to MDT1, then checking.."
15294         for ((i = 0; i < 10; i++)); do
15295                 for file in $(find $migrate_dir/dir_${i}); do
15296                         mdt_index=$($LFS getstripe -m $file)
15297                         [ $mdt_index == $MDTIDX ] ||
15298                                 error "$file is not on MDT${MDTIDX}"
15299                 done
15300         done
15301
15302         # the multiple link file should still in MDT0
15303         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15304         [ $mdt_index == 0 ] ||
15305                 error "$file is not on MDT${MDTIDX}"
15306
15307         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15308         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15309                 error " expect $old_dir_flag get $new_dir_flag"
15310
15311         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15312         [ "$old_file_flag" = "$new_file_flag" ] ||
15313                 error " expect $old_file_flag get $new_file_flag"
15314
15315         local new_dir_mode=$(stat -c%f $migrate_dir)
15316         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15317                 error "expect mode $old_dir_mode get $new_dir_mode"
15318
15319         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15320         [ "$old_file_mode" = "$new_file_mode" ] ||
15321                 error "expect mode $old_file_mode get $new_file_mode"
15322
15323         diff /etc/passwd $migrate_dir/$tfile ||
15324                 error "$tfile different after migration"
15325
15326         diff /etc/passwd $other_dir/luna ||
15327                 error "luna different after migration"
15328
15329         diff /etc/passwd $migrate_dir/sofia ||
15330                 error "sofia different after migration"
15331
15332         diff /etc/passwd $migrate_dir/david ||
15333                 error "david different after migration"
15334
15335         diff /etc/passwd $other_dir/zachary ||
15336                 error "zachary different after migration"
15337
15338         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15339                 error "${tfile}_ln different after migration"
15340
15341         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15342                 error "${tfile}_ln_other different after migration"
15343
15344         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15345         [ $stripe_count = 2 ] ||
15346                 error "dir strpe_count $d != 2 after migration."
15347
15348         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15349         [ $stripe_count = 2 ] ||
15350                 error "file strpe_count $d != 2 after migration."
15351
15352         #migrate back to MDT0
15353         MDTIDX=0
15354
15355         $LFS migrate -m $MDTIDX $migrate_dir ||
15356                 error "fails on migrating remote dir to MDT0"
15357
15358         echo "migrate back to MDT0, checking.."
15359         for file in $(find $migrate_dir); do
15360                 mdt_index=$($LFS getstripe -m $file)
15361                 [ $mdt_index == $MDTIDX ] ||
15362                         error "$file is not on MDT${MDTIDX}"
15363         done
15364
15365         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15366         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15367                 error " expect $old_dir_flag get $new_dir_flag"
15368
15369         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15370         [ "$old_file_flag" = "$new_file_flag" ] ||
15371                 error " expect $old_file_flag get $new_file_flag"
15372
15373         local new_dir_mode=$(stat -c%f $migrate_dir)
15374         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15375                 error "expect mode $old_dir_mode get $new_dir_mode"
15376
15377         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15378         [ "$old_file_mode" = "$new_file_mode" ] ||
15379                 error "expect mode $old_file_mode get $new_file_mode"
15380
15381         diff /etc/passwd ${migrate_dir}/$tfile ||
15382                 error "$tfile different after migration"
15383
15384         diff /etc/passwd ${other_dir}/luna ||
15385                 error "luna different after migration"
15386
15387         diff /etc/passwd ${migrate_dir}/sofia ||
15388                 error "sofia different after migration"
15389
15390         diff /etc/passwd ${other_dir}/zachary ||
15391                 error "zachary different after migration"
15392
15393         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15394                 error "${tfile}_ln different after migration"
15395
15396         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15397                 error "${tfile}_ln_other different after migration"
15398
15399         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15400         [ $stripe_count = 2 ] ||
15401                 error "dir strpe_count $d != 2 after migration."
15402
15403         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15404         [ $stripe_count = 2 ] ||
15405                 error "file strpe_count $d != 2 after migration."
15406
15407         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15408 }
15409 run_test 230b "migrate directory"
15410
15411 test_230c() {
15412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15414         remote_mds_nodsh && skip "remote MDS with nodsh"
15415         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15416                 skip "Need MDS version at least 2.11.52"
15417
15418         local MDTIDX=1
15419         local total=3
15420         local mdt_index
15421         local file
15422         local migrate_dir=$DIR/$tdir/migrate_dir
15423
15424         #If migrating directory fails in the middle, all entries of
15425         #the directory is still accessiable.
15426         test_mkdir $DIR/$tdir
15427         test_mkdir -i0 -c1 $migrate_dir
15428         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15429         stat $migrate_dir
15430         createmany -o $migrate_dir/f $total ||
15431                 error "create files under ${migrate_dir} failed"
15432
15433         # fail after migrating top dir, and this will fail only once, so the
15434         # first sub file migration will fail (currently f3), others succeed.
15435         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15436         do_facet mds1 lctl set_param fail_loc=0x1801
15437         local t=$(ls $migrate_dir | wc -l)
15438         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15439                 error "migrate should fail"
15440         local u=$(ls $migrate_dir | wc -l)
15441         [ "$u" == "$t" ] || error "$u != $t during migration"
15442
15443         # add new dir/file should succeed
15444         mkdir $migrate_dir/dir ||
15445                 error "mkdir failed under migrating directory"
15446         touch $migrate_dir/file ||
15447                 error "create file failed under migrating directory"
15448
15449         # add file with existing name should fail
15450         for file in $migrate_dir/f*; do
15451                 stat $file > /dev/null || error "stat $file failed"
15452                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15453                         error "open(O_CREAT|O_EXCL) $file should fail"
15454                 $MULTIOP $file m && error "create $file should fail"
15455                 touch $DIR/$tdir/remote_dir/$tfile ||
15456                         error "touch $tfile failed"
15457                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15458                         error "link $file should fail"
15459                 mdt_index=$($LFS getstripe -m $file)
15460                 if [ $mdt_index == 0 ]; then
15461                         # file failed to migrate is not allowed to rename to
15462                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15463                                 error "rename to $file should fail"
15464                 else
15465                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15466                                 error "rename to $file failed"
15467                 fi
15468                 echo hello >> $file || error "write $file failed"
15469         done
15470
15471         # resume migration with different options should fail
15472         $LFS migrate -m 0 $migrate_dir &&
15473                 error "migrate -m 0 $migrate_dir should fail"
15474
15475         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15476                 error "migrate -c 2 $migrate_dir should fail"
15477
15478         # resume migration should succeed
15479         $LFS migrate -m $MDTIDX $migrate_dir ||
15480                 error "migrate $migrate_dir failed"
15481
15482         echo "Finish migration, then checking.."
15483         for file in $(find $migrate_dir); do
15484                 mdt_index=$($LFS getstripe -m $file)
15485                 [ $mdt_index == $MDTIDX ] ||
15486                         error "$file is not on MDT${MDTIDX}"
15487         done
15488
15489         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15490 }
15491 run_test 230c "check directory accessiblity if migration failed"
15492
15493 test_230d() {
15494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15496         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15497                 skip "Need MDS version at least 2.11.52"
15498         # LU-11235
15499         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15500
15501         local migrate_dir=$DIR/$tdir/migrate_dir
15502         local old_index
15503         local new_index
15504         local old_count
15505         local new_count
15506         local new_hash
15507         local mdt_index
15508         local i
15509         local j
15510
15511         old_index=$((RANDOM % MDSCOUNT))
15512         old_count=$((MDSCOUNT - old_index))
15513         new_index=$((RANDOM % MDSCOUNT))
15514         new_count=$((MDSCOUNT - new_index))
15515         new_hash="all_char"
15516
15517         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15518         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15519
15520         test_mkdir $DIR/$tdir
15521         test_mkdir -i $old_index -c $old_count $migrate_dir
15522
15523         for ((i=0; i<100; i++)); do
15524                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15525                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15526                         error "create files under remote dir failed $i"
15527         done
15528
15529         echo -n "Migrate from MDT$old_index "
15530         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15531         echo -n "to MDT$new_index"
15532         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15533         echo
15534
15535         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15536         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15537                 error "migrate remote dir error"
15538
15539         echo "Finish migration, then checking.."
15540         for file in $(find $migrate_dir); do
15541                 mdt_index=$($LFS getstripe -m $file)
15542                 if [ $mdt_index -lt $new_index ] ||
15543                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15544                         error "$file is on MDT$mdt_index"
15545                 fi
15546         done
15547
15548         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15549 }
15550 run_test 230d "check migrate big directory"
15551
15552 test_230e() {
15553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15555         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15556                 skip "Need MDS version at least 2.11.52"
15557
15558         local i
15559         local j
15560         local a_fid
15561         local b_fid
15562
15563         mkdir -p $DIR/$tdir
15564         mkdir $DIR/$tdir/migrate_dir
15565         mkdir $DIR/$tdir/other_dir
15566         touch $DIR/$tdir/migrate_dir/a
15567         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15568         ls $DIR/$tdir/other_dir
15569
15570         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15571                 error "migrate dir fails"
15572
15573         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15574         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15575
15576         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15577         [ $mdt_index == 0 ] || error "a is not on MDT0"
15578
15579         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15580                 error "migrate dir fails"
15581
15582         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15583         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15584
15585         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15586         [ $mdt_index == 1 ] || error "a is not on MDT1"
15587
15588         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15589         [ $mdt_index == 1 ] || error "b is not on MDT1"
15590
15591         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15592         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15593
15594         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15595
15596         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15597 }
15598 run_test 230e "migrate mulitple local link files"
15599
15600 test_230f() {
15601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15602         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15603         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15604                 skip "Need MDS version at least 2.11.52"
15605
15606         local a_fid
15607         local ln_fid
15608
15609         mkdir -p $DIR/$tdir
15610         mkdir $DIR/$tdir/migrate_dir
15611         $LFS mkdir -i1 $DIR/$tdir/other_dir
15612         touch $DIR/$tdir/migrate_dir/a
15613         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15614         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15615         ls $DIR/$tdir/other_dir
15616
15617         # a should be migrated to MDT1, since no other links on MDT0
15618         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15619                 error "#1 migrate dir fails"
15620         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15621         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15622         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15623         [ $mdt_index == 1 ] || error "a is not on MDT1"
15624
15625         # a should stay on MDT1, because it is a mulitple link file
15626         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15627                 error "#2 migrate dir fails"
15628         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15629         [ $mdt_index == 1 ] || error "a is not on MDT1"
15630
15631         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15632                 error "#3 migrate dir fails"
15633
15634         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15635         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15636         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15637
15638         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15639         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15640
15641         # a should be migrated to MDT0, since no other links on MDT1
15642         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15643                 error "#4 migrate dir fails"
15644         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15645         [ $mdt_index == 0 ] || error "a is not on MDT0"
15646
15647         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15648 }
15649 run_test 230f "migrate mulitple remote link files"
15650
15651 test_230g() {
15652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15654         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15655                 skip "Need MDS version at least 2.11.52"
15656
15657         mkdir -p $DIR/$tdir/migrate_dir
15658
15659         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15660                 error "migrating dir to non-exist MDT succeeds"
15661         true
15662 }
15663 run_test 230g "migrate dir to non-exist MDT"
15664
15665 test_230h() {
15666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15668         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15669                 skip "Need MDS version at least 2.11.52"
15670
15671         local mdt_index
15672
15673         mkdir -p $DIR/$tdir/migrate_dir
15674
15675         $LFS migrate -m1 $DIR &&
15676                 error "migrating mountpoint1 should fail"
15677
15678         $LFS migrate -m1 $DIR/$tdir/.. &&
15679                 error "migrating mountpoint2 should fail"
15680
15681         # same as mv
15682         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15683                 error "migrating $tdir/migrate_dir/.. should fail"
15684
15685         true
15686 }
15687 run_test 230h "migrate .. and root"
15688
15689 test_230i() {
15690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15692         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15693                 skip "Need MDS version at least 2.11.52"
15694
15695         mkdir -p $DIR/$tdir/migrate_dir
15696
15697         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15698                 error "migration fails with a tailing slash"
15699
15700         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15701                 error "migration fails with two tailing slashes"
15702 }
15703 run_test 230i "lfs migrate -m tolerates trailing slashes"
15704
15705 test_230j() {
15706         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15707         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15708                 skip "Need MDS version at least 2.11.52"
15709
15710         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15711         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15712                 error "create $tfile failed"
15713         cat /etc/passwd > $DIR/$tdir/$tfile
15714
15715         $LFS migrate -m 1 $DIR/$tdir
15716
15717         cmp /etc/passwd $DIR/$tdir/$tfile ||
15718                 error "DoM file mismatch after migration"
15719 }
15720 run_test 230j "DoM file data not changed after dir migration"
15721
15722 test_230k() {
15723         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15724         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15725                 skip "Need MDS version at least 2.11.56"
15726
15727         local total=20
15728         local files_on_starting_mdt=0
15729
15730         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15731         $LFS getdirstripe $DIR/$tdir
15732         for i in $(seq $total); do
15733                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15734                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15735                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15736         done
15737
15738         echo "$files_on_starting_mdt files on MDT0"
15739
15740         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15741         $LFS getdirstripe $DIR/$tdir
15742
15743         files_on_starting_mdt=0
15744         for i in $(seq $total); do
15745                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15746                         error "file $tfile.$i mismatch after migration"
15747                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15748                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15749         done
15750
15751         echo "$files_on_starting_mdt files on MDT1 after migration"
15752         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15753
15754         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15755         $LFS getdirstripe $DIR/$tdir
15756
15757         files_on_starting_mdt=0
15758         for i in $(seq $total); do
15759                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15760                         error "file $tfile.$i mismatch after 2nd migration"
15761                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15762                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15763         done
15764
15765         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15766         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15767
15768         true
15769 }
15770 run_test 230k "file data not changed after dir migration"
15771
15772 test_230l() {
15773         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15774         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15775                 skip "Need MDS version at least 2.11.56"
15776
15777         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15778         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15779                 error "create files under remote dir failed $i"
15780         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15781 }
15782 run_test 230l "readdir between MDTs won't crash"
15783
15784 test_231a()
15785 {
15786         # For simplicity this test assumes that max_pages_per_rpc
15787         # is the same across all OSCs
15788         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15789         local bulk_size=$((max_pages * PAGE_SIZE))
15790         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15791                                        head -n 1)
15792
15793         mkdir -p $DIR/$tdir
15794         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15795                 error "failed to set stripe with -S ${brw_size}M option"
15796
15797         # clear the OSC stats
15798         $LCTL set_param osc.*.stats=0 &>/dev/null
15799         stop_writeback
15800
15801         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15802         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15803                 oflag=direct &>/dev/null || error "dd failed"
15804
15805         sync; sleep 1; sync # just to be safe
15806         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15807         if [ x$nrpcs != "x1" ]; then
15808                 $LCTL get_param osc.*.stats
15809                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15810         fi
15811
15812         start_writeback
15813         # Drop the OSC cache, otherwise we will read from it
15814         cancel_lru_locks osc
15815
15816         # clear the OSC stats
15817         $LCTL set_param osc.*.stats=0 &>/dev/null
15818
15819         # Client reads $bulk_size.
15820         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15821                 iflag=direct &>/dev/null || error "dd failed"
15822
15823         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15824         if [ x$nrpcs != "x1" ]; then
15825                 $LCTL get_param osc.*.stats
15826                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15827         fi
15828 }
15829 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15830
15831 test_231b() {
15832         mkdir -p $DIR/$tdir
15833         local i
15834         for i in {0..1023}; do
15835                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15836                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15837                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15838         done
15839         sync
15840 }
15841 run_test 231b "must not assert on fully utilized OST request buffer"
15842
15843 test_232a() {
15844         mkdir -p $DIR/$tdir
15845         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15846
15847         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15848         do_facet ost1 $LCTL set_param fail_loc=0x31c
15849
15850         # ignore dd failure
15851         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15852
15853         do_facet ost1 $LCTL set_param fail_loc=0
15854         umount_client $MOUNT || error "umount failed"
15855         mount_client $MOUNT || error "mount failed"
15856         stop ost1 || error "cannot stop ost1"
15857         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15858 }
15859 run_test 232a "failed lock should not block umount"
15860
15861 test_232b() {
15862         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15863                 skip "Need MDS version at least 2.10.58"
15864
15865         mkdir -p $DIR/$tdir
15866         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15867         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15868         sync
15869         cancel_lru_locks osc
15870
15871         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15872         do_facet ost1 $LCTL set_param fail_loc=0x31c
15873
15874         # ignore failure
15875         $LFS data_version $DIR/$tdir/$tfile || true
15876
15877         do_facet ost1 $LCTL set_param fail_loc=0
15878         umount_client $MOUNT || error "umount failed"
15879         mount_client $MOUNT || error "mount failed"
15880         stop ost1 || error "cannot stop ost1"
15881         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15882 }
15883 run_test 232b "failed data version lock should not block umount"
15884
15885 test_233a() {
15886         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15887                 skip "Need MDS version at least 2.3.64"
15888         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15889
15890         local fid=$($LFS path2fid $MOUNT)
15891
15892         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15893                 error "cannot access $MOUNT using its FID '$fid'"
15894 }
15895 run_test 233a "checking that OBF of the FS root succeeds"
15896
15897 test_233b() {
15898         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15899                 skip "Need MDS version at least 2.5.90"
15900         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15901
15902         local fid=$($LFS path2fid $MOUNT/.lustre)
15903
15904         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15905                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15906
15907         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15908         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15909                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15910 }
15911 run_test 233b "checking that OBF of the FS .lustre succeeds"
15912
15913 test_234() {
15914         local p="$TMP/sanityN-$TESTNAME.parameters"
15915         save_lustre_params client "llite.*.xattr_cache" > $p
15916         lctl set_param llite.*.xattr_cache 1 ||
15917                 skip_env "xattr cache is not supported"
15918
15919         mkdir -p $DIR/$tdir || error "mkdir failed"
15920         touch $DIR/$tdir/$tfile || error "touch failed"
15921         # OBD_FAIL_LLITE_XATTR_ENOMEM
15922         $LCTL set_param fail_loc=0x1405
15923         getfattr -n user.attr $DIR/$tdir/$tfile &&
15924                 error "getfattr should have failed with ENOMEM"
15925         $LCTL set_param fail_loc=0x0
15926         rm -rf $DIR/$tdir
15927
15928         restore_lustre_params < $p
15929         rm -f $p
15930 }
15931 run_test 234 "xattr cache should not crash on ENOMEM"
15932
15933 test_235() {
15934         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15935                 skip "Need MDS version at least 2.4.52"
15936
15937         flock_deadlock $DIR/$tfile
15938         local RC=$?
15939         case $RC in
15940                 0)
15941                 ;;
15942                 124) error "process hangs on a deadlock"
15943                 ;;
15944                 *) error "error executing flock_deadlock $DIR/$tfile"
15945                 ;;
15946         esac
15947 }
15948 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15949
15950 #LU-2935
15951 test_236() {
15952         check_swap_layouts_support
15953
15954         local ref1=/etc/passwd
15955         local ref2=/etc/group
15956         local file1=$DIR/$tdir/f1
15957         local file2=$DIR/$tdir/f2
15958
15959         test_mkdir -c1 $DIR/$tdir
15960         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15961         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15962         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15963         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15964         local fd=$(free_fd)
15965         local cmd="exec $fd<>$file2"
15966         eval $cmd
15967         rm $file2
15968         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15969                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15970         cmd="exec $fd>&-"
15971         eval $cmd
15972         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15973
15974         #cleanup
15975         rm -rf $DIR/$tdir
15976 }
15977 run_test 236 "Layout swap on open unlinked file"
15978
15979 # LU-4659 linkea consistency
15980 test_238() {
15981         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15982                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15983                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15984                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15985
15986         touch $DIR/$tfile
15987         ln $DIR/$tfile $DIR/$tfile.lnk
15988         touch $DIR/$tfile.new
15989         mv $DIR/$tfile.new $DIR/$tfile
15990         local fid1=$($LFS path2fid $DIR/$tfile)
15991         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15992         local path1=$($LFS fid2path $FSNAME "$fid1")
15993         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15994         local path2=$($LFS fid2path $FSNAME "$fid2")
15995         [ $tfile.lnk == $path2 ] ||
15996                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15997         rm -f $DIR/$tfile*
15998 }
15999 run_test 238 "Verify linkea consistency"
16000
16001 test_239A() { # was test_239
16002         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16003                 skip "Need MDS version at least 2.5.60"
16004
16005         local list=$(comma_list $(mdts_nodes))
16006
16007         mkdir -p $DIR/$tdir
16008         createmany -o $DIR/$tdir/f- 5000
16009         unlinkmany $DIR/$tdir/f- 5000
16010         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16011                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16012         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16013                         osp.*MDT*.sync_in_flight" | calc_sum)
16014         [ "$changes" -eq 0 ] || error "$changes not synced"
16015 }
16016 run_test 239A "osp_sync test"
16017
16018 test_239a() { #LU-5297
16019         remote_mds_nodsh && skip "remote MDS with nodsh"
16020
16021         touch $DIR/$tfile
16022         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16023         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16024         chgrp $RUNAS_GID $DIR/$tfile
16025         wait_delete_completed
16026 }
16027 run_test 239a "process invalid osp sync record correctly"
16028
16029 test_239b() { #LU-5297
16030         remote_mds_nodsh && skip "remote MDS with nodsh"
16031
16032         touch $DIR/$tfile1
16033         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16034         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16035         chgrp $RUNAS_GID $DIR/$tfile1
16036         wait_delete_completed
16037         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16038         touch $DIR/$tfile2
16039         chgrp $RUNAS_GID $DIR/$tfile2
16040         wait_delete_completed
16041 }
16042 run_test 239b "process osp sync record with ENOMEM error correctly"
16043
16044 test_240() {
16045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16046         remote_mds_nodsh && skip "remote MDS with nodsh"
16047
16048         mkdir -p $DIR/$tdir
16049
16050         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16051                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16052         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16053                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16054
16055         umount_client $MOUNT || error "umount failed"
16056         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16057         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16058         mount_client $MOUNT || error "failed to mount client"
16059
16060         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16061         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16062 }
16063 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16064
16065 test_241_bio() {
16066         local count=$1
16067         local bsize=$2
16068
16069         for LOOP in $(seq $count); do
16070                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16071                 cancel_lru_locks $OSC || true
16072         done
16073 }
16074
16075 test_241_dio() {
16076         local count=$1
16077         local bsize=$2
16078
16079         for LOOP in $(seq $1); do
16080                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16081                         2>/dev/null
16082         done
16083 }
16084
16085 test_241a() { # was test_241
16086         local bsize=$PAGE_SIZE
16087
16088         (( bsize < 40960 )) && bsize=40960
16089         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16090         ls -la $DIR/$tfile
16091         cancel_lru_locks $OSC
16092         test_241_bio 1000 $bsize &
16093         PID=$!
16094         test_241_dio 1000 $bsize
16095         wait $PID
16096 }
16097 run_test 241a "bio vs dio"
16098
16099 test_241b() {
16100         local bsize=$PAGE_SIZE
16101
16102         (( bsize < 40960 )) && bsize=40960
16103         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16104         ls -la $DIR/$tfile
16105         test_241_dio 1000 $bsize &
16106         PID=$!
16107         test_241_dio 1000 $bsize
16108         wait $PID
16109 }
16110 run_test 241b "dio vs dio"
16111
16112 test_242() {
16113         remote_mds_nodsh && skip "remote MDS with nodsh"
16114
16115         mkdir -p $DIR/$tdir
16116         touch $DIR/$tdir/$tfile
16117
16118         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16119         do_facet mds1 lctl set_param fail_loc=0x105
16120         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16121
16122         do_facet mds1 lctl set_param fail_loc=0
16123         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16124 }
16125 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16126
16127 test_243()
16128 {
16129         test_mkdir $DIR/$tdir
16130         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16131 }
16132 run_test 243 "various group lock tests"
16133
16134 test_244()
16135 {
16136         test_mkdir $DIR/$tdir
16137         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16138         sendfile_grouplock $DIR/$tdir/$tfile || \
16139                 error "sendfile+grouplock failed"
16140         rm -rf $DIR/$tdir
16141 }
16142 run_test 244 "sendfile with group lock tests"
16143
16144 test_245() {
16145         local flagname="multi_mod_rpcs"
16146         local connect_data_name="max_mod_rpcs"
16147         local out
16148
16149         # check if multiple modify RPCs flag is set
16150         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16151                 grep "connect_flags:")
16152         echo "$out"
16153
16154         echo "$out" | grep -qw $flagname
16155         if [ $? -ne 0 ]; then
16156                 echo "connect flag $flagname is not set"
16157                 return
16158         fi
16159
16160         # check if multiple modify RPCs data is set
16161         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16162         echo "$out"
16163
16164         echo "$out" | grep -qw $connect_data_name ||
16165                 error "import should have connect data $connect_data_name"
16166 }
16167 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16168
16169 test_246() { # LU-7371
16170         remote_ost_nodsh && skip "remote OST with nodsh"
16171         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16172                 skip "Need OST version >= 2.7.62"
16173
16174         do_facet ost1 $LCTL set_param fail_val=4095
16175 #define OBD_FAIL_OST_READ_SIZE          0x234
16176         do_facet ost1 $LCTL set_param fail_loc=0x234
16177         $LFS setstripe $DIR/$tfile -i 0 -c 1
16178         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16179         cancel_lru_locks $FSNAME-OST0000
16180         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16181 }
16182 run_test 246 "Read file of size 4095 should return right length"
16183
16184 cleanup_247() {
16185         local submount=$1
16186
16187         trap 0
16188         umount_client $submount
16189         rmdir $submount
16190 }
16191
16192 test_247a() {
16193         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16194                 grep -q subtree ||
16195                 skip_env "Fileset feature is not supported"
16196
16197         local submount=${MOUNT}_$tdir
16198
16199         mkdir $MOUNT/$tdir
16200         mkdir -p $submount || error "mkdir $submount failed"
16201         FILESET="$FILESET/$tdir" mount_client $submount ||
16202                 error "mount $submount failed"
16203         trap "cleanup_247 $submount" EXIT
16204         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16205         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16206                 error "read $MOUNT/$tdir/$tfile failed"
16207         cleanup_247 $submount
16208 }
16209 run_test 247a "mount subdir as fileset"
16210
16211 test_247b() {
16212         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16213                 skip_env "Fileset feature is not supported"
16214
16215         local submount=${MOUNT}_$tdir
16216
16217         rm -rf $MOUNT/$tdir
16218         mkdir -p $submount || error "mkdir $submount failed"
16219         SKIP_FILESET=1
16220         FILESET="$FILESET/$tdir" mount_client $submount &&
16221                 error "mount $submount should fail"
16222         rmdir $submount
16223 }
16224 run_test 247b "mount subdir that dose not exist"
16225
16226 test_247c() {
16227         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16228                 skip_env "Fileset feature is not supported"
16229
16230         local submount=${MOUNT}_$tdir
16231
16232         mkdir -p $MOUNT/$tdir/dir1
16233         mkdir -p $submount || error "mkdir $submount failed"
16234         trap "cleanup_247 $submount" EXIT
16235         FILESET="$FILESET/$tdir" mount_client $submount ||
16236                 error "mount $submount failed"
16237         local fid=$($LFS path2fid $MOUNT/)
16238         $LFS fid2path $submount $fid && error "fid2path should fail"
16239         cleanup_247 $submount
16240 }
16241 run_test 247c "running fid2path outside root"
16242
16243 test_247d() {
16244         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16245                 skip "Fileset feature is not supported"
16246
16247         local submount=${MOUNT}_$tdir
16248
16249         mkdir -p $MOUNT/$tdir/dir1
16250         mkdir -p $submount || error "mkdir $submount failed"
16251         FILESET="$FILESET/$tdir" mount_client $submount ||
16252                 error "mount $submount failed"
16253         trap "cleanup_247 $submount" EXIT
16254         local fid=$($LFS path2fid $submount/dir1)
16255         $LFS fid2path $submount $fid || error "fid2path should succeed"
16256         cleanup_247 $submount
16257 }
16258 run_test 247d "running fid2path inside root"
16259
16260 # LU-8037
16261 test_247e() {
16262         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16263                 grep -q subtree ||
16264                 skip "Fileset feature is not supported"
16265
16266         local submount=${MOUNT}_$tdir
16267
16268         mkdir $MOUNT/$tdir
16269         mkdir -p $submount || error "mkdir $submount failed"
16270         FILESET="$FILESET/.." mount_client $submount &&
16271                 error "mount $submount should fail"
16272         rmdir $submount
16273 }
16274 run_test 247e "mount .. as fileset"
16275
16276 test_248() {
16277         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16278         [ -z "$fast_read_sav" ] && skip "no fast read support"
16279
16280         # create a large file for fast read verification
16281         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16282
16283         # make sure the file is created correctly
16284         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16285                 { rm -f $DIR/$tfile; skip "file creation error"; }
16286
16287         echo "Test 1: verify that fast read is 4 times faster on cache read"
16288
16289         # small read with fast read enabled
16290         $LCTL set_param -n llite.*.fast_read=1
16291         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16292                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16293                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16294         # small read with fast read disabled
16295         $LCTL set_param -n llite.*.fast_read=0
16296         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16297                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16298                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16299
16300         # verify that fast read is 4 times faster for cache read
16301         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16302                 error_not_in_vm "fast read was not 4 times faster: " \
16303                            "$t_fast vs $t_slow"
16304
16305         echo "Test 2: verify the performance between big and small read"
16306         $LCTL set_param -n llite.*.fast_read=1
16307
16308         # 1k non-cache read
16309         cancel_lru_locks osc
16310         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16311                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16312                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16313
16314         # 1M non-cache read
16315         cancel_lru_locks osc
16316         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16317                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16318                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16319
16320         # verify that big IO is not 4 times faster than small IO
16321         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16322                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16323
16324         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16325         rm -f $DIR/$tfile
16326 }
16327 run_test 248 "fast read verification"
16328
16329 test_249() { # LU-7890
16330         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16331                 skip "Need at least version 2.8.54"
16332
16333         rm -f $DIR/$tfile
16334         $LFS setstripe -c 1 $DIR/$tfile
16335         # Offset 2T == 4k * 512M
16336         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16337                 error "dd to 2T offset failed"
16338 }
16339 run_test 249 "Write above 2T file size"
16340
16341 test_250() {
16342         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16343          && skip "no 16TB file size limit on ZFS"
16344
16345         $LFS setstripe -c 1 $DIR/$tfile
16346         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16347         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16348         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16349         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16350                 conv=notrunc,fsync && error "append succeeded"
16351         return 0
16352 }
16353 run_test 250 "Write above 16T limit"
16354
16355 test_251() {
16356         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16357
16358         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16359         #Skip once - writing the first stripe will succeed
16360         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16361         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16362                 error "short write happened"
16363
16364         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16365         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16366                 error "short read happened"
16367
16368         rm -f $DIR/$tfile
16369 }
16370 run_test 251 "Handling short read and write correctly"
16371
16372 test_252() {
16373         remote_mds_nodsh && skip "remote MDS with nodsh"
16374         remote_ost_nodsh && skip "remote OST with nodsh"
16375         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16376                 skip_env "ldiskfs only test"
16377         fi
16378
16379         local tgt
16380         local dev
16381         local out
16382         local uuid
16383         local num
16384         local gen
16385
16386         # check lr_reader on OST0000
16387         tgt=ost1
16388         dev=$(facet_device $tgt)
16389         out=$(do_facet $tgt $LR_READER $dev)
16390         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16391         echo "$out"
16392         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16393         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16394                 error "Invalid uuid returned by $LR_READER on target $tgt"
16395         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16396
16397         # check lr_reader -c on MDT0000
16398         tgt=mds1
16399         dev=$(facet_device $tgt)
16400         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16401                 skip "$LR_READER does not support additional options"
16402         fi
16403         out=$(do_facet $tgt $LR_READER -c $dev)
16404         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16405         echo "$out"
16406         num=$(echo "$out" | grep -c "mdtlov")
16407         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16408                 error "Invalid number of mdtlov clients returned by $LR_READER"
16409         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16410
16411         # check lr_reader -cr on MDT0000
16412         out=$(do_facet $tgt $LR_READER -cr $dev)
16413         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16414         echo "$out"
16415         echo "$out" | grep -q "^reply_data:$" ||
16416                 error "$LR_READER should have returned 'reply_data' section"
16417         num=$(echo "$out" | grep -c "client_generation")
16418         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16419 }
16420 run_test 252 "check lr_reader tool"
16421
16422 test_253_fill_ost() {
16423         local size_mb #how many MB should we write to pass watermark
16424         local lwm=$3  #low watermark
16425         local free_10mb #10% of free space
16426
16427         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16428         size_mb=$((free_kb / 1024 - lwm))
16429         free_10mb=$((free_kb / 10240))
16430         #If 10% of free space cross low watermark use it
16431         if (( free_10mb > size_mb )); then
16432                 size_mb=$free_10mb
16433         else
16434                 #At least we need to store 1.1 of difference between
16435                 #free space and low watermark
16436                 size_mb=$((size_mb + size_mb / 10))
16437         fi
16438         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16439                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16440                          oflag=append conv=notrunc
16441         fi
16442
16443         sleep_maxage
16444
16445         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16446         echo "OST still has $((free_kb / 1024)) mbytes free"
16447 }
16448
16449 test_253() {
16450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16451         remote_mds_nodsh && skip "remote MDS with nodsh"
16452         remote_mgs_nodsh && skip "remote MGS with nodsh"
16453
16454         local ostidx=0
16455         local rc=0
16456
16457         local ost_name=$($LFS osts |
16458                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16459         # on the mdt's osc
16460         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16461         do_facet $SINGLEMDS $LCTL get_param -n \
16462                 osp.$mdtosc_proc1.reserved_mb_high ||
16463                 skip  "remote MDS does not support reserved_mb_high"
16464
16465         rm -rf $DIR/$tdir
16466         wait_mds_ost_sync
16467         wait_delete_completed
16468         mkdir $DIR/$tdir
16469
16470         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16471                         osp.$mdtosc_proc1.reserved_mb_high)
16472         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16473                         osp.$mdtosc_proc1.reserved_mb_low)
16474         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16475
16476         if ! combined_mgs_mds ; then
16477                 mount_mgs_client
16478         fi
16479         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16480         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16481                 error "Adding $ost_name to pool failed"
16482
16483         # Wait for client to see a OST at pool
16484         wait_update $HOSTNAME "$LCTL get_param -n
16485                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16486                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16487                 error "Client can not see the pool"
16488         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16489                 error "Setstripe failed"
16490
16491         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16492         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16493         echo "OST still has $((blocks/1024)) mbytes free"
16494
16495         local new_lwm=$((blocks/1024-10))
16496         do_facet $SINGLEMDS $LCTL set_param \
16497                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16498         do_facet $SINGLEMDS $LCTL set_param \
16499                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16500
16501         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16502
16503         #First enospc could execute orphan deletion so repeat.
16504         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16505
16506         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16507                         osp.$mdtosc_proc1.prealloc_status)
16508         echo "prealloc_status $oa_status"
16509
16510         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16511                 error "File creation should fail"
16512         #object allocation was stopped, but we still able to append files
16513         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16514                 error "Append failed"
16515         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16516
16517         wait_delete_completed
16518
16519         sleep_maxage
16520
16521         for i in $(seq 10 12); do
16522                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16523                         error "File creation failed after rm";
16524         done
16525
16526         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16527                         osp.$mdtosc_proc1.prealloc_status)
16528         echo "prealloc_status $oa_status"
16529
16530         if (( oa_status != 0 )); then
16531                 error "Object allocation still disable after rm"
16532         fi
16533         do_facet $SINGLEMDS $LCTL set_param \
16534                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16535         do_facet $SINGLEMDS $LCTL set_param \
16536                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16537
16538
16539         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16540                 error "Remove $ost_name from pool failed"
16541         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16542                 error "Pool destroy fialed"
16543
16544         if ! combined_mgs_mds ; then
16545                 umount_mgs_client
16546         fi
16547 }
16548 run_test 253 "Check object allocation limit"
16549
16550 test_254() {
16551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16552         remote_mds_nodsh && skip "remote MDS with nodsh"
16553         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16554                 skip "MDS does not support changelog_size"
16555
16556         local cl_user
16557         local MDT0=$(facet_svc $SINGLEMDS)
16558
16559         changelog_register || error "changelog_register failed"
16560
16561         changelog_clear 0 || error "changelog_clear failed"
16562
16563         local size1=$(do_facet $SINGLEMDS \
16564                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16565         echo "Changelog size $size1"
16566
16567         rm -rf $DIR/$tdir
16568         $LFS mkdir -i 0 $DIR/$tdir
16569         # change something
16570         mkdir -p $DIR/$tdir/pics/2008/zachy
16571         touch $DIR/$tdir/pics/2008/zachy/timestamp
16572         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16573         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16574         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16575         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16576         rm $DIR/$tdir/pics/desktop.jpg
16577
16578         local size2=$(do_facet $SINGLEMDS \
16579                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16580         echo "Changelog size after work $size2"
16581
16582         (( $size2 > $size1 )) ||
16583                 error "new Changelog size=$size2 less than old size=$size1"
16584 }
16585 run_test 254 "Check changelog size"
16586
16587 ladvise_no_type()
16588 {
16589         local type=$1
16590         local file=$2
16591
16592         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16593                 awk -F: '{print $2}' | grep $type > /dev/null
16594         if [ $? -ne 0 ]; then
16595                 return 0
16596         fi
16597         return 1
16598 }
16599
16600 ladvise_no_ioctl()
16601 {
16602         local file=$1
16603
16604         lfs ladvise -a willread $file > /dev/null 2>&1
16605         if [ $? -eq 0 ]; then
16606                 return 1
16607         fi
16608
16609         lfs ladvise -a willread $file 2>&1 |
16610                 grep "Inappropriate ioctl for device" > /dev/null
16611         if [ $? -eq 0 ]; then
16612                 return 0
16613         fi
16614         return 1
16615 }
16616
16617 percent() {
16618         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16619 }
16620
16621 # run a random read IO workload
16622 # usage: random_read_iops <filename> <filesize> <iosize>
16623 random_read_iops() {
16624         local file=$1
16625         local fsize=$2
16626         local iosize=${3:-4096}
16627
16628         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16629                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16630 }
16631
16632 drop_file_oss_cache() {
16633         local file="$1"
16634         local nodes="$2"
16635
16636         $LFS ladvise -a dontneed $file 2>/dev/null ||
16637                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16638 }
16639
16640 ladvise_willread_performance()
16641 {
16642         local repeat=10
16643         local average_origin=0
16644         local average_cache=0
16645         local average_ladvise=0
16646
16647         for ((i = 1; i <= $repeat; i++)); do
16648                 echo "Iter $i/$repeat: reading without willread hint"
16649                 cancel_lru_locks osc
16650                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16651                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16652                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16653                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16654
16655                 cancel_lru_locks osc
16656                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16657                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16658                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16659
16660                 cancel_lru_locks osc
16661                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16662                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16663                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16664                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16665                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16666         done
16667         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16668         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16669         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16670
16671         speedup_cache=$(percent $average_cache $average_origin)
16672         speedup_ladvise=$(percent $average_ladvise $average_origin)
16673
16674         echo "Average uncached read: $average_origin"
16675         echo "Average speedup with OSS cached read: " \
16676                 "$average_cache = +$speedup_cache%"
16677         echo "Average speedup with ladvise willread: " \
16678                 "$average_ladvise = +$speedup_ladvise%"
16679
16680         local lowest_speedup=20
16681         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16682                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16683                         "got $average_cache%. Skipping ladvise willread check."
16684                 return 0
16685         fi
16686
16687         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16688         # it is still good to run until then to exercise 'ladvise willread'
16689         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16690                 [ "$ost1_FSTYPE" = "zfs" ] &&
16691                 echo "osd-zfs does not support dontneed or drop_caches" &&
16692                 return 0
16693
16694         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16695         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16696                 error_not_in_vm "Speedup with willread is less than " \
16697                         "$lowest_speedup%, got $average_ladvise%"
16698 }
16699
16700 test_255a() {
16701         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16702                 skip "lustre < 2.8.54 does not support ladvise "
16703         remote_ost_nodsh && skip "remote OST with nodsh"
16704
16705         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16706
16707         ladvise_no_type willread $DIR/$tfile &&
16708                 skip "willread ladvise is not supported"
16709
16710         ladvise_no_ioctl $DIR/$tfile &&
16711                 skip "ladvise ioctl is not supported"
16712
16713         local size_mb=100
16714         local size=$((size_mb * 1048576))
16715         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16716                 error "dd to $DIR/$tfile failed"
16717
16718         lfs ladvise -a willread $DIR/$tfile ||
16719                 error "Ladvise failed with no range argument"
16720
16721         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16722                 error "Ladvise failed with no -l or -e argument"
16723
16724         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16725                 error "Ladvise failed with only -e argument"
16726
16727         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16728                 error "Ladvise failed with only -l argument"
16729
16730         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16731                 error "End offset should not be smaller than start offset"
16732
16733         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16734                 error "End offset should not be equal to start offset"
16735
16736         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16737                 error "Ladvise failed with overflowing -s argument"
16738
16739         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16740                 error "Ladvise failed with overflowing -e argument"
16741
16742         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16743                 error "Ladvise failed with overflowing -l argument"
16744
16745         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16746                 error "Ladvise succeeded with conflicting -l and -e arguments"
16747
16748         echo "Synchronous ladvise should wait"
16749         local delay=4
16750 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16751         do_nodes $(comma_list $(osts_nodes)) \
16752                 $LCTL set_param fail_val=$delay fail_loc=0x237
16753
16754         local start_ts=$SECONDS
16755         lfs ladvise -a willread $DIR/$tfile ||
16756                 error "Ladvise failed with no range argument"
16757         local end_ts=$SECONDS
16758         local inteval_ts=$((end_ts - start_ts))
16759
16760         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16761                 error "Synchronous advice didn't wait reply"
16762         fi
16763
16764         echo "Asynchronous ladvise shouldn't wait"
16765         local start_ts=$SECONDS
16766         lfs ladvise -a willread -b $DIR/$tfile ||
16767                 error "Ladvise failed with no range argument"
16768         local end_ts=$SECONDS
16769         local inteval_ts=$((end_ts - start_ts))
16770
16771         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16772                 error "Asynchronous advice blocked"
16773         fi
16774
16775         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16776         ladvise_willread_performance
16777 }
16778 run_test 255a "check 'lfs ladvise -a willread'"
16779
16780 facet_meminfo() {
16781         local facet=$1
16782         local info=$2
16783
16784         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16785 }
16786
16787 test_255b() {
16788         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16789                 skip "lustre < 2.8.54 does not support ladvise "
16790         remote_ost_nodsh && skip "remote OST with nodsh"
16791
16792         lfs setstripe -c 1 -i 0 $DIR/$tfile
16793
16794         ladvise_no_type dontneed $DIR/$tfile &&
16795                 skip "dontneed ladvise is not supported"
16796
16797         ladvise_no_ioctl $DIR/$tfile &&
16798                 skip "ladvise ioctl is not supported"
16799
16800         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16801                 [ "$ost1_FSTYPE" = "zfs" ] &&
16802                 skip "zfs-osd does not support 'ladvise dontneed'"
16803
16804         local size_mb=100
16805         local size=$((size_mb * 1048576))
16806         # In order to prevent disturbance of other processes, only check 3/4
16807         # of the memory usage
16808         local kibibytes=$((size_mb * 1024 * 3 / 4))
16809
16810         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16811                 error "dd to $DIR/$tfile failed"
16812
16813         #force write to complete before dropping OST cache & checking memory
16814         sync
16815
16816         local total=$(facet_meminfo ost1 MemTotal)
16817         echo "Total memory: $total KiB"
16818
16819         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16820         local before_read=$(facet_meminfo ost1 Cached)
16821         echo "Cache used before read: $before_read KiB"
16822
16823         lfs ladvise -a willread $DIR/$tfile ||
16824                 error "Ladvise willread failed"
16825         local after_read=$(facet_meminfo ost1 Cached)
16826         echo "Cache used after read: $after_read KiB"
16827
16828         lfs ladvise -a dontneed $DIR/$tfile ||
16829                 error "Ladvise dontneed again failed"
16830         local no_read=$(facet_meminfo ost1 Cached)
16831         echo "Cache used after dontneed ladvise: $no_read KiB"
16832
16833         if [ $total -lt $((before_read + kibibytes)) ]; then
16834                 echo "Memory is too small, abort checking"
16835                 return 0
16836         fi
16837
16838         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16839                 error "Ladvise willread should use more memory" \
16840                         "than $kibibytes KiB"
16841         fi
16842
16843         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16844                 error "Ladvise dontneed should release more memory" \
16845                         "than $kibibytes KiB"
16846         fi
16847 }
16848 run_test 255b "check 'lfs ladvise -a dontneed'"
16849
16850 test_255c() {
16851         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16852                 skip "lustre < 2.10.53 does not support lockahead"
16853
16854         local count
16855         local new_count
16856         local difference
16857         local i
16858         local rc
16859
16860         test_mkdir -p $DIR/$tdir
16861         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16862
16863         #test 10 returns only success/failure
16864         i=10
16865         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16866         rc=$?
16867         if [ $rc -eq 255 ]; then
16868                 error "Ladvise test${i} failed, ${rc}"
16869         fi
16870
16871         #test 11 counts lock enqueue requests, all others count new locks
16872         i=11
16873         count=$(do_facet ost1 \
16874                 $LCTL get_param -n ost.OSS.ost.stats)
16875         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16876
16877         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16878         rc=$?
16879         if [ $rc -eq 255 ]; then
16880                 error "Ladvise test${i} failed, ${rc}"
16881         fi
16882
16883         new_count=$(do_facet ost1 \
16884                 $LCTL get_param -n ost.OSS.ost.stats)
16885         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16886                    awk '{ print $2 }')
16887
16888         difference="$((new_count - count))"
16889         if [ $difference -ne $rc ]; then
16890                 error "Ladvise test${i}, bad enqueue count, returned " \
16891                       "${rc}, actual ${difference}"
16892         fi
16893
16894         for i in $(seq 12 21); do
16895                 # If we do not do this, we run the risk of having too many
16896                 # locks and starting lock cancellation while we are checking
16897                 # lock counts.
16898                 cancel_lru_locks osc
16899
16900                 count=$($LCTL get_param -n \
16901                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16902
16903                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16904                 rc=$?
16905                 if [ $rc -eq 255 ]; then
16906                         error "Ladvise test ${i} failed, ${rc}"
16907                 fi
16908
16909                 new_count=$($LCTL get_param -n \
16910                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16911                 difference="$((new_count - count))"
16912
16913                 # Test 15 output is divided by 100 to map down to valid return
16914                 if [ $i -eq 15 ]; then
16915                         rc="$((rc * 100))"
16916                 fi
16917
16918                 if [ $difference -ne $rc ]; then
16919                         error "Ladvise test ${i}, bad lock count, returned " \
16920                               "${rc}, actual ${difference}"
16921                 fi
16922         done
16923
16924         #test 22 returns only success/failure
16925         i=22
16926         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16927         rc=$?
16928         if [ $rc -eq 255 ]; then
16929                 error "Ladvise test${i} failed, ${rc}"
16930         fi
16931 }
16932 run_test 255c "suite of ladvise lockahead tests"
16933
16934 test_256() {
16935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16936         remote_mds_nodsh && skip "remote MDS with nodsh"
16937         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16938         changelog_users $SINGLEMDS | grep "^cl" &&
16939                 skip "active changelog user"
16940
16941         local cl_user
16942         local cat_sl
16943         local mdt_dev
16944
16945         mdt_dev=$(mdsdevname 1)
16946         echo $mdt_dev
16947
16948         changelog_register || error "changelog_register failed"
16949
16950         rm -rf $DIR/$tdir
16951         mkdir -p $DIR/$tdir
16952
16953         changelog_clear 0 || error "changelog_clear failed"
16954
16955         # change something
16956         touch $DIR/$tdir/{1..10}
16957
16958         # stop the MDT
16959         stop $SINGLEMDS || error "Fail to stop MDT"
16960
16961         # remount the MDT
16962
16963         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16964
16965         #after mount new plainllog is used
16966         touch $DIR/$tdir/{11..19}
16967         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16968         cat_sl=$(do_facet $SINGLEMDS "sync; \
16969                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16970                  llog_reader $tmpfile | grep -c type=1064553b")
16971         do_facet $SINGLEMDS llog_reader $tmpfile
16972
16973         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16974
16975         changelog_clear 0 || error "changelog_clear failed"
16976
16977         cat_sl=$(do_facet $SINGLEMDS "sync; \
16978                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16979                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16980
16981         if (( cat_sl == 2 )); then
16982                 error "Empty plain llog was not deleted from changelog catalog"
16983         elif (( cat_sl != 1 )); then
16984                 error "Active plain llog shouldn't be deleted from catalog"
16985         fi
16986 }
16987 run_test 256 "Check llog delete for empty and not full state"
16988
16989 test_257() {
16990         remote_mds_nodsh && skip "remote MDS with nodsh"
16991         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16992                 skip "Need MDS version at least 2.8.55"
16993
16994         test_mkdir $DIR/$tdir
16995
16996         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16997                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16998         stat $DIR/$tdir
16999
17000 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17001         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17002         local facet=mds$((mdtidx + 1))
17003         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17004         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17005
17006         stop $facet || error "stop MDS failed"
17007         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17008                 error "start MDS fail"
17009         wait_recovery_complete $facet
17010 }
17011 run_test 257 "xattr locks are not lost"
17012
17013 # Verify we take the i_mutex when security requires it
17014 test_258a() {
17015 #define OBD_FAIL_IMUTEX_SEC 0x141c
17016         $LCTL set_param fail_loc=0x141c
17017         touch $DIR/$tfile
17018         chmod u+s $DIR/$tfile
17019         chmod a+rwx $DIR/$tfile
17020         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17021         RC=$?
17022         if [ $RC -ne 0 ]; then
17023                 error "error, failed to take i_mutex, rc=$?"
17024         fi
17025         rm -f $DIR/$tfile
17026 }
17027 run_test 258a
17028
17029 # Verify we do NOT take the i_mutex in the normal case
17030 test_258b() {
17031 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17032         $LCTL set_param fail_loc=0x141d
17033         touch $DIR/$tfile
17034         chmod a+rwx $DIR
17035         chmod a+rw $DIR/$tfile
17036         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17037         RC=$?
17038         if [ $RC -ne 0 ]; then
17039                 error "error, took i_mutex unnecessarily, rc=$?"
17040         fi
17041         rm -f $DIR/$tfile
17042
17043 }
17044 run_test 258b "verify i_mutex security behavior"
17045
17046 test_259() {
17047         local file=$DIR/$tfile
17048         local before
17049         local after
17050
17051         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17052
17053         stack_trap "rm -f $file" EXIT
17054
17055         wait_delete_completed
17056         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17057         echo "before: $before"
17058
17059         $LFS setstripe -i 0 -c 1 $file
17060         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17061         sync_all_data
17062         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17063         echo "after write: $after"
17064
17065 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17066         do_facet ost1 $LCTL set_param fail_loc=0x2301
17067         $TRUNCATE $file 0
17068         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17069         echo "after truncate: $after"
17070
17071         stop ost1
17072         do_facet ost1 $LCTL set_param fail_loc=0
17073         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17074         sleep 2
17075         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17076         echo "after restart: $after"
17077         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17078                 error "missing truncate?"
17079
17080         return 0
17081 }
17082 run_test 259 "crash at delayed truncate"
17083
17084 test_260() {
17085 #define OBD_FAIL_MDC_CLOSE               0x806
17086         $LCTL set_param fail_loc=0x80000806
17087         touch $DIR/$tfile
17088
17089 }
17090 run_test 260 "Check mdc_close fail"
17091
17092 ### Data-on-MDT sanity tests ###
17093 test_270a() {
17094         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17095                 skip "Need MDS version at least 2.10.55 for DoM"
17096
17097         # create DoM file
17098         local dom=$DIR/$tdir/dom_file
17099         local tmp=$DIR/$tdir/tmp_file
17100
17101         mkdir -p $DIR/$tdir
17102
17103         # basic checks for DoM component creation
17104         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17105                 error "Can set MDT layout to non-first entry"
17106
17107         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17108                 error "Can define multiple entries as MDT layout"
17109
17110         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17111
17112         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17113         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17114         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17115
17116         local mdtidx=$($LFS getstripe -m $dom)
17117         local mdtname=MDT$(printf %04x $mdtidx)
17118         local facet=mds$((mdtidx + 1))
17119         local space_check=1
17120
17121         # Skip free space checks with ZFS
17122         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17123
17124         # write
17125         sync
17126         local size_tmp=$((65536 * 3))
17127         local mdtfree1=$(do_facet $facet \
17128                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17129
17130         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17131         # check also direct IO along write
17132         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17133         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17134         sync
17135         cmp $tmp $dom || error "file data is different"
17136         [ $(stat -c%s $dom) == $size_tmp ] ||
17137                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17138         if [ $space_check == 1 ]; then
17139                 local mdtfree2=$(do_facet $facet \
17140                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17141
17142                 # increase in usage from by $size_tmp
17143                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17144                         error "MDT free space wrong after write: " \
17145                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17146         fi
17147
17148         # truncate
17149         local size_dom=10000
17150
17151         $TRUNCATE $dom $size_dom
17152         [ $(stat -c%s $dom) == $size_dom ] ||
17153                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17154         if [ $space_check == 1 ]; then
17155                 mdtfree1=$(do_facet $facet \
17156                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17157                 # decrease in usage from $size_tmp to new $size_dom
17158                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17159                   $(((size_tmp - size_dom) / 1024)) ] ||
17160                         error "MDT free space is wrong after truncate: " \
17161                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17162         fi
17163
17164         # append
17165         cat $tmp >> $dom
17166         sync
17167         size_dom=$((size_dom + size_tmp))
17168         [ $(stat -c%s $dom) == $size_dom ] ||
17169                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17170         if [ $space_check == 1 ]; then
17171                 mdtfree2=$(do_facet $facet \
17172                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17173                 # increase in usage by $size_tmp from previous
17174                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17175                         error "MDT free space is wrong after append: " \
17176                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17177         fi
17178
17179         # delete
17180         rm $dom
17181         if [ $space_check == 1 ]; then
17182                 mdtfree1=$(do_facet $facet \
17183                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17184                 # decrease in usage by $size_dom from previous
17185                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17186                         error "MDT free space is wrong after removal: " \
17187                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17188         fi
17189
17190         # combined striping
17191         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17192                 error "Can't create DoM + OST striping"
17193
17194         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17195         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17196         # check also direct IO along write
17197         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17198         sync
17199         cmp $tmp $dom || error "file data is different"
17200         [ $(stat -c%s $dom) == $size_tmp ] ||
17201                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17202         rm $dom $tmp
17203
17204         return 0
17205 }
17206 run_test 270a "DoM: basic functionality tests"
17207
17208 test_270b() {
17209         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17210                 skip "Need MDS version at least 2.10.55"
17211
17212         local dom=$DIR/$tdir/dom_file
17213         local max_size=1048576
17214
17215         mkdir -p $DIR/$tdir
17216         $LFS setstripe -E $max_size -L mdt $dom
17217
17218         # truncate over the limit
17219         $TRUNCATE $dom $(($max_size + 1)) &&
17220                 error "successful truncate over the maximum size"
17221         # write over the limit
17222         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17223                 error "successful write over the maximum size"
17224         # append over the limit
17225         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17226         echo "12345" >> $dom && error "successful append over the maximum size"
17227         rm $dom
17228
17229         return 0
17230 }
17231 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17232
17233 test_270c() {
17234         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17235                 skip "Need MDS version at least 2.10.55"
17236
17237         mkdir -p $DIR/$tdir
17238         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17239
17240         # check files inherit DoM EA
17241         touch $DIR/$tdir/first
17242         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17243                 error "bad pattern"
17244         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17245                 error "bad stripe count"
17246         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17247                 error "bad stripe size"
17248
17249         # check directory inherits DoM EA and uses it as default
17250         mkdir $DIR/$tdir/subdir
17251         touch $DIR/$tdir/subdir/second
17252         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17253                 error "bad pattern in sub-directory"
17254         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17255                 error "bad stripe count in sub-directory"
17256         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17257                 error "bad stripe size in sub-directory"
17258         return 0
17259 }
17260 run_test 270c "DoM: DoM EA inheritance tests"
17261
17262 test_270d() {
17263         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17264                 skip "Need MDS version at least 2.10.55"
17265
17266         mkdir -p $DIR/$tdir
17267         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17268
17269         # inherit default DoM striping
17270         mkdir $DIR/$tdir/subdir
17271         touch $DIR/$tdir/subdir/f1
17272
17273         # change default directory striping
17274         $LFS setstripe -c 1 $DIR/$tdir/subdir
17275         touch $DIR/$tdir/subdir/f2
17276         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17277                 error "wrong default striping in file 2"
17278         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17279                 error "bad pattern in file 2"
17280         return 0
17281 }
17282 run_test 270d "DoM: change striping from DoM to RAID0"
17283
17284 test_270e() {
17285         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17286                 skip "Need MDS version at least 2.10.55"
17287
17288         mkdir -p $DIR/$tdir/dom
17289         mkdir -p $DIR/$tdir/norm
17290         DOMFILES=20
17291         NORMFILES=10
17292         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17293         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17294
17295         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17296         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17297
17298         # find DoM files by layout
17299         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17300         [ $NUM -eq  $DOMFILES ] ||
17301                 error "lfs find -L: found $NUM, expected $DOMFILES"
17302         echo "Test 1: lfs find 20 DOM files by layout: OK"
17303
17304         # there should be 1 dir with default DOM striping
17305         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17306         [ $NUM -eq  1 ] ||
17307                 error "lfs find -L: found $NUM, expected 1 dir"
17308         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17309
17310         # find DoM files by stripe size
17311         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17312         [ $NUM -eq  $DOMFILES ] ||
17313                 error "lfs find -S: found $NUM, expected $DOMFILES"
17314         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17315
17316         # find files by stripe offset except DoM files
17317         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17318         [ $NUM -eq  $NORMFILES ] ||
17319                 error "lfs find -i: found $NUM, expected $NORMFILES"
17320         echo "Test 5: lfs find no DOM files by stripe index: OK"
17321         return 0
17322 }
17323 run_test 270e "DoM: lfs find with DoM files test"
17324
17325 test_270f() {
17326         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17327                 skip "Need MDS version at least 2.10.55"
17328
17329         local mdtname=${FSNAME}-MDT0000-mdtlov
17330         local dom=$DIR/$tdir/dom_file
17331         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17332                                                 lod.$mdtname.dom_stripesize)
17333         local dom_limit=131072
17334
17335         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17336         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17337                                                 lod.$mdtname.dom_stripesize)
17338         [ ${dom_limit} -eq ${dom_current} ] ||
17339                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17340
17341         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17342         $LFS setstripe -d $DIR/$tdir
17343         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17344                 error "Can't set directory default striping"
17345
17346         # exceed maximum stripe size
17347         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17348                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17349         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17350                 error "Able to create DoM component size more than LOD limit"
17351
17352         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17353         dom_current=$(do_facet mds1 $LCTL get_param -n \
17354                                                 lod.$mdtname.dom_stripesize)
17355         [ 0 -eq ${dom_current} ] ||
17356                 error "Can't set zero DoM stripe limit"
17357         rm $dom
17358
17359         # attempt to create DoM file on server with disabled DoM should
17360         # remove DoM entry from layout and be succeed
17361         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17362                 error "Can't create DoM file (DoM is disabled)"
17363         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17364                 error "File has DoM component while DoM is disabled"
17365         rm $dom
17366
17367         # attempt to create DoM file with only DoM stripe should return error
17368         $LFS setstripe -E $dom_limit -L mdt $dom &&
17369                 error "Able to create DoM-only file while DoM is disabled"
17370
17371         # too low values to be aligned with smallest stripe size 64K
17372         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17373         dom_current=$(do_facet mds1 $LCTL get_param -n \
17374                                                 lod.$mdtname.dom_stripesize)
17375         [ 30000 -eq ${dom_current} ] &&
17376                 error "Can set too small DoM stripe limit"
17377
17378         # 64K is a minimal stripe size in Lustre, expect limit of that size
17379         [ 65536 -eq ${dom_current} ] ||
17380                 error "Limit is not set to 64K but ${dom_current}"
17381
17382         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17383         dom_current=$(do_facet mds1 $LCTL get_param -n \
17384                                                 lod.$mdtname.dom_stripesize)
17385         echo $dom_current
17386         [ 2147483648 -eq ${dom_current} ] &&
17387                 error "Can set too large DoM stripe limit"
17388
17389         do_facet mds1 $LCTL set_param -n \
17390                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17391         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17392                 error "Can't create DoM component size after limit change"
17393         do_facet mds1 $LCTL set_param -n \
17394                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17395         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17396                 error "Can't create DoM file after limit decrease"
17397         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17398                 error "Can create big DoM component after limit decrease"
17399         touch ${dom}_def ||
17400                 error "Can't create file with old default layout"
17401
17402         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17403         return 0
17404 }
17405 run_test 270f "DoM: maximum DoM stripe size checks"
17406
17407 test_271a() {
17408         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17409                 skip "Need MDS version at least 2.10.55"
17410
17411         local dom=$DIR/$tdir/dom
17412
17413         mkdir -p $DIR/$tdir
17414
17415         $LFS setstripe -E 1024K -L mdt $dom
17416
17417         lctl set_param -n mdc.*.stats=clear
17418         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17419         cat $dom > /dev/null
17420         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17421         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17422         ls $dom
17423         rm -f $dom
17424 }
17425 run_test 271a "DoM: data is cached for read after write"
17426
17427 test_271b() {
17428         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17429                 skip "Need MDS version at least 2.10.55"
17430
17431         local dom=$DIR/$tdir/dom
17432
17433         mkdir -p $DIR/$tdir
17434
17435         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17436
17437         lctl set_param -n mdc.*.stats=clear
17438         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17439         cancel_lru_locks mdc
17440         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17441         # second stat to check size is cached on client
17442         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17443         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17444         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17445         rm -f $dom
17446 }
17447 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17448
17449 test_271ba() {
17450         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17451                 skip "Need MDS version at least 2.10.55"
17452
17453         local dom=$DIR/$tdir/dom
17454
17455         mkdir -p $DIR/$tdir
17456
17457         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17458
17459         lctl set_param -n mdc.*.stats=clear
17460         lctl set_param -n osc.*.stats=clear
17461         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17462         cancel_lru_locks mdc
17463         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17464         # second stat to check size is cached on client
17465         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17466         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17467         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17468         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17469         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17470         rm -f $dom
17471 }
17472 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17473
17474
17475 get_mdc_stats() {
17476         local mdtidx=$1
17477         local param=$2
17478         local mdt=MDT$(printf %04x $mdtidx)
17479
17480         if [ -z $param ]; then
17481                 lctl get_param -n mdc.*$mdt*.stats
17482         else
17483                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17484         fi
17485 }
17486
17487 test_271c() {
17488         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17489                 skip "Need MDS version at least 2.10.55"
17490
17491         local dom=$DIR/$tdir/dom
17492
17493         mkdir -p $DIR/$tdir
17494
17495         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17496
17497         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17498         local facet=mds$((mdtidx + 1))
17499
17500         cancel_lru_locks mdc
17501         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17502         createmany -o $dom 1000
17503         lctl set_param -n mdc.*.stats=clear
17504         smalliomany -w $dom 1000 200
17505         get_mdc_stats $mdtidx
17506         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17507         # Each file has 1 open, 1 IO enqueues, total 2000
17508         # but now we have also +1 getxattr for security.capability, total 3000
17509         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17510         unlinkmany $dom 1000
17511
17512         cancel_lru_locks mdc
17513         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17514         createmany -o $dom 1000
17515         lctl set_param -n mdc.*.stats=clear
17516         smalliomany -w $dom 1000 200
17517         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17518         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17519         # for OPEN and IO lock.
17520         [ $((enq - enq_2)) -ge 1000 ] ||
17521                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17522         unlinkmany $dom 1000
17523         return 0
17524 }
17525 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17526
17527 cleanup_271def_tests() {
17528         trap 0
17529         rm -f $1
17530 }
17531
17532 test_271d() {
17533         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17534                 skip "Need MDS version at least 2.10.57"
17535
17536         local dom=$DIR/$tdir/dom
17537         local tmp=$TMP/$tfile
17538         trap "cleanup_271def_tests $tmp" EXIT
17539
17540         mkdir -p $DIR/$tdir
17541
17542         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17543
17544         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17545
17546         cancel_lru_locks mdc
17547         dd if=/dev/urandom of=$tmp bs=1000 count=1
17548         dd if=$tmp of=$dom bs=1000 count=1
17549         cancel_lru_locks mdc
17550
17551         cat /etc/hosts >> $tmp
17552         lctl set_param -n mdc.*.stats=clear
17553
17554         # append data to the same file it should update local page
17555         echo "Append to the same page"
17556         cat /etc/hosts >> $dom
17557         local num=$(get_mdc_stats $mdtidx ost_read)
17558         local ra=$(get_mdc_stats $mdtidx req_active)
17559         local rw=$(get_mdc_stats $mdtidx req_waittime)
17560
17561         [ -z $num ] || error "$num READ RPC occured"
17562         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17563         echo "... DONE"
17564
17565         # compare content
17566         cmp $tmp $dom || error "file miscompare"
17567
17568         cancel_lru_locks mdc
17569         lctl set_param -n mdc.*.stats=clear
17570
17571         echo "Open and read file"
17572         cat $dom > /dev/null
17573         local num=$(get_mdc_stats $mdtidx ost_read)
17574         local ra=$(get_mdc_stats $mdtidx req_active)
17575         local rw=$(get_mdc_stats $mdtidx req_waittime)
17576
17577         [ -z $num ] || error "$num READ RPC occured"
17578         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17579         echo "... DONE"
17580
17581         # compare content
17582         cmp $tmp $dom || error "file miscompare"
17583
17584         return 0
17585 }
17586 run_test 271d "DoM: read on open (1K file in reply buffer)"
17587
17588 test_271f() {
17589         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17590                 skip "Need MDS version at least 2.10.57"
17591
17592         local dom=$DIR/$tdir/dom
17593         local tmp=$TMP/$tfile
17594         trap "cleanup_271def_tests $tmp" EXIT
17595
17596         mkdir -p $DIR/$tdir
17597
17598         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17599
17600         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17601
17602         cancel_lru_locks mdc
17603         dd if=/dev/urandom of=$tmp bs=200000 count=1
17604         dd if=$tmp of=$dom bs=200000 count=1
17605         cancel_lru_locks mdc
17606         cat /etc/hosts >> $tmp
17607         lctl set_param -n mdc.*.stats=clear
17608
17609         echo "Append to the same page"
17610         cat /etc/hosts >> $dom
17611         local num=$(get_mdc_stats $mdtidx ost_read)
17612         local ra=$(get_mdc_stats $mdtidx req_active)
17613         local rw=$(get_mdc_stats $mdtidx req_waittime)
17614
17615         [ -z $num ] || error "$num READ RPC occured"
17616         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17617         echo "... DONE"
17618
17619         # compare content
17620         cmp $tmp $dom || error "file miscompare"
17621
17622         cancel_lru_locks mdc
17623         lctl set_param -n mdc.*.stats=clear
17624
17625         echo "Open and read file"
17626         cat $dom > /dev/null
17627         local num=$(get_mdc_stats $mdtidx ost_read)
17628         local ra=$(get_mdc_stats $mdtidx req_active)
17629         local rw=$(get_mdc_stats $mdtidx req_waittime)
17630
17631         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17632         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17633         echo "... DONE"
17634
17635         # compare content
17636         cmp $tmp $dom || error "file miscompare"
17637
17638         return 0
17639 }
17640 run_test 271f "DoM: read on open (200K file and read tail)"
17641
17642 test_272a() {
17643         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17644                 skip "Need MDS version at least 2.11.50"
17645
17646         local dom=$DIR/$tdir/dom
17647         mkdir -p $DIR/$tdir
17648
17649         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17650         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17651                 error "failed to write data into $dom"
17652         local old_md5=$(md5sum $dom)
17653
17654         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17655                 error "failed to migrate to the same DoM component"
17656
17657         local new_md5=$(md5sum $dom)
17658
17659         [ "$old_md5" == "$new_md5" ] ||
17660                 error "md5sum differ: $old_md5, $new_md5"
17661
17662         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17663                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17664 }
17665 run_test 272a "DoM migration: new layout with the same DOM component"
17666
17667 test_272b() {
17668         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17669                 skip "Need MDS version at least 2.11.50"
17670
17671         local dom=$DIR/$tdir/dom
17672         mkdir -p $DIR/$tdir
17673         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17674
17675         local mdtidx=$($LFS getstripe -m $dom)
17676         local mdtname=MDT$(printf %04x $mdtidx)
17677         local facet=mds$((mdtidx + 1))
17678
17679         local mdtfree1=$(do_facet $facet \
17680                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17681         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17682                 error "failed to write data into $dom"
17683         local old_md5=$(md5sum $dom)
17684         cancel_lru_locks mdc
17685         local mdtfree1=$(do_facet $facet \
17686                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17687
17688         $LFS migrate -c2 $dom ||
17689                 error "failed to migrate to the new composite layout"
17690         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17691                 error "MDT stripe was not removed"
17692
17693         cancel_lru_locks mdc
17694         local new_md5=$(md5sum $dom)
17695         [ "$old_md5" != "$new_md5" ] &&
17696                 error "$old_md5 != $new_md5"
17697
17698         # Skip free space checks with ZFS
17699         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17700                 local mdtfree2=$(do_facet $facet \
17701                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17702                 [ $mdtfree2 -gt $mdtfree1 ] ||
17703                         error "MDT space is not freed after migration"
17704         fi
17705         return 0
17706 }
17707 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17708
17709 test_272c() {
17710         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17711                 skip "Need MDS version at least 2.11.50"
17712
17713         local dom=$DIR/$tdir/$tfile
17714         mkdir -p $DIR/$tdir
17715         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17716
17717         local mdtidx=$($LFS getstripe -m $dom)
17718         local mdtname=MDT$(printf %04x $mdtidx)
17719         local facet=mds$((mdtidx + 1))
17720
17721         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17722                 error "failed to write data into $dom"
17723         local old_md5=$(md5sum $dom)
17724         cancel_lru_locks mdc
17725         local mdtfree1=$(do_facet $facet \
17726                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17727
17728         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17729                 error "failed to migrate to the new composite layout"
17730         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17731                 error "MDT stripe was not removed"
17732
17733         cancel_lru_locks mdc
17734         local new_md5=$(md5sum $dom)
17735         [ "$old_md5" != "$new_md5" ] &&
17736                 error "$old_md5 != $new_md5"
17737
17738         # Skip free space checks with ZFS
17739         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17740                 local mdtfree2=$(do_facet $facet \
17741                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17742                 [ $mdtfree2 -gt $mdtfree1 ] ||
17743                         error "MDS space is not freed after migration"
17744         fi
17745         return 0
17746 }
17747 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17748
17749 test_273a() {
17750         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17751                 skip "Need MDS version at least 2.11.50"
17752
17753         # Layout swap cannot be done if either file has DOM component,
17754         # this will never be supported, migration should be used instead
17755
17756         local dom=$DIR/$tdir/$tfile
17757         mkdir -p $DIR/$tdir
17758
17759         $LFS setstripe -c2 ${dom}_plain
17760         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17761         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17762                 error "can swap layout with DoM component"
17763         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17764                 error "can swap layout with DoM component"
17765
17766         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17767         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17768                 error "can swap layout with DoM component"
17769         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17770                 error "can swap layout with DoM component"
17771         return 0
17772 }
17773 run_test 273a "DoM: layout swapping should fail with DOM"
17774
17775 test_275() {
17776         remote_ost_nodsh && skip "remote OST with nodsh"
17777         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17778                 skip "Need OST version >= 2.10.57"
17779
17780         local file=$DIR/$tfile
17781         local oss
17782
17783         oss=$(comma_list $(osts_nodes))
17784
17785         dd if=/dev/urandom of=$file bs=1M count=2 ||
17786                 error "failed to create a file"
17787         cancel_lru_locks osc
17788
17789         #lock 1
17790         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17791                 error "failed to read a file"
17792
17793 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17794         $LCTL set_param fail_loc=0x8000031f
17795
17796         cancel_lru_locks osc &
17797         sleep 1
17798
17799 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17800         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17801         #IO takes another lock, but matches the PENDING one
17802         #and places it to the IO RPC
17803         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17804                 error "failed to read a file with PENDING lock"
17805 }
17806 run_test 275 "Read on a canceled duplicate lock"
17807
17808 test_276() {
17809         remote_ost_nodsh && skip "remote OST with nodsh"
17810         local pid
17811
17812         do_facet ost1 "(while true; do \
17813                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17814                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17815         pid=$!
17816
17817         for LOOP in $(seq 20); do
17818                 stop ost1
17819                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17820         done
17821         kill -9 $pid
17822         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17823                 rm $TMP/sanity_276_pid"
17824 }
17825 run_test 276 "Race between mount and obd_statfs"
17826
17827 cleanup_test_300() {
17828         trap 0
17829         umask $SAVE_UMASK
17830 }
17831 test_striped_dir() {
17832         local mdt_index=$1
17833         local stripe_count
17834         local stripe_index
17835
17836         mkdir -p $DIR/$tdir
17837
17838         SAVE_UMASK=$(umask)
17839         trap cleanup_test_300 RETURN EXIT
17840
17841         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17842                                                 $DIR/$tdir/striped_dir ||
17843                 error "set striped dir error"
17844
17845         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17846         [ "$mode" = "755" ] || error "expect 755 got $mode"
17847
17848         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17849                 error "getdirstripe failed"
17850         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17851         if [ "$stripe_count" != "2" ]; then
17852                 error "1:stripe_count is $stripe_count, expect 2"
17853         fi
17854         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17855         if [ "$stripe_count" != "2" ]; then
17856                 error "2:stripe_count is $stripe_count, expect 2"
17857         fi
17858
17859         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17860         if [ "$stripe_index" != "$mdt_index" ]; then
17861                 error "stripe_index is $stripe_index, expect $mdt_index"
17862         fi
17863
17864         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17865                 error "nlink error after create striped dir"
17866
17867         mkdir $DIR/$tdir/striped_dir/a
17868         mkdir $DIR/$tdir/striped_dir/b
17869
17870         stat $DIR/$tdir/striped_dir/a ||
17871                 error "create dir under striped dir failed"
17872         stat $DIR/$tdir/striped_dir/b ||
17873                 error "create dir under striped dir failed"
17874
17875         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17876                 error "nlink error after mkdir"
17877
17878         rmdir $DIR/$tdir/striped_dir/a
17879         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17880                 error "nlink error after rmdir"
17881
17882         rmdir $DIR/$tdir/striped_dir/b
17883         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17884                 error "nlink error after rmdir"
17885
17886         chattr +i $DIR/$tdir/striped_dir
17887         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17888                 error "immutable flags not working under striped dir!"
17889         chattr -i $DIR/$tdir/striped_dir
17890
17891         rmdir $DIR/$tdir/striped_dir ||
17892                 error "rmdir striped dir error"
17893
17894         cleanup_test_300
17895
17896         true
17897 }
17898
17899 test_300a() {
17900         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17901                 skip "skipped for lustre < 2.7.0"
17902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17903         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17904
17905         test_striped_dir 0 || error "failed on striped dir on MDT0"
17906         test_striped_dir 1 || error "failed on striped dir on MDT0"
17907 }
17908 run_test 300a "basic striped dir sanity test"
17909
17910 test_300b() {
17911         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17912                 skip "skipped for lustre < 2.7.0"
17913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17915
17916         local i
17917         local mtime1
17918         local mtime2
17919         local mtime3
17920
17921         test_mkdir $DIR/$tdir || error "mkdir fail"
17922         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17923                 error "set striped dir error"
17924         for i in {0..9}; do
17925                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17926                 sleep 1
17927                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17928                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17929                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17930                 sleep 1
17931                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17932                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17933                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17934         done
17935         true
17936 }
17937 run_test 300b "check ctime/mtime for striped dir"
17938
17939 test_300c() {
17940         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17941                 skip "skipped for lustre < 2.7.0"
17942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17944
17945         local file_count
17946
17947         mkdir -p $DIR/$tdir
17948         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17949                 error "set striped dir error"
17950
17951         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17952                 error "chown striped dir failed"
17953
17954         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17955                 error "create 5k files failed"
17956
17957         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17958
17959         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17960
17961         rm -rf $DIR/$tdir
17962 }
17963 run_test 300c "chown && check ls under striped directory"
17964
17965 test_300d() {
17966         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17967                 skip "skipped for lustre < 2.7.0"
17968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17970
17971         local stripe_count
17972         local file
17973
17974         mkdir -p $DIR/$tdir
17975         $LFS setstripe -c 2 $DIR/$tdir
17976
17977         #local striped directory
17978         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17979                 error "set striped dir error"
17980         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17981                 error "create 10 files failed"
17982
17983         #remote striped directory
17984         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17985                 error "set striped dir error"
17986         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17987                 error "create 10 files failed"
17988
17989         for file in $(find $DIR/$tdir); do
17990                 stripe_count=$($LFS getstripe -c $file)
17991                 [ $stripe_count -eq 2 ] ||
17992                         error "wrong stripe $stripe_count for $file"
17993         done
17994
17995         rm -rf $DIR/$tdir
17996 }
17997 run_test 300d "check default stripe under striped directory"
17998
17999 test_300e() {
18000         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18001                 skip "Need MDS version at least 2.7.55"
18002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18004
18005         local stripe_count
18006         local file
18007
18008         mkdir -p $DIR/$tdir
18009
18010         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18011                 error "set striped dir error"
18012
18013         touch $DIR/$tdir/striped_dir/a
18014         touch $DIR/$tdir/striped_dir/b
18015         touch $DIR/$tdir/striped_dir/c
18016
18017         mkdir $DIR/$tdir/striped_dir/dir_a
18018         mkdir $DIR/$tdir/striped_dir/dir_b
18019         mkdir $DIR/$tdir/striped_dir/dir_c
18020
18021         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18022                 error "set striped adir under striped dir error"
18023
18024         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18025                 error "set striped bdir under striped dir error"
18026
18027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18028                 error "set striped cdir under striped dir error"
18029
18030         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18031                 error "rename dir under striped dir fails"
18032
18033         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18034                 error "rename dir under different stripes fails"
18035
18036         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18037                 error "rename file under striped dir should succeed"
18038
18039         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18040                 error "rename dir under striped dir should succeed"
18041
18042         rm -rf $DIR/$tdir
18043 }
18044 run_test 300e "check rename under striped directory"
18045
18046 test_300f() {
18047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18049         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18050                 skip "Need MDS version at least 2.7.55"
18051
18052         local stripe_count
18053         local file
18054
18055         rm -rf $DIR/$tdir
18056         mkdir -p $DIR/$tdir
18057
18058         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18059                 error "set striped dir error"
18060
18061         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18062                 error "set striped dir error"
18063
18064         touch $DIR/$tdir/striped_dir/a
18065         mkdir $DIR/$tdir/striped_dir/dir_a
18066         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18067                 error "create striped dir under striped dir fails"
18068
18069         touch $DIR/$tdir/striped_dir1/b
18070         mkdir $DIR/$tdir/striped_dir1/dir_b
18071         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18072                 error "create striped dir under striped dir fails"
18073
18074         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18075                 error "rename dir under different striped dir should fail"
18076
18077         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18078                 error "rename striped dir under diff striped dir should fail"
18079
18080         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18081                 error "rename file under diff striped dirs fails"
18082
18083         rm -rf $DIR/$tdir
18084 }
18085 run_test 300f "check rename cross striped directory"
18086
18087 test_300_check_default_striped_dir()
18088 {
18089         local dirname=$1
18090         local default_count=$2
18091         local default_index=$3
18092         local stripe_count
18093         local stripe_index
18094         local dir_stripe_index
18095         local dir
18096
18097         echo "checking $dirname $default_count $default_index"
18098         $LFS setdirstripe -D -c $default_count -i $default_index \
18099                                 -t all_char $DIR/$tdir/$dirname ||
18100                 error "set default stripe on striped dir error"
18101         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18102         [ $stripe_count -eq $default_count ] ||
18103                 error "expect $default_count get $stripe_count for $dirname"
18104
18105         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18106         [ $stripe_index -eq $default_index ] ||
18107                 error "expect $default_index get $stripe_index for $dirname"
18108
18109         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18110                                                 error "create dirs failed"
18111
18112         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18113         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18114         for dir in $(find $DIR/$tdir/$dirname/*); do
18115                 stripe_count=$($LFS getdirstripe -c $dir)
18116                 [ $stripe_count -eq $default_count ] ||
18117                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18118                 error "stripe count $default_count != $stripe_count for $dir"
18119
18120                 stripe_index=$($LFS getdirstripe -i $dir)
18121                 [ $default_index -eq -1 ] ||
18122                         [ $stripe_index -eq $default_index ] ||
18123                         error "$stripe_index != $default_index for $dir"
18124
18125                 #check default stripe
18126                 stripe_count=$($LFS getdirstripe -D -c $dir)
18127                 [ $stripe_count -eq $default_count ] ||
18128                 error "default count $default_count != $stripe_count for $dir"
18129
18130                 stripe_index=$($LFS getdirstripe -D -i $dir)
18131                 [ $stripe_index -eq $default_index ] ||
18132                 error "default index $default_index != $stripe_index for $dir"
18133         done
18134         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18135 }
18136
18137 test_300g() {
18138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18139         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18140                 skip "Need MDS version at least 2.7.55"
18141
18142         local dir
18143         local stripe_count
18144         local stripe_index
18145
18146         mkdir $DIR/$tdir
18147         mkdir $DIR/$tdir/normal_dir
18148
18149         #Checking when client cache stripe index
18150         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18151         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18152                 error "create striped_dir failed"
18153
18154         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18155                 error "create dir0 fails"
18156         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18157         [ $stripe_index -eq 0 ] ||
18158                 error "dir0 expect index 0 got $stripe_index"
18159
18160         mkdir $DIR/$tdir/striped_dir/dir1 ||
18161                 error "create dir1 fails"
18162         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18163         [ $stripe_index -eq 1 ] ||
18164                 error "dir1 expect index 1 got $stripe_index"
18165
18166         #check default stripe count/stripe index
18167         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18168         test_300_check_default_striped_dir normal_dir 1 0
18169         test_300_check_default_striped_dir normal_dir 2 1
18170         test_300_check_default_striped_dir normal_dir 2 -1
18171
18172         #delete default stripe information
18173         echo "delete default stripeEA"
18174         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18175                 error "set default stripe on striped dir error"
18176
18177         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18178         for dir in $(find $DIR/$tdir/normal_dir/*); do
18179                 stripe_count=$($LFS getdirstripe -c $dir)
18180                 [ $stripe_count -eq 0 ] ||
18181                         error "expect 1 get $stripe_count for $dir"
18182                 stripe_index=$($LFS getdirstripe -i $dir)
18183                 [ $stripe_index -eq 0 ] ||
18184                         error "expect 0 get $stripe_index for $dir"
18185         done
18186 }
18187 run_test 300g "check default striped directory for normal directory"
18188
18189 test_300h() {
18190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18191         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18192                 skip "Need MDS version at least 2.7.55"
18193
18194         local dir
18195         local stripe_count
18196
18197         mkdir $DIR/$tdir
18198         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18199                 error "set striped dir error"
18200
18201         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18202         test_300_check_default_striped_dir striped_dir 1 0
18203         test_300_check_default_striped_dir striped_dir 2 1
18204         test_300_check_default_striped_dir striped_dir 2 -1
18205
18206         #delete default stripe information
18207         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18208                 error "set default stripe on striped dir error"
18209
18210         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18211         for dir in $(find $DIR/$tdir/striped_dir/*); do
18212                 stripe_count=$($LFS getdirstripe -c $dir)
18213                 [ $stripe_count -eq 0 ] ||
18214                         error "expect 1 get $stripe_count for $dir"
18215         done
18216 }
18217 run_test 300h "check default striped directory for striped directory"
18218
18219 test_300i() {
18220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18222         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18223                 skip "Need MDS version at least 2.7.55"
18224
18225         local stripe_count
18226         local file
18227
18228         mkdir $DIR/$tdir
18229
18230         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18231                 error "set striped dir error"
18232
18233         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18234                 error "create files under striped dir failed"
18235
18236         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18237                 error "set striped hashdir error"
18238
18239         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18240                 error "create dir0 under hash dir failed"
18241         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18242                 error "create dir1 under hash dir failed"
18243
18244         # unfortunately, we need to umount to clear dir layout cache for now
18245         # once we fully implement dir layout, we can drop this
18246         umount_client $MOUNT || error "umount failed"
18247         mount_client $MOUNT || error "mount failed"
18248
18249         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18250         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18251         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18252
18253         #set the stripe to be unknown hash type
18254         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18255         $LCTL set_param fail_loc=0x1901
18256         for ((i = 0; i < 10; i++)); do
18257                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18258                         error "stat f-$i failed"
18259                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18260         done
18261
18262         touch $DIR/$tdir/striped_dir/f0 &&
18263                 error "create under striped dir with unknown hash should fail"
18264
18265         $LCTL set_param fail_loc=0
18266
18267         umount_client $MOUNT || error "umount failed"
18268         mount_client $MOUNT || error "mount failed"
18269
18270         return 0
18271 }
18272 run_test 300i "client handle unknown hash type striped directory"
18273
18274 test_300j() {
18275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18277         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18278                 skip "Need MDS version at least 2.7.55"
18279
18280         local stripe_count
18281         local file
18282
18283         mkdir $DIR/$tdir
18284
18285         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18286         $LCTL set_param fail_loc=0x1702
18287         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18288                 error "set striped dir error"
18289
18290         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18291                 error "create files under striped dir failed"
18292
18293         $LCTL set_param fail_loc=0
18294
18295         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18296
18297         return 0
18298 }
18299 run_test 300j "test large update record"
18300
18301 test_300k() {
18302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18303         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18304         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18305                 skip "Need MDS version at least 2.7.55"
18306
18307         # this test needs a huge transaction
18308         local kb
18309         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18310         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18311
18312         local stripe_count
18313         local file
18314
18315         mkdir $DIR/$tdir
18316
18317         #define OBD_FAIL_LARGE_STRIPE   0x1703
18318         $LCTL set_param fail_loc=0x1703
18319         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18320                 error "set striped dir error"
18321         $LCTL set_param fail_loc=0
18322
18323         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18324                 error "getstripeddir fails"
18325         rm -rf $DIR/$tdir/striped_dir ||
18326                 error "unlink striped dir fails"
18327
18328         return 0
18329 }
18330 run_test 300k "test large striped directory"
18331
18332 test_300l() {
18333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18335         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18336                 skip "Need MDS version at least 2.7.55"
18337
18338         local stripe_index
18339
18340         test_mkdir -p $DIR/$tdir/striped_dir
18341         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18342                         error "chown $RUNAS_ID failed"
18343         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18344                 error "set default striped dir failed"
18345
18346         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18347         $LCTL set_param fail_loc=0x80000158
18348         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18349
18350         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18351         [ $stripe_index -eq 1 ] ||
18352                 error "expect 1 get $stripe_index for $dir"
18353 }
18354 run_test 300l "non-root user to create dir under striped dir with stale layout"
18355
18356 test_300m() {
18357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18358         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18359         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18360                 skip "Need MDS version at least 2.7.55"
18361
18362         mkdir -p $DIR/$tdir/striped_dir
18363         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18364                 error "set default stripes dir error"
18365
18366         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18367
18368         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18369         [ $stripe_count -eq 0 ] ||
18370                         error "expect 0 get $stripe_count for a"
18371
18372         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18373                 error "set default stripes dir error"
18374
18375         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18376
18377         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18378         [ $stripe_count -eq 0 ] ||
18379                         error "expect 0 get $stripe_count for b"
18380
18381         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18382                 error "set default stripes dir error"
18383
18384         mkdir $DIR/$tdir/striped_dir/c &&
18385                 error "default stripe_index is invalid, mkdir c should fails"
18386
18387         rm -rf $DIR/$tdir || error "rmdir fails"
18388 }
18389 run_test 300m "setstriped directory on single MDT FS"
18390
18391 cleanup_300n() {
18392         local list=$(comma_list $(mdts_nodes))
18393
18394         trap 0
18395         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18396 }
18397
18398 test_300n() {
18399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18401         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18402                 skip "Need MDS version at least 2.7.55"
18403         remote_mds_nodsh && skip "remote MDS with nodsh"
18404
18405         local stripe_index
18406         local list=$(comma_list $(mdts_nodes))
18407
18408         trap cleanup_300n RETURN EXIT
18409         mkdir -p $DIR/$tdir
18410         chmod 777 $DIR/$tdir
18411         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18412                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18413                 error "create striped dir succeeds with gid=0"
18414
18415         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18416         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18417                 error "create striped dir fails with gid=-1"
18418
18419         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18420         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18421                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18422                 error "set default striped dir succeeds with gid=0"
18423
18424
18425         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18426         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18427                 error "set default striped dir fails with gid=-1"
18428
18429
18430         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18431         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18432                                         error "create test_dir fails"
18433         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18434                                         error "create test_dir1 fails"
18435         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18436                                         error "create test_dir2 fails"
18437         cleanup_300n
18438 }
18439 run_test 300n "non-root user to create dir under striped dir with default EA"
18440
18441 test_300o() {
18442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18444         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18445                 skip "Need MDS version at least 2.7.55"
18446
18447         local numfree1
18448         local numfree2
18449
18450         mkdir -p $DIR/$tdir
18451
18452         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18453         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18454         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18455                 skip "not enough free inodes $numfree1 $numfree2"
18456         fi
18457
18458         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18459         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18460         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18461                 skip "not enough free space $numfree1 $numfree2"
18462         fi
18463
18464         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18465                 error "setdirstripe fails"
18466
18467         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18468                 error "create dirs fails"
18469
18470         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18471         ls $DIR/$tdir/striped_dir > /dev/null ||
18472                 error "ls striped dir fails"
18473         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18474                 error "unlink big striped dir fails"
18475 }
18476 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18477
18478 test_300p() {
18479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18481         remote_mds_nodsh && skip "remote MDS with nodsh"
18482
18483         mkdir -p $DIR/$tdir
18484
18485         #define OBD_FAIL_OUT_ENOSPC     0x1704
18486         do_facet mds2 lctl set_param fail_loc=0x80001704
18487         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18488                  && error "create striped directory should fail"
18489
18490         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18491
18492         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18493         true
18494 }
18495 run_test 300p "create striped directory without space"
18496
18497 test_300q() {
18498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18499         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18500
18501         local fd=$(free_fd)
18502         local cmd="exec $fd<$tdir"
18503         cd $DIR
18504         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18505         eval $cmd
18506         cmd="exec $fd<&-"
18507         trap "eval $cmd" EXIT
18508         cd $tdir || error "cd $tdir fails"
18509         rmdir  ../$tdir || error "rmdir $tdir fails"
18510         mkdir local_dir && error "create dir succeeds"
18511         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18512         eval $cmd
18513         return 0
18514 }
18515 run_test 300q "create remote directory under orphan directory"
18516
18517 test_300r() {
18518         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18519                 skip "Need MDS version at least 2.7.55" && return
18520         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18521
18522         mkdir $DIR/$tdir
18523
18524         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18525                 error "set striped dir error"
18526
18527         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18528                 error "getstripeddir fails"
18529
18530         local stripe_count
18531         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18532                       awk '/lmv_stripe_count:/ { print $2 }')
18533
18534         [ $MDSCOUNT -ne $stripe_count ] &&
18535                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18536
18537         rm -rf $DIR/$tdir/striped_dir ||
18538                 error "unlink striped dir fails"
18539 }
18540 run_test 300r "test -1 striped directory"
18541
18542 prepare_remote_file() {
18543         mkdir $DIR/$tdir/src_dir ||
18544                 error "create remote source failed"
18545
18546         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18547                  error "cp to remote source failed"
18548         touch $DIR/$tdir/src_dir/a
18549
18550         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18551                 error "create remote target dir failed"
18552
18553         touch $DIR/$tdir/tgt_dir/b
18554
18555         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18556                 error "rename dir cross MDT failed!"
18557
18558         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18559                 error "src_child still exists after rename"
18560
18561         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18562                 error "missing file(a) after rename"
18563
18564         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18565                 error "diff after rename"
18566 }
18567
18568 test_310a() {
18569         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18571
18572         local remote_file=$DIR/$tdir/tgt_dir/b
18573
18574         mkdir -p $DIR/$tdir
18575
18576         prepare_remote_file || error "prepare remote file failed"
18577
18578         #open-unlink file
18579         $OPENUNLINK $remote_file $remote_file ||
18580                 error "openunlink $remote_file failed"
18581         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18582 }
18583 run_test 310a "open unlink remote file"
18584
18585 test_310b() {
18586         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18588
18589         local remote_file=$DIR/$tdir/tgt_dir/b
18590
18591         mkdir -p $DIR/$tdir
18592
18593         prepare_remote_file || error "prepare remote file failed"
18594
18595         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18596         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18597         $CHECKSTAT -t file $remote_file || error "check file failed"
18598 }
18599 run_test 310b "unlink remote file with multiple links while open"
18600
18601 test_310c() {
18602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18603         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18604
18605         local remote_file=$DIR/$tdir/tgt_dir/b
18606
18607         mkdir -p $DIR/$tdir
18608
18609         prepare_remote_file || error "prepare remote file failed"
18610
18611         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18612         multiop_bg_pause $remote_file O_uc ||
18613                         error "mulitop failed for remote file"
18614         MULTIPID=$!
18615         $MULTIOP $DIR/$tfile Ouc
18616         kill -USR1 $MULTIPID
18617         wait $MULTIPID
18618 }
18619 run_test 310c "open-unlink remote file with multiple links"
18620
18621 #LU-4825
18622 test_311() {
18623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18624         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18625         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18626                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18627         remote_mds_nodsh && skip "remote MDS with nodsh"
18628
18629         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18630         local mdts=$(comma_list $(mdts_nodes))
18631
18632         mkdir -p $DIR/$tdir
18633         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18634         createmany -o $DIR/$tdir/$tfile. 1000
18635
18636         # statfs data is not real time, let's just calculate it
18637         old_iused=$((old_iused + 1000))
18638
18639         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18640                         osp.*OST0000*MDT0000.create_count")
18641         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18642                                 osp.*OST0000*MDT0000.max_create_count")
18643         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18644
18645         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18646         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18647         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18648
18649         unlinkmany $DIR/$tdir/$tfile. 1000
18650
18651         do_nodes $mdts "$LCTL set_param -n \
18652                         osp.*OST0000*.max_create_count=$max_count"
18653         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18654                 do_nodes $mdts "$LCTL set_param -n \
18655                                 osp.*OST0000*.create_count=$count"
18656         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18657                         grep "=0" && error "create_count is zero"
18658
18659         local new_iused
18660         for i in $(seq 120); do
18661                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18662                 # system may be too busy to destroy all objs in time, use
18663                 # a somewhat small value to not fail autotest
18664                 [ $((old_iused - new_iused)) -gt 400 ] && break
18665                 sleep 1
18666         done
18667
18668         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18669         [ $((old_iused - new_iused)) -gt 400 ] ||
18670                 error "objs not destroyed after unlink"
18671 }
18672 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18673
18674 zfs_oid_to_objid()
18675 {
18676         local ost=$1
18677         local objid=$2
18678
18679         local vdevdir=$(dirname $(facet_vdevice $ost))
18680         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18681         local zfs_zapid=$(do_facet $ost $cmd |
18682                           grep -w "/O/0/d$((objid%32))" -C 5 |
18683                           awk '/Object/{getline; print $1}')
18684         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18685                           awk "/$objid = /"'{printf $3}')
18686
18687         echo $zfs_objid
18688 }
18689
18690 zfs_object_blksz() {
18691         local ost=$1
18692         local objid=$2
18693
18694         local vdevdir=$(dirname $(facet_vdevice $ost))
18695         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18696         local blksz=$(do_facet $ost $cmd $objid |
18697                       awk '/dblk/{getline; printf $4}')
18698
18699         case "${blksz: -1}" in
18700                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18701                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18702                 *) ;;
18703         esac
18704
18705         echo $blksz
18706 }
18707
18708 test_312() { # LU-4856
18709         remote_ost_nodsh && skip "remote OST with nodsh"
18710         [ "$ost1_FSTYPE" = "zfs" ] ||
18711                 skip_env "the test only applies to zfs"
18712
18713         local max_blksz=$(do_facet ost1 \
18714                           $ZFS get -p recordsize $(facet_device ost1) |
18715                           awk '!/VALUE/{print $3}')
18716
18717         # to make life a little bit easier
18718         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18719         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18720
18721         local tf=$DIR/$tdir/$tfile
18722         touch $tf
18723         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18724
18725         # Get ZFS object id
18726         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18727         # block size change by sequential overwrite
18728         local bs
18729
18730         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18731                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18732
18733                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18734                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18735         done
18736         rm -f $tf
18737
18738         # block size change by sequential append write
18739         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18740         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18741         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18742         local count
18743
18744         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18745                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18746                         oflag=sync conv=notrunc
18747
18748                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18749                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18750                         error "blksz error, actual $blksz, " \
18751                                 "expected: 2 * $count * $PAGE_SIZE"
18752         done
18753         rm -f $tf
18754
18755         # random write
18756         touch $tf
18757         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18758         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18759
18760         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18761         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18762         [ $blksz -eq $PAGE_SIZE ] ||
18763                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18764
18765         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18766         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18767         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18768
18769         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18770         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18771         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18772 }
18773 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18774
18775 test_313() {
18776         remote_ost_nodsh && skip "remote OST with nodsh"
18777
18778         local file=$DIR/$tfile
18779
18780         rm -f $file
18781         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18782
18783         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18784         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18785         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18786                 error "write should failed"
18787         do_facet ost1 "$LCTL set_param fail_loc=0"
18788         rm -f $file
18789 }
18790 run_test 313 "io should fail after last_rcvd update fail"
18791
18792 test_314() {
18793         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18794
18795         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18796         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18797         rm -f $DIR/$tfile
18798         wait_delete_completed
18799         do_facet ost1 "$LCTL set_param fail_loc=0"
18800 }
18801 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18802
18803 test_315() { # LU-618
18804         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18805
18806         local file=$DIR/$tfile
18807         rm -f $file
18808
18809         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18810                 error "multiop file write failed"
18811         $MULTIOP $file oO_RDONLY:r4063232_c &
18812         PID=$!
18813
18814         sleep 2
18815
18816         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18817         kill -USR1 $PID
18818
18819         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18820         rm -f $file
18821 }
18822 run_test 315 "read should be accounted"
18823
18824 test_316() {
18825         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18826         large_xattr_enabled || skip_env "ea_inode feature disabled"
18827
18828         rm -rf $DIR/$tdir/d
18829         mkdir -p $DIR/$tdir/d
18830         chown nobody $DIR/$tdir/d
18831         touch $DIR/$tdir/d/file
18832
18833         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18834 }
18835 run_test 316 "lfs mv"
18836
18837 test_317() {
18838         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18839                 skip "Need MDS version at least 2.11.53"
18840         local trunc_sz
18841         local grant_blk_size
18842
18843         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18844                 skip "LU-10370: no implementation for ZFS" && return
18845         fi
18846
18847         stack_trap "rm -f $DIR/$tfile" EXIT
18848         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18849                         awk '/grant_block_size:/ { print $2; exit; }')
18850         #
18851         # Create File of size 5M. Truncate it to below size's and verify
18852         # blocks count.
18853         #
18854         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18855                 error "Create file : $DIR/$tfile"
18856
18857         for trunc_sz in 2097152 4097 4000 509 0; do
18858                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18859                         error "truncate $tfile to $trunc_sz failed"
18860                 local sz=$(stat --format=%s $DIR/$tfile)
18861                 local blk=$(stat --format=%b $DIR/$tfile)
18862                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18863                                      grant_blk_size) * 8))
18864
18865                 if [[ $blk -ne $trunc_blk ]]; then
18866                         $(which stat) $DIR/$tfile
18867                         error "Expected Block $trunc_blk got $blk for $tfile"
18868                 fi
18869
18870                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18871                         error "Expected Size $trunc_sz got $sz for $tfile"
18872         done
18873
18874         #
18875         # sparse file test
18876         # Create file with a hole and write actual two blocks. Block count
18877         # must be 16.
18878         #
18879         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18880                 conv=fsync || error "Create file : $DIR/$tfile"
18881
18882         # Calculate the final truncate size.
18883         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18884
18885         #
18886         # truncate to size $trunc_sz bytes. Strip the last block
18887         # The block count must drop to 8
18888         #
18889         $TRUNCATE $DIR/$tfile $trunc_sz ||
18890                 error "truncate $tfile to $trunc_sz failed"
18891
18892         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18893         sz=$(stat --format=%s $DIR/$tfile)
18894         blk=$(stat --format=%b $DIR/$tfile)
18895
18896         if [[ $blk -ne $trunc_bsz ]]; then
18897                 $(which stat) $DIR/$tfile
18898                 error "Expected Block $trunc_bsz got $blk for $tfile"
18899         fi
18900
18901         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18902                 error "Expected Size $trunc_sz got $sz for $tfile"
18903 }
18904 run_test 317 "Verify blocks get correctly update after truncate"
18905
18906 test_319() {
18907         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18908
18909         local before=$(date +%s)
18910         local evict
18911         local mdir=$DIR/$tdir
18912         local file=$mdir/xxx
18913
18914         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18915         touch $file
18916
18917 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18918         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18919         $LFS mv -m1 $file &
18920
18921         sleep 1
18922         dd if=$file of=/dev/null
18923         wait
18924         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18925           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18926
18927         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18928 }
18929 run_test 319 "lost lease lock on migrate error"
18930
18931 test_fake_rw() {
18932         local read_write=$1
18933         if [ "$read_write" = "write" ]; then
18934                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18935         elif [ "$read_write" = "read" ]; then
18936                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18937         else
18938                 error "argument error"
18939         fi
18940
18941         # turn off debug for performance testing
18942         local saved_debug=$($LCTL get_param -n debug)
18943         $LCTL set_param debug=0
18944
18945         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18946
18947         # get ost1 size - lustre-OST0000
18948         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18949         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18950         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18951
18952         if [ "$read_write" = "read" ]; then
18953                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18954         fi
18955
18956         local start_time=$(date +%s.%N)
18957         $dd_cmd bs=1M count=$blocks oflag=sync ||
18958                 error "real dd $read_write error"
18959         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18960
18961         if [ "$read_write" = "write" ]; then
18962                 rm -f $DIR/$tfile
18963         fi
18964
18965         # define OBD_FAIL_OST_FAKE_RW           0x238
18966         do_facet ost1 $LCTL set_param fail_loc=0x238
18967
18968         local start_time=$(date +%s.%N)
18969         $dd_cmd bs=1M count=$blocks oflag=sync ||
18970                 error "fake dd $read_write error"
18971         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18972
18973         if [ "$read_write" = "write" ]; then
18974                 # verify file size
18975                 cancel_lru_locks osc
18976                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18977                         error "$tfile size not $blocks MB"
18978         fi
18979         do_facet ost1 $LCTL set_param fail_loc=0
18980
18981         echo "fake $read_write $duration_fake vs. normal $read_write" \
18982                 "$duration in seconds"
18983         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18984                 error_not_in_vm "fake write is slower"
18985
18986         $LCTL set_param -n debug="$saved_debug"
18987         rm -f $DIR/$tfile
18988 }
18989 test_399a() { # LU-7655 for OST fake write
18990         remote_ost_nodsh && skip "remote OST with nodsh"
18991
18992         test_fake_rw write
18993 }
18994 run_test 399a "fake write should not be slower than normal write"
18995
18996 test_399b() { # LU-8726 for OST fake read
18997         remote_ost_nodsh && skip "remote OST with nodsh"
18998         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18999                 skip_env "ldiskfs only test"
19000         fi
19001
19002         test_fake_rw read
19003 }
19004 run_test 399b "fake read should not be slower than normal read"
19005
19006 test_400a() { # LU-1606, was conf-sanity test_74
19007         if ! which $CC > /dev/null 2>&1; then
19008                 skip_env "$CC is not installed"
19009         fi
19010
19011         local extra_flags=''
19012         local out=$TMP/$tfile
19013         local prefix=/usr/include/lustre
19014         local prog
19015
19016         if ! [[ -d $prefix ]]; then
19017                 # Assume we're running in tree and fixup the include path.
19018                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19019                 extra_flags+=" -L$LUSTRE/utils/.lib"
19020         fi
19021
19022         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19023                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19024                         error "client api broken"
19025         done
19026         rm -f $out
19027 }
19028 run_test 400a "Lustre client api program can compile and link"
19029
19030 test_400b() { # LU-1606, LU-5011
19031         local header
19032         local out=$TMP/$tfile
19033         local prefix=/usr/include/linux/lustre
19034
19035         # We use a hard coded prefix so that this test will not fail
19036         # when run in tree. There are headers in lustre/include/lustre/
19037         # that are not packaged (like lustre_idl.h) and have more
19038         # complicated include dependencies (like config.h and lnet/types.h).
19039         # Since this test about correct packaging we just skip them when
19040         # they don't exist (see below) rather than try to fixup cppflags.
19041
19042         if ! which $CC > /dev/null 2>&1; then
19043                 skip_env "$CC is not installed"
19044         fi
19045
19046         for header in $prefix/*.h; do
19047                 if ! [[ -f "$header" ]]; then
19048                         continue
19049                 fi
19050
19051                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19052                         continue # lustre_ioctl.h is internal header
19053                 fi
19054
19055                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19056                         error "cannot compile '$header'"
19057         done
19058         rm -f $out
19059 }
19060 run_test 400b "packaged headers can be compiled"
19061
19062 test_401a() { #LU-7437
19063         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19064         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19065
19066         #count the number of parameters by "list_param -R"
19067         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19068         #count the number of parameters by listing proc files
19069         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19070         echo "proc_dirs='$proc_dirs'"
19071         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19072         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19073                       sort -u | wc -l)
19074
19075         [ $params -eq $procs ] ||
19076                 error "found $params parameters vs. $procs proc files"
19077
19078         # test the list_param -D option only returns directories
19079         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19080         #count the number of parameters by listing proc directories
19081         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19082                 sort -u | wc -l)
19083
19084         [ $params -eq $procs ] ||
19085                 error "found $params parameters vs. $procs proc files"
19086 }
19087 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19088
19089 test_401b() {
19090         local save=$($LCTL get_param -n jobid_var)
19091         local tmp=testing
19092
19093         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19094                 error "no error returned when setting bad parameters"
19095
19096         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19097         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19098
19099         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19100         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19101         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19102 }
19103 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19104
19105 test_401c() {
19106         local jobid_var_old=$($LCTL get_param -n jobid_var)
19107         local jobid_var_new
19108
19109         $LCTL set_param jobid_var= &&
19110                 error "no error returned for 'set_param a='"
19111
19112         jobid_var_new=$($LCTL get_param -n jobid_var)
19113         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19114                 error "jobid_var was changed by setting without value"
19115
19116         $LCTL set_param jobid_var &&
19117                 error "no error returned for 'set_param a'"
19118
19119         jobid_var_new=$($LCTL get_param -n jobid_var)
19120         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19121                 error "jobid_var was changed by setting without value"
19122 }
19123 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19124
19125 test_401d() {
19126         local jobid_var_old=$($LCTL get_param -n jobid_var)
19127         local jobid_var_new
19128         local new_value="foo=bar"
19129
19130         $LCTL set_param jobid_var=$new_value ||
19131                 error "'set_param a=b' did not accept a value containing '='"
19132
19133         jobid_var_new=$($LCTL get_param -n jobid_var)
19134         [[ "$jobid_var_new" == "$new_value" ]] ||
19135                 error "'set_param a=b' failed on a value containing '='"
19136
19137         # Reset the jobid_var to test the other format
19138         $LCTL set_param jobid_var=$jobid_var_old
19139         jobid_var_new=$($LCTL get_param -n jobid_var)
19140         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19141                 error "failed to reset jobid_var"
19142
19143         $LCTL set_param jobid_var $new_value ||
19144                 error "'set_param a b' did not accept a value containing '='"
19145
19146         jobid_var_new=$($LCTL get_param -n jobid_var)
19147         [[ "$jobid_var_new" == "$new_value" ]] ||
19148                 error "'set_param a b' failed on a value containing '='"
19149
19150         $LCTL set_param jobid_var $jobid_var_old
19151         jobid_var_new=$($LCTL get_param -n jobid_var)
19152         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19153                 error "failed to reset jobid_var"
19154 }
19155 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19156
19157 test_402() {
19158         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19159         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19160                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19161         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19162                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19163                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19164         remote_mds_nodsh && skip "remote MDS with nodsh"
19165
19166         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19167 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19168         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19169         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19170                 echo "Touch failed - OK"
19171 }
19172 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19173
19174 test_403() {
19175         local file1=$DIR/$tfile.1
19176         local file2=$DIR/$tfile.2
19177         local tfile=$TMP/$tfile
19178
19179         rm -f $file1 $file2 $tfile
19180
19181         touch $file1
19182         ln $file1 $file2
19183
19184         # 30 sec OBD_TIMEOUT in ll_getattr()
19185         # right before populating st_nlink
19186         $LCTL set_param fail_loc=0x80001409
19187         stat -c %h $file1 > $tfile &
19188
19189         # create an alias, drop all locks and reclaim the dentry
19190         < $file2
19191         cancel_lru_locks mdc
19192         cancel_lru_locks osc
19193         sysctl -w vm.drop_caches=2
19194
19195         wait
19196
19197         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19198
19199         rm -f $tfile $file1 $file2
19200 }
19201 run_test 403 "i_nlink should not drop to zero due to aliasing"
19202
19203 test_404() { # LU-6601
19204         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19205                 skip "Need server version newer than 2.8.52"
19206         remote_mds_nodsh && skip "remote MDS with nodsh"
19207
19208         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19209                 awk '/osp .*-osc-MDT/ { print $4}')
19210
19211         local osp
19212         for osp in $mosps; do
19213                 echo "Deactivate: " $osp
19214                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19215                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19216                         awk -vp=$osp '$4 == p { print $2 }')
19217                 [ $stat = IN ] || {
19218                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19219                         error "deactivate error"
19220                 }
19221                 echo "Activate: " $osp
19222                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19223                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19224                         awk -vp=$osp '$4 == p { print $2 }')
19225                 [ $stat = UP ] || {
19226                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19227                         error "activate error"
19228                 }
19229         done
19230 }
19231 run_test 404 "validate manual {de}activated works properly for OSPs"
19232
19233 test_405() {
19234         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19235         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19236                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19237                         skip "Layout swap lock is not supported"
19238
19239         check_swap_layouts_support
19240
19241         test_mkdir $DIR/$tdir
19242         swap_lock_test -d $DIR/$tdir ||
19243                 error "One layout swap locked test failed"
19244 }
19245 run_test 405 "Various layout swap lock tests"
19246
19247 test_406() {
19248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19249         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19250         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19252         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19253                 skip "Need MDS version at least 2.8.50"
19254
19255         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19256         local test_pool=$TESTNAME
19257
19258         if ! combined_mgs_mds ; then
19259                 mount_mgs_client
19260         fi
19261         pool_add $test_pool || error "pool_add failed"
19262         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19263                 error "pool_add_targets failed"
19264
19265         save_layout_restore_at_exit $MOUNT
19266
19267         # parent set default stripe count only, child will stripe from both
19268         # parent and fs default
19269         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19270                 error "setstripe $MOUNT failed"
19271         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19272         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19273         for i in $(seq 10); do
19274                 local f=$DIR/$tdir/$tfile.$i
19275                 touch $f || error "touch failed"
19276                 local count=$($LFS getstripe -c $f)
19277                 [ $count -eq $OSTCOUNT ] ||
19278                         error "$f stripe count $count != $OSTCOUNT"
19279                 local offset=$($LFS getstripe -i $f)
19280                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19281                 local size=$($LFS getstripe -S $f)
19282                 [ $size -eq $((def_stripe_size * 2)) ] ||
19283                         error "$f stripe size $size != $((def_stripe_size * 2))"
19284                 local pool=$($LFS getstripe -p $f)
19285                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19286         done
19287
19288         # change fs default striping, delete parent default striping, now child
19289         # will stripe from new fs default striping only
19290         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19291                 error "change $MOUNT default stripe failed"
19292         $LFS setstripe -c 0 $DIR/$tdir ||
19293                 error "delete $tdir default stripe failed"
19294         for i in $(seq 11 20); do
19295                 local f=$DIR/$tdir/$tfile.$i
19296                 touch $f || error "touch $f failed"
19297                 local count=$($LFS getstripe -c $f)
19298                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19299                 local offset=$($LFS getstripe -i $f)
19300                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19301                 local size=$($LFS getstripe -S $f)
19302                 [ $size -eq $def_stripe_size ] ||
19303                         error "$f stripe size $size != $def_stripe_size"
19304                 local pool=$($LFS getstripe -p $f)
19305                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19306         done
19307
19308         unlinkmany $DIR/$tdir/$tfile. 1 20
19309
19310         local f=$DIR/$tdir/$tfile
19311         pool_remove_all_targets $test_pool $f
19312         pool_remove $test_pool $f
19313
19314         if ! combined_mgs_mds ; then
19315                 umount_mgs_client
19316         fi
19317 }
19318 run_test 406 "DNE support fs default striping"
19319
19320 test_407() {
19321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19322         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19323                 skip "Need MDS version at least 2.8.55"
19324         remote_mds_nodsh && skip "remote MDS with nodsh"
19325
19326         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19327                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19328         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19329                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19330         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19331
19332         #define OBD_FAIL_DT_TXN_STOP    0x2019
19333         for idx in $(seq $MDSCOUNT); do
19334                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19335         done
19336         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19337         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19338                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19339         true
19340 }
19341 run_test 407 "transaction fail should cause operation fail"
19342
19343 test_408() {
19344         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19345
19346         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19347         lctl set_param fail_loc=0x8000040a
19348         # let ll_prepare_partial_page() fail
19349         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19350
19351         rm -f $DIR/$tfile
19352
19353         # create at least 100 unused inodes so that
19354         # shrink_icache_memory(0) should not return 0
19355         touch $DIR/$tfile-{0..100}
19356         rm -f $DIR/$tfile-{0..100}
19357         sync
19358
19359         echo 2 > /proc/sys/vm/drop_caches
19360 }
19361 run_test 408 "drop_caches should not hang due to page leaks"
19362
19363 test_409()
19364 {
19365         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19366
19367         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19368         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19369         touch $DIR/$tdir/guard || error "(2) Fail to create"
19370
19371         local PREFIX=$(str_repeat 'A' 128)
19372         echo "Create 1K hard links start at $(date)"
19373         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19374                 error "(3) Fail to hard link"
19375
19376         echo "Links count should be right although linkEA overflow"
19377         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19378         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19379         [ $linkcount -eq 1001 ] ||
19380                 error "(5) Unexpected hard links count: $linkcount"
19381
19382         echo "List all links start at $(date)"
19383         ls -l $DIR/$tdir/foo > /dev/null ||
19384                 error "(6) Fail to list $DIR/$tdir/foo"
19385
19386         echo "Unlink hard links start at $(date)"
19387         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19388                 error "(7) Fail to unlink"
19389         echo "Unlink hard links finished at $(date)"
19390 }
19391 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19392
19393 test_410()
19394 {
19395         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19396                 skip "Need client version at least 2.9.59"
19397
19398         # Create a file, and stat it from the kernel
19399         local testfile=$DIR/$tfile
19400         touch $testfile
19401
19402         local run_id=$RANDOM
19403         local my_ino=$(stat --format "%i" $testfile)
19404
19405         # Try to insert the module. This will always fail as the
19406         # module is designed to not be inserted.
19407         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19408             &> /dev/null
19409
19410         # Anything but success is a test failure
19411         dmesg | grep -q \
19412             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19413             error "no inode match"
19414 }
19415 run_test 410 "Test inode number returned from kernel thread"
19416
19417 cleanup_test411_cgroup() {
19418         trap 0
19419         rmdir "$1"
19420 }
19421
19422 test_411() {
19423         local cg_basedir=/sys/fs/cgroup/memory
19424         # LU-9966
19425         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19426                 skip "no setup for cgroup"
19427
19428         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19429                 error "test file creation failed"
19430         cancel_lru_locks osc
19431
19432         # Create a very small memory cgroup to force a slab allocation error
19433         local cgdir=$cg_basedir/osc_slab_alloc
19434         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19435         trap "cleanup_test411_cgroup $cgdir" EXIT
19436         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19437         echo 1M > $cgdir/memory.limit_in_bytes
19438
19439         # Should not LBUG, just be killed by oom-killer
19440         # dd will return 0 even allocation failure in some environment.
19441         # So don't check return value
19442         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19443         cleanup_test411_cgroup $cgdir
19444
19445         return 0
19446 }
19447 run_test 411 "Slab allocation error with cgroup does not LBUG"
19448
19449 test_412() {
19450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19451         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19452                 skip "Need server version at least 2.10.55"
19453         fi
19454
19455         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19456                 error "mkdir failed"
19457         $LFS getdirstripe $DIR/$tdir
19458         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19459         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19460                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19461         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19462         [ $stripe_count -eq 2 ] ||
19463                 error "expect 2 get $stripe_count"
19464 }
19465 run_test 412 "mkdir on specific MDTs"
19466
19467 test_413() {
19468         [ $MDSCOUNT -lt 2 ] &&
19469                 skip "We need at least 2 MDTs for this test"
19470
19471         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19472                 skip "Need server version at least 2.10.55"
19473         fi
19474
19475         mkdir $DIR/$tdir || error "mkdir failed"
19476
19477         # find MDT that is the most full
19478         local max=$($LFS df | grep MDT |
19479                 awk 'BEGIN { a=0 }
19480                         { sub("%", "", $5)
19481                           if (0+$5 >= a)
19482                           {
19483                                 a = $5
19484                                 b = $6
19485                           }
19486                         }
19487                      END { split(b, c, ":")
19488                            sub("]", "", c[2])
19489                            print c[2]
19490                          }')
19491
19492         for i in $(seq $((MDSCOUNT - 1))); do
19493                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19494                         error "mkdir d$i failed"
19495                 $LFS getdirstripe $DIR/$tdir/d$i
19496                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19497                 [ $stripe_index -ne $max ] ||
19498                         error "don't expect $max"
19499         done
19500 }
19501 run_test 413 "mkdir on less full MDTs"
19502
19503 test_414() {
19504 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19505         $LCTL set_param fail_loc=0x80000521
19506         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19507         rm -f $DIR/$tfile
19508 }
19509 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19510
19511 test_415() {
19512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19513         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19514                 skip "Need server version at least 2.11.52"
19515
19516         # LU-11102
19517         local total
19518         local setattr_pid
19519         local start_time
19520         local end_time
19521         local duration
19522
19523         total=500
19524         # this test may be slow on ZFS
19525         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19526
19527         # though this test is designed for striped directory, let's test normal
19528         # directory too since lock is always saved as CoS lock.
19529         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19530         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19531
19532         (
19533                 while true; do
19534                         touch $DIR/$tdir
19535                 done
19536         ) &
19537         setattr_pid=$!
19538
19539         start_time=$(date +%s)
19540         for i in $(seq $total); do
19541                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19542                         > /dev/null
19543         done
19544         end_time=$(date +%s)
19545         duration=$((end_time - start_time))
19546
19547         kill -9 $setattr_pid
19548
19549         echo "rename $total files took $duration sec"
19550         [ $duration -lt 100 ] || error "rename took $duration sec"
19551 }
19552 run_test 415 "lock revoke is not missing"
19553
19554 test_416() {
19555         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19556                 skip "Need server version at least 2.11.55"
19557
19558         # define OBD_FAIL_OSD_TXN_START    0x19a
19559         do_facet mds1 lctl set_param fail_loc=0x19a
19560
19561         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19562
19563         true
19564 }
19565 run_test 416 "transaction start failure won't cause system hung"
19566
19567 cleanup_417() {
19568         trap 0
19569         do_nodes $(comma_list $(mdts_nodes)) \
19570                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19571         do_nodes $(comma_list $(mdts_nodes)) \
19572                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19573         do_nodes $(comma_list $(mdts_nodes)) \
19574                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19575 }
19576
19577 test_417() {
19578         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19579         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19580                 skip "Need MDS version at least 2.11.56"
19581
19582         trap cleanup_417 RETURN EXIT
19583
19584         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19585         do_nodes $(comma_list $(mdts_nodes)) \
19586                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19587         $LFS migrate -m 0 $DIR/$tdir.1 &&
19588                 error "migrate dir $tdir.1 should fail"
19589
19590         do_nodes $(comma_list $(mdts_nodes)) \
19591                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19592         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19593                 error "create remote dir $tdir.2 should fail"
19594
19595         do_nodes $(comma_list $(mdts_nodes)) \
19596                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19597         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19598                 error "create striped dir $tdir.3 should fail"
19599         true
19600 }
19601 run_test 417 "disable remote dir, striped dir and dir migration"
19602
19603 # Checks that the outputs of df [-i] and lfs df [-i] match
19604 #
19605 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19606 check_lfs_df() {
19607         local dir=$2
19608         local inodes
19609         local df_out
19610         local lfs_df_out
19611         local count
19612         local passed=false
19613
19614         # blocks or inodes
19615         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19616
19617         for count in {1..100}; do
19618                 cancel_lru_locks
19619                 sync; sleep 0.2
19620
19621                 # read the lines of interest
19622                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19623                         error "df $inodes $dir | tail -n +2 failed"
19624                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19625                         error "lfs df $inodes $dir | grep summary: failed"
19626
19627                 # skip first substrings of each output as they are different
19628                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19629                 # compare the two outputs
19630                 passed=true
19631                 for i in {1..5}; do
19632                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19633                 done
19634                 $passed && break
19635         done
19636
19637         if ! $passed; then
19638                 df -P $inodes $dir
19639                 echo
19640                 lfs df $inodes $dir
19641                 error "df and lfs df $1 output mismatch: "      \
19642                       "df ${inodes}: ${df_out[*]}, "            \
19643                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19644         fi
19645 }
19646
19647 test_418() {
19648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19649
19650         local dir=$DIR/$tdir
19651         local numfiles=$((RANDOM % 4096 + 2))
19652         local numblocks=$((RANDOM % 256 + 1))
19653
19654         wait_delete_completed
19655         test_mkdir $dir
19656
19657         # check block output
19658         check_lfs_df blocks $dir
19659         # check inode output
19660         check_lfs_df inodes $dir
19661
19662         # create a single file and retest
19663         echo "Creating a single file and testing"
19664         createmany -o $dir/$tfile- 1 &>/dev/null ||
19665                 error "creating 1 file in $dir failed"
19666         check_lfs_df blocks $dir
19667         check_lfs_df inodes $dir
19668
19669         # create a random number of files
19670         echo "Creating $((numfiles - 1)) files and testing"
19671         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19672                 error "creating $((numfiles - 1)) files in $dir failed"
19673
19674         # write a random number of blocks to the first test file
19675         echo "Writing $numblocks 4K blocks and testing"
19676         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19677                 count=$numblocks &>/dev/null ||
19678                 error "dd to $dir/${tfile}-0 failed"
19679
19680         # retest
19681         check_lfs_df blocks $dir
19682         check_lfs_df inodes $dir
19683
19684         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19685                 error "unlinking $numfiles files in $dir failed"
19686 }
19687 run_test 418 "df and lfs df outputs match"
19688
19689 test_419()
19690 {
19691         local dir=$DIR/$tdir
19692
19693         mkdir -p $dir
19694         touch $dir/file
19695
19696         cancel_lru_locks mdc
19697
19698         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19699         $LCTL set_param fail_loc=0x1410
19700         cat $dir/file
19701         $LCTL set_param fail_loc=0
19702         rm -rf $dir
19703 }
19704 run_test 419 "Verify open file by name doesn't crash kernel"
19705
19706 prep_801() {
19707         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19708         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19709                 skip "Need server version at least 2.9.55"
19710
19711         start_full_debug_logging
19712 }
19713
19714 post_801() {
19715         stop_full_debug_logging
19716 }
19717
19718 barrier_stat() {
19719         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19720                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19721                            awk '/The barrier for/ { print $7 }')
19722                 echo $st
19723         else
19724                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19725                 echo \'$st\'
19726         fi
19727 }
19728
19729 barrier_expired() {
19730         local expired
19731
19732         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19733                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19734                           awk '/will be expired/ { print $7 }')
19735         else
19736                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19737         fi
19738
19739         echo $expired
19740 }
19741
19742 test_801a() {
19743         prep_801
19744
19745         echo "Start barrier_freeze at: $(date)"
19746         #define OBD_FAIL_BARRIER_DELAY          0x2202
19747         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19748         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19749
19750         sleep 2
19751         local b_status=$(barrier_stat)
19752         echo "Got barrier status at: $(date)"
19753         [ "$b_status" = "'freezing_p1'" ] ||
19754                 error "(1) unexpected barrier status $b_status"
19755
19756         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19757         wait
19758         b_status=$(barrier_stat)
19759         [ "$b_status" = "'frozen'" ] ||
19760                 error "(2) unexpected barrier status $b_status"
19761
19762         local expired=$(barrier_expired)
19763         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19764         sleep $((expired + 3))
19765
19766         b_status=$(barrier_stat)
19767         [ "$b_status" = "'expired'" ] ||
19768                 error "(3) unexpected barrier status $b_status"
19769
19770         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19771                 error "(4) fail to freeze barrier"
19772
19773         b_status=$(barrier_stat)
19774         [ "$b_status" = "'frozen'" ] ||
19775                 error "(5) unexpected barrier status $b_status"
19776
19777         echo "Start barrier_thaw at: $(date)"
19778         #define OBD_FAIL_BARRIER_DELAY          0x2202
19779         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19780         do_facet mgs $LCTL barrier_thaw $FSNAME &
19781
19782         sleep 2
19783         b_status=$(barrier_stat)
19784         echo "Got barrier status at: $(date)"
19785         [ "$b_status" = "'thawing'" ] ||
19786                 error "(6) unexpected barrier status $b_status"
19787
19788         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19789         wait
19790         b_status=$(barrier_stat)
19791         [ "$b_status" = "'thawed'" ] ||
19792                 error "(7) unexpected barrier status $b_status"
19793
19794         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19795         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19796         do_facet mgs $LCTL barrier_freeze $FSNAME
19797
19798         b_status=$(barrier_stat)
19799         [ "$b_status" = "'failed'" ] ||
19800                 error "(8) unexpected barrier status $b_status"
19801
19802         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19803         do_facet mgs $LCTL barrier_thaw $FSNAME
19804
19805         post_801
19806 }
19807 run_test 801a "write barrier user interfaces and stat machine"
19808
19809 test_801b() {
19810         prep_801
19811
19812         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19813         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19814         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19815         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19816         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19817
19818         cancel_lru_locks mdc
19819
19820         # 180 seconds should be long enough
19821         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19822
19823         local b_status=$(barrier_stat)
19824         [ "$b_status" = "'frozen'" ] ||
19825                 error "(6) unexpected barrier status $b_status"
19826
19827         mkdir $DIR/$tdir/d0/d10 &
19828         mkdir_pid=$!
19829
19830         touch $DIR/$tdir/d1/f13 &
19831         touch_pid=$!
19832
19833         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19834         ln_pid=$!
19835
19836         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19837         mv_pid=$!
19838
19839         rm -f $DIR/$tdir/d4/f12 &
19840         rm_pid=$!
19841
19842         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19843
19844         # To guarantee taht the 'stat' is not blocked
19845         b_status=$(barrier_stat)
19846         [ "$b_status" = "'frozen'" ] ||
19847                 error "(8) unexpected barrier status $b_status"
19848
19849         # let above commands to run at background
19850         sleep 5
19851
19852         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19853         ps -p $touch_pid || error "(10) touch should be blocked"
19854         ps -p $ln_pid || error "(11) link should be blocked"
19855         ps -p $mv_pid || error "(12) rename should be blocked"
19856         ps -p $rm_pid || error "(13) unlink should be blocked"
19857
19858         b_status=$(barrier_stat)
19859         [ "$b_status" = "'frozen'" ] ||
19860                 error "(14) unexpected barrier status $b_status"
19861
19862         do_facet mgs $LCTL barrier_thaw $FSNAME
19863         b_status=$(barrier_stat)
19864         [ "$b_status" = "'thawed'" ] ||
19865                 error "(15) unexpected barrier status $b_status"
19866
19867         wait $mkdir_pid || error "(16) mkdir should succeed"
19868         wait $touch_pid || error "(17) touch should succeed"
19869         wait $ln_pid || error "(18) link should succeed"
19870         wait $mv_pid || error "(19) rename should succeed"
19871         wait $rm_pid || error "(20) unlink should succeed"
19872
19873         post_801
19874 }
19875 run_test 801b "modification will be blocked by write barrier"
19876
19877 test_801c() {
19878         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19879
19880         prep_801
19881
19882         stop mds2 || error "(1) Fail to stop mds2"
19883
19884         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19885
19886         local b_status=$(barrier_stat)
19887         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19888                 do_facet mgs $LCTL barrier_thaw $FSNAME
19889                 error "(2) unexpected barrier status $b_status"
19890         }
19891
19892         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19893                 error "(3) Fail to rescan barrier bitmap"
19894
19895         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19896
19897         b_status=$(barrier_stat)
19898         [ "$b_status" = "'frozen'" ] ||
19899                 error "(4) unexpected barrier status $b_status"
19900
19901         do_facet mgs $LCTL barrier_thaw $FSNAME
19902         b_status=$(barrier_stat)
19903         [ "$b_status" = "'thawed'" ] ||
19904                 error "(5) unexpected barrier status $b_status"
19905
19906         local devname=$(mdsdevname 2)
19907
19908         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19909
19910         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19911                 error "(7) Fail to rescan barrier bitmap"
19912
19913         post_801
19914 }
19915 run_test 801c "rescan barrier bitmap"
19916
19917 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19918 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19919 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19920
19921 cleanup_802a() {
19922         trap 0
19923
19924         stopall
19925         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19926         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19927         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19928         setupall
19929 }
19930
19931 test_802a() {
19932
19933         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19934         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19935                 skip "Need server version at least 2.9.55"
19936
19937         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19938
19939         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19940
19941         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19942                 error "(2) Fail to copy"
19943
19944         trap cleanup_802a EXIT
19945
19946         # sync by force before remount as readonly
19947         sync; sync_all_data; sleep 3; sync_all_data
19948
19949         stopall
19950
19951         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19952         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19953         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19954
19955         echo "Mount the server as read only"
19956         setupall server_only || error "(3) Fail to start servers"
19957
19958         echo "Mount client without ro should fail"
19959         mount_client $MOUNT &&
19960                 error "(4) Mount client without 'ro' should fail"
19961
19962         echo "Mount client with ro should succeed"
19963         mount_client $MOUNT ro ||
19964                 error "(5) Mount client with 'ro' should succeed"
19965
19966         echo "Modify should be refused"
19967         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19968
19969         echo "Read should be allowed"
19970         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19971                 error "(7) Read should succeed under ro mode"
19972
19973         cleanup_802a
19974 }
19975 run_test 802a "simulate readonly device"
19976
19977 test_802b() {
19978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19979         remote_mds_nodsh && skip "remote MDS with nodsh"
19980
19981         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19982                 skip "readonly option not available"
19983
19984         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19985
19986         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19987                 error "(2) Fail to copy"
19988
19989         # write back all cached data before setting MDT to readonly
19990         cancel_lru_locks
19991         sync_all_data
19992
19993         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19994         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
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         # disable readonly
20004         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20005 }
20006 run_test 802b "be able to set MDTs to readonly"
20007
20008 test_803() {
20009         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20010         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20011                 skip "MDS needs to be newer than 2.10.54"
20012
20013         mkdir -p $DIR/$tdir
20014         # Create some objects on all MDTs to trigger related logs objects
20015         for idx in $(seq $MDSCOUNT); do
20016                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20017                         $DIR/$tdir/dir${idx} ||
20018                         error "Fail to create $DIR/$tdir/dir${idx}"
20019         done
20020
20021         sync; sleep 3
20022         wait_delete_completed # ensure old test cleanups are finished
20023         echo "before create:"
20024         $LFS df -i $MOUNT
20025         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20026
20027         for i in {1..10}; do
20028                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20029                         error "Fail to create $DIR/$tdir/foo$i"
20030         done
20031
20032         sync; sleep 3
20033         echo "after create:"
20034         $LFS df -i $MOUNT
20035         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20036
20037         # allow for an llog to be cleaned up during the test
20038         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20039                 error "before ($before_used) + 10 > after ($after_used)"
20040
20041         for i in {1..10}; do
20042                 rm -rf $DIR/$tdir/foo$i ||
20043                         error "Fail to remove $DIR/$tdir/foo$i"
20044         done
20045
20046         sleep 3 # avoid MDT return cached statfs
20047         wait_delete_completed
20048         echo "after unlink:"
20049         $LFS df -i $MOUNT
20050         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20051
20052         # allow for an llog to be created during the test
20053         [ $after_used -le $((before_used + 1)) ] ||
20054                 error "after ($after_used) > before ($before_used) + 1"
20055 }
20056 run_test 803 "verify agent object for remote object"
20057
20058 test_804() {
20059         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20060         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20061                 skip "MDS needs to be newer than 2.10.54"
20062         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20063
20064         mkdir -p $DIR/$tdir
20065         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20066                 error "Fail to create $DIR/$tdir/dir0"
20067
20068         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20069         local dev=$(mdsdevname 2)
20070
20071         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20072                 grep ${fid} || error "NOT found agent entry for dir0"
20073
20074         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20075                 error "Fail to create $DIR/$tdir/dir1"
20076
20077         touch $DIR/$tdir/dir1/foo0 ||
20078                 error "Fail to create $DIR/$tdir/dir1/foo0"
20079         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20080         local rc=0
20081
20082         for idx in $(seq $MDSCOUNT); do
20083                 dev=$(mdsdevname $idx)
20084                 do_facet mds${idx} \
20085                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20086                         grep ${fid} && rc=$idx
20087         done
20088
20089         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20090                 error "Fail to rename foo0 to foo1"
20091         if [ $rc -eq 0 ]; then
20092                 for idx in $(seq $MDSCOUNT); do
20093                         dev=$(mdsdevname $idx)
20094                         do_facet mds${idx} \
20095                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20096                         grep ${fid} && rc=$idx
20097                 done
20098         fi
20099
20100         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20101                 error "Fail to rename foo1 to foo2"
20102         if [ $rc -eq 0 ]; then
20103                 for idx in $(seq $MDSCOUNT); do
20104                         dev=$(mdsdevname $idx)
20105                         do_facet mds${idx} \
20106                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20107                         grep ${fid} && rc=$idx
20108                 done
20109         fi
20110
20111         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20112
20113         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20114                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20115         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20116                 error "Fail to rename foo2 to foo0"
20117         unlink $DIR/$tdir/dir1/foo0 ||
20118                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20119         rm -rf $DIR/$tdir/dir0 ||
20120                 error "Fail to rm $DIR/$tdir/dir0"
20121
20122         for idx in $(seq $MDSCOUNT); do
20123                 dev=$(mdsdevname $idx)
20124                 rc=0
20125
20126                 stop mds${idx}
20127                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20128                         rc=$?
20129                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20130                         error "mount mds$idx failed"
20131                 df $MOUNT > /dev/null 2>&1
20132
20133                 # e2fsck should not return error
20134                 [ $rc -eq 0 ] ||
20135                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20136         done
20137 }
20138 run_test 804 "verify agent entry for remote entry"
20139
20140 cleanup_805() {
20141         do_facet $SINGLEMDS zfs set quota=$old $fsset
20142         unlinkmany $DIR/$tdir/f- 1000000
20143         trap 0
20144 }
20145
20146 test_805() {
20147         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20148         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20149         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20150                 skip "netfree not implemented before 0.7"
20151         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20152                 skip "Need MDS version at least 2.10.57"
20153
20154         local fsset
20155         local freekb
20156         local usedkb
20157         local old
20158         local quota
20159         local pref="osd-zfs.lustre-MDT0000."
20160
20161         # limit available space on MDS dataset to meet nospace issue
20162         # quickly. then ZFS 0.7.2 can use reserved space if asked
20163         # properly (using netfree flag in osd_declare_destroy()
20164         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20165         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20166                 gawk '{print $3}')
20167         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20168         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20169         let "usedkb=usedkb-freekb"
20170         let "freekb=freekb/2"
20171         if let "freekb > 5000"; then
20172                 let "freekb=5000"
20173         fi
20174         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20175         trap cleanup_805 EXIT
20176         mkdir $DIR/$tdir
20177         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20178         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20179         rm -rf $DIR/$tdir || error "not able to remove"
20180         do_facet $SINGLEMDS zfs set quota=$old $fsset
20181         trap 0
20182 }
20183 run_test 805 "ZFS can remove from full fs"
20184
20185 # Size-on-MDS test
20186 check_lsom_data()
20187 {
20188         local file=$1
20189         local size=$($LFS getsom -s $file)
20190         local expect=$(stat -c %s $file)
20191
20192         [[ $size == $expect ]] ||
20193                 error "$file expected size: $expect, got: $size"
20194
20195         local blocks=$($LFS getsom -b $file)
20196         expect=$(stat -c %b $file)
20197         [[ $blocks == $expect ]] ||
20198                 error "$file expected blocks: $expect, got: $blocks"
20199 }
20200
20201 check_lsom_size()
20202 {
20203         local size=$($LFS getsom -s $1)
20204         local expect=$2
20205
20206         [[ $size == $expect ]] ||
20207                 error "$file expected size: $expect, got: $size"
20208 }
20209
20210 test_806() {
20211         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20212                 skip "Need MDS version at least 2.11.52"
20213
20214         local bs=1048576
20215
20216         touch $DIR/$tfile || error "touch $tfile failed"
20217
20218         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20219         save_lustre_params client "llite.*.xattr_cache" > $save
20220         lctl set_param llite.*.xattr_cache=0
20221         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20222
20223         # single-threaded write
20224         echo "Test SOM for single-threaded write"
20225         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20226                 error "write $tfile failed"
20227         check_lsom_size $DIR/$tfile $bs
20228
20229         local num=32
20230         local size=$(($num * $bs))
20231         local offset=0
20232         local i
20233
20234         echo "Test SOM for single client multi-threaded($num) write"
20235         $TRUNCATE $DIR/$tfile 0
20236         for ((i = 0; i < $num; i++)); do
20237                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20238                 local pids[$i]=$!
20239                 offset=$((offset + $bs))
20240         done
20241         for (( i=0; i < $num; i++ )); do
20242                 wait ${pids[$i]}
20243         done
20244         check_lsom_size $DIR/$tfile $size
20245
20246         $TRUNCATE $DIR/$tfile 0
20247         for ((i = 0; i < $num; i++)); do
20248                 offset=$((offset - $bs))
20249                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20250                 local pids[$i]=$!
20251         done
20252         for (( i=0; i < $num; i++ )); do
20253                 wait ${pids[$i]}
20254         done
20255         check_lsom_size $DIR/$tfile $size
20256
20257         # multi-client wirtes
20258         num=$(get_node_count ${CLIENTS//,/ })
20259         size=$(($num * $bs))
20260         offset=0
20261         i=0
20262
20263         echo "Test SOM for multi-client ($num) writes"
20264         $TRUNCATE $DIR/$tfile 0
20265         for client in ${CLIENTS//,/ }; do
20266                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20267                 local pids[$i]=$!
20268                 i=$((i + 1))
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 $offset
20275
20276         i=0
20277         $TRUNCATE $DIR/$tfile 0
20278         for client in ${CLIENTS//,/ }; do
20279                 offset=$((offset - $bs))
20280                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20281                 local pids[$i]=$!
20282                 i=$((i + 1))
20283         done
20284         for (( i=0; i < $num; i++ )); do
20285                 wait ${pids[$i]}
20286         done
20287         check_lsom_size $DIR/$tfile $size
20288
20289         # verify truncate
20290         echo "Test SOM for truncate"
20291         $TRUNCATE $DIR/$tfile 1048576
20292         check_lsom_size $DIR/$tfile 1048576
20293         $TRUNCATE $DIR/$tfile 1234
20294         check_lsom_size $DIR/$tfile 1234
20295
20296         # verify SOM blocks count
20297         echo "Verify SOM block count"
20298         $TRUNCATE $DIR/$tfile 0
20299         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20300                 error "failed to write file $tfile"
20301         check_lsom_data $DIR/$tfile
20302 }
20303 run_test 806 "Verify Lazy Size on MDS"
20304
20305 test_807() {
20306         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20307         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20308                 skip "Need MDS version at least 2.11.52"
20309
20310         # Registration step
20311         changelog_register || error "changelog_register failed"
20312         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20313         changelog_users $SINGLEMDS | grep -q $cl_user ||
20314                 error "User $cl_user not found in changelog_users"
20315
20316         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20317         save_lustre_params client "llite.*.xattr_cache" > $save
20318         lctl set_param llite.*.xattr_cache=0
20319         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20320
20321         rm -rf $DIR/$tdir || error "rm $tdir failed"
20322         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20323         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20324         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20325         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20326                 error "truncate $tdir/trunc failed"
20327
20328         local bs=1048576
20329         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20330                 error "write $tfile failed"
20331
20332         # multi-client wirtes
20333         local num=$(get_node_count ${CLIENTS//,/ })
20334         local offset=0
20335         local i=0
20336
20337         echo "Test SOM for multi-client ($num) writes"
20338         touch $DIR/$tfile || error "touch $tfile failed"
20339         $TRUNCATE $DIR/$tfile 0
20340         for client in ${CLIENTS//,/ }; do
20341                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20342                 local pids[$i]=$!
20343                 i=$((i + 1))
20344                 offset=$((offset + $bs))
20345         done
20346         for (( i=0; i < $num; i++ )); do
20347                 wait ${pids[$i]}
20348         done
20349
20350         sleep 5
20351         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20352         check_lsom_data $DIR/$tdir/trunc
20353         check_lsom_data $DIR/$tdir/single_dd
20354         check_lsom_data $DIR/$tfile
20355
20356         rm -rf $DIR/$tdir
20357         # Deregistration step
20358         changelog_deregister || error "changelog_deregister failed"
20359 }
20360 run_test 807 "verify LSOM syncing tool"
20361
20362 check_som_nologged()
20363 {
20364         local lines=$($LFS changelog $FSNAME-MDT0000 |
20365                 grep 'x=trusted.som' | wc -l)
20366         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20367 }
20368
20369 test_808() {
20370         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20371                 skip "Need MDS version at least 2.11.55"
20372
20373         # Registration step
20374         changelog_register || error "changelog_register failed"
20375
20376         touch $DIR/$tfile || error "touch $tfile failed"
20377         check_som_nologged
20378
20379         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20380                 error "write $tfile failed"
20381         check_som_nologged
20382
20383         $TRUNCATE $DIR/$tfile 1234
20384         check_som_nologged
20385
20386         $TRUNCATE $DIR/$tfile 1048576
20387         check_som_nologged
20388
20389         # Deregistration step
20390         changelog_deregister || error "changelog_deregister failed"
20391 }
20392 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20393
20394 check_som_nodata()
20395 {
20396         $LFS getsom $1
20397         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20398 }
20399
20400 test_809() {
20401         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20402                 skip "Need MDS version at least 2.11.56"
20403
20404         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20405                 error "failed to create DoM-only file $DIR/$tfile"
20406         touch $DIR/$tfile || error "touch $tfile failed"
20407         check_som_nodata $DIR/$tfile
20408
20409         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20410                 error "write $tfile failed"
20411         check_som_nodata $DIR/$tfile
20412
20413         $TRUNCATE $DIR/$tfile 1234
20414         check_som_nodata $DIR/$tfile
20415
20416         $TRUNCATE $DIR/$tfile 4097
20417         check_som_nodata $DIR/$file
20418 }
20419 run_test 809 "Verify no SOM xattr store for DoM-only files"
20420
20421 test_810() {
20422         local ORIG
20423         local CSUM
20424
20425         # t10 seem to dislike partial pages
20426         lctl set_param osc.*.checksum_type=adler
20427         lctl set_param fail_loc=0x411
20428         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20429         ORIG=$(md5sum $DIR/$tfile)
20430         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20431         CSUM=$(md5sum $DIR/$tfile)
20432         set_checksum_type adler
20433         if [ "$ORIG" != "$CSUM" ]; then
20434                 error "$ORIG != $CSUM"
20435         fi
20436 }
20437 run_test 810 "partial page writes on ZFS (LU-11663)"
20438
20439 test_811() {
20440         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20441                 skip "Need MDS version at least 2.11.56"
20442
20443         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20444         do_facet mds1 $LCTL set_param fail_loc=0x165
20445         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20446
20447         stop mds1
20448         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20449
20450         sleep 5
20451         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20452                 error "MDD orphan cleanup thread not quit"
20453 }
20454 run_test 811 "orphan name stub can be cleaned up in startup"
20455
20456 test_812() {
20457         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20458                 skip "OST < 2.12.51 doesn't support this fail_loc"
20459
20460         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20461         # ensure ost1 is connected
20462         stat $DIR/$tfile >/dev/null || error "can't stat"
20463         wait_osc_import_state client ost1 FULL
20464         # no locks, no reqs to let the connection idle
20465         cancel_lru_locks osc
20466
20467         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20468 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20469         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20470         wait_osc_import_state client ost1 CONNECTING
20471         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20472
20473         stat $DIR/$tfile >/dev/null || error "can't stat file"
20474 }
20475 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20476
20477 test_813() {
20478         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20479         [ -z "$file_heat_sav" ] && skip "no file heat support"
20480
20481         local readsample
20482         local writesample
20483         local readbyte
20484         local writebyte
20485         local readsample1
20486         local writesample1
20487         local readbyte1
20488         local writebyte1
20489
20490         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20491         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20492
20493         $LCTL set_param -n llite.*.file_heat=1
20494         echo "Turn on file heat"
20495         echo "Period second: $period_second, Decay percentage: $decay_pct"
20496
20497         echo "QQQQ" > $DIR/$tfile
20498         echo "QQQQ" > $DIR/$tfile
20499         echo "QQQQ" > $DIR/$tfile
20500         cat $DIR/$tfile > /dev/null
20501         cat $DIR/$tfile > /dev/null
20502         cat $DIR/$tfile > /dev/null
20503         cat $DIR/$tfile > /dev/null
20504
20505         local out=$($LFS heat_get $DIR/$tfile)
20506
20507         $LFS heat_get $DIR/$tfile
20508         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20509         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20510         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20511         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20512
20513         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20514         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20515         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20516         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20517
20518         sleep $((period_second + 3))
20519         echo "Sleep $((period_second + 3)) seconds..."
20520         # The recursion formula to calculate the heat of the file f is as
20521         # follow:
20522         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20523         # Where Hi is the heat value in the period between time points i*I and
20524         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20525         # to the weight of Ci.
20526         out=$($LFS heat_get $DIR/$tfile)
20527         $LFS heat_get $DIR/$tfile
20528         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20529         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20530         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20531         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20532
20533         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20534                 error "read sample ($readsample) is wrong"
20535         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20536                 error "write sample ($writesample) is wrong"
20537         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20538                 error "read bytes ($readbyte) is wrong"
20539         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20540                 error "write bytes ($writebyte) is wrong"
20541
20542         echo "QQQQ" > $DIR/$tfile
20543         echo "QQQQ" > $DIR/$tfile
20544         echo "QQQQ" > $DIR/$tfile
20545         cat $DIR/$tfile > /dev/null
20546         cat $DIR/$tfile > /dev/null
20547         cat $DIR/$tfile > /dev/null
20548         cat $DIR/$tfile > /dev/null
20549
20550         sleep $((period_second + 3))
20551         echo "Sleep $((period_second + 3)) seconds..."
20552
20553         out=$($LFS heat_get $DIR/$tfile)
20554         $LFS heat_get $DIR/$tfile
20555         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20556         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20557         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20558         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20559
20560         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20561                 4 * $decay_pct) / 100") -eq 1 ] ||
20562                 error "read sample ($readsample1) is wrong"
20563         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20564                 3 * $decay_pct) / 100") -eq 1 ] ||
20565                 error "write sample ($writesample1) is wrong"
20566         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20567                 20 * $decay_pct) / 100") -eq 1 ] ||
20568                 error "read bytes ($readbyte1) is wrong"
20569         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20570                 15 * $decay_pct) / 100") -eq 1 ] ||
20571                 error "write bytes ($writebyte1) is wrong"
20572
20573         echo "Turn off file heat for the file $DIR/$tfile"
20574         $LFS heat_set -o $DIR/$tfile
20575
20576         echo "QQQQ" > $DIR/$tfile
20577         echo "QQQQ" > $DIR/$tfile
20578         echo "QQQQ" > $DIR/$tfile
20579         cat $DIR/$tfile > /dev/null
20580         cat $DIR/$tfile > /dev/null
20581         cat $DIR/$tfile > /dev/null
20582         cat $DIR/$tfile > /dev/null
20583
20584         out=$($LFS heat_get $DIR/$tfile)
20585         $LFS heat_get $DIR/$tfile
20586         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20587         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20588         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20589         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20590
20591         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20592         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20593         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20594         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20595
20596         echo "Trun on file heat for the file $DIR/$tfile"
20597         $LFS heat_set -O $DIR/$tfile
20598
20599         echo "QQQQ" > $DIR/$tfile
20600         echo "QQQQ" > $DIR/$tfile
20601         echo "QQQQ" > $DIR/$tfile
20602         cat $DIR/$tfile > /dev/null
20603         cat $DIR/$tfile > /dev/null
20604         cat $DIR/$tfile > /dev/null
20605         cat $DIR/$tfile > /dev/null
20606
20607         out=$($LFS heat_get $DIR/$tfile)
20608         $LFS heat_get $DIR/$tfile
20609         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20610         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20611         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20612         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20613
20614         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20615         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20616         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20617         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20618
20619         $LFS heat_set -c $DIR/$tfile
20620         $LCTL set_param -n llite.*.file_heat=0
20621         echo "Turn off file heat support for the Lustre filesystem"
20622
20623         echo "QQQQ" > $DIR/$tfile
20624         echo "QQQQ" > $DIR/$tfile
20625         echo "QQQQ" > $DIR/$tfile
20626         cat $DIR/$tfile > /dev/null
20627         cat $DIR/$tfile > /dev/null
20628         cat $DIR/$tfile > /dev/null
20629         cat $DIR/$tfile > /dev/null
20630
20631         out=$($LFS heat_get $DIR/$tfile)
20632         $LFS heat_get $DIR/$tfile
20633         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20634         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20635         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20636         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20637
20638         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20639         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20640         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20641         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20642
20643         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20644         rm -f $DIR/$tfile
20645 }
20646 run_test 813 "File heat verfication"
20647
20648 #
20649 # tests that do cleanup/setup should be run at the end
20650 #
20651
20652 test_900() {
20653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20654         local ls
20655
20656         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20657         $LCTL set_param fail_loc=0x903
20658
20659         cancel_lru_locks MGC
20660
20661         FAIL_ON_ERROR=true cleanup
20662         FAIL_ON_ERROR=true setup
20663 }
20664 run_test 900 "umount should not race with any mgc requeue thread"
20665
20666 complete $SECONDS
20667 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20668 check_and_cleanup_lustre
20669 if [ "$I_MOUNTED" != "yes" ]; then
20670         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20671 fi
20672 exit_status