Whamcloud - gitweb
4f302fe1e307414f40c87f8624064d00ee80594d
[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" -o -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles -o $num_uniq -ne $nrfiles -o \
1190              $num_all -ne $((nrfiles + 2)) ]; then
1191                 error "Expected $nrfiles files, got $num_ls " \
1192                         "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_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 -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
1328                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1329         fi
1330
1331         simple_cleanup_common || error "Can not delete directories"
1332 }
1333 run_test 24A "readdir() returns correct number of entries."
1334
1335 test_24B() { # LU-4805
1336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1337
1338         local count
1339
1340         test_mkdir $DIR/$tdir
1341         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1342                 error "create striped dir failed"
1343
1344         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1345         [ $count -eq 2 ] || error "Expected 2, got $count"
1346
1347         touch $DIR/$tdir/striped_dir/a
1348
1349         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1350         [ $count -eq 3 ] || error "Expected 3, got $count"
1351
1352         touch $DIR/$tdir/striped_dir/.f
1353
1354         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1355         [ $count -eq 4 ] || error "Expected 4, got $count"
1356
1357         rm -rf $DIR/$tdir || error "Can not delete directories"
1358 }
1359 run_test 24B "readdir for striped dir return correct number of entries"
1360
1361 test_24C() {
1362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1363
1364         mkdir $DIR/$tdir
1365         mkdir $DIR/$tdir/d0
1366         mkdir $DIR/$tdir/d1
1367
1368         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1369                 error "create striped dir failed"
1370
1371         cd $DIR/$tdir/d0/striped_dir
1372
1373         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1374         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1375         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1376
1377         [ "$d0_ino" = "$parent_ino" ] ||
1378                 error ".. wrong, expect $d0_ino, get $parent_ino"
1379
1380         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1381                 error "mv striped dir failed"
1382
1383         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1384
1385         [ "$d1_ino" = "$parent_ino" ] ||
1386                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1387 }
1388 run_test 24C "check .. in striped dir"
1389
1390 test_24E() {
1391         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1393
1394         mkdir -p $DIR/$tdir
1395         mkdir $DIR/$tdir/src_dir
1396         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1397                 error "create remote source failed"
1398
1399         touch $DIR/$tdir/src_dir/src_child/a
1400
1401         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1402                 error "create remote target dir failed"
1403
1404         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1405                 error "create remote target child failed"
1406
1407         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1408                 error "rename dir cross MDT failed!"
1409
1410         find $DIR/$tdir
1411
1412         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1413                 error "src_child still exists after rename"
1414
1415         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1416                 error "missing file(a) after rename"
1417
1418         rm -rf $DIR/$tdir || error "Can not delete directories"
1419 }
1420 run_test 24E "cross MDT rename/link"
1421
1422 test_24F () {
1423         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1424
1425         local repeats=1000
1426         [ "$SLOW" = "no" ] && repeats=100
1427
1428         mkdir -p $DIR/$tdir
1429
1430         echo "$repeats repeats"
1431         for ((i = 0; i < repeats; i++)); do
1432                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1433                 touch $DIR/$tdir/test/a || error "touch fails"
1434                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1435                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1436         done
1437
1438         true
1439 }
1440 run_test 24F "hash order vs readdir (LU-11330)"
1441
1442 test_25a() {
1443         echo '== symlink sanity ============================================='
1444
1445         test_mkdir $DIR/d25
1446         ln -s d25 $DIR/s25
1447         touch $DIR/s25/foo ||
1448                 error "File creation in symlinked directory failed"
1449 }
1450 run_test 25a "create file in symlinked directory ==============="
1451
1452 test_25b() {
1453         [ ! -d $DIR/d25 ] && test_25a
1454         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1455 }
1456 run_test 25b "lookup file in symlinked directory ==============="
1457
1458 test_26a() {
1459         test_mkdir $DIR/d26
1460         test_mkdir $DIR/d26/d26-2
1461         ln -s d26/d26-2 $DIR/s26
1462         touch $DIR/s26/foo || error "File creation failed"
1463 }
1464 run_test 26a "multiple component symlink ======================="
1465
1466 test_26b() {
1467         test_mkdir -p $DIR/$tdir/d26-2
1468         ln -s $tdir/d26-2/foo $DIR/s26-2
1469         touch $DIR/s26-2 || error "File creation failed"
1470 }
1471 run_test 26b "multiple component symlink at end of lookup ======"
1472
1473 test_26c() {
1474         test_mkdir $DIR/d26.2
1475         touch $DIR/d26.2/foo
1476         ln -s d26.2 $DIR/s26.2-1
1477         ln -s s26.2-1 $DIR/s26.2-2
1478         ln -s s26.2-2 $DIR/s26.2-3
1479         chmod 0666 $DIR/s26.2-3/foo
1480 }
1481 run_test 26c "chain of symlinks"
1482
1483 # recursive symlinks (bug 439)
1484 test_26d() {
1485         ln -s d26-3/foo $DIR/d26-3
1486 }
1487 run_test 26d "create multiple component recursive symlink"
1488
1489 test_26e() {
1490         [ ! -h $DIR/d26-3 ] && test_26d
1491         rm $DIR/d26-3
1492 }
1493 run_test 26e "unlink multiple component recursive symlink"
1494
1495 # recursive symlinks (bug 7022)
1496 test_26f() {
1497         test_mkdir $DIR/$tdir
1498         test_mkdir $DIR/$tdir/$tfile
1499         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1500         test_mkdir -p lndir/bar1
1501         test_mkdir $DIR/$tdir/$tfile/$tfile
1502         cd $tfile                || error "cd $tfile failed"
1503         ln -s .. dotdot          || error "ln dotdot failed"
1504         ln -s dotdot/lndir lndir || error "ln lndir failed"
1505         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1506         output=`ls $tfile/$tfile/lndir/bar1`
1507         [ "$output" = bar1 ] && error "unexpected output"
1508         rm -r $tfile             || error "rm $tfile failed"
1509         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1510 }
1511 run_test 26f "rm -r of a directory which has recursive symlink"
1512
1513 test_27a() {
1514         test_mkdir $DIR/$tdir
1515         $LFS getstripe $DIR/$tdir
1516         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1517         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1518         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1519 }
1520 run_test 27a "one stripe file"
1521
1522 test_27b() {
1523         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1524
1525         test_mkdir $DIR/$tdir
1526         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1527         $LFS getstripe -c $DIR/$tdir/$tfile
1528         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1529                 error "two-stripe file doesn't have two stripes"
1530
1531         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1532 }
1533 run_test 27b "create and write to two stripe file"
1534
1535 test_27d() {
1536         test_mkdir $DIR/$tdir
1537         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1538                 error "setstripe failed"
1539         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1540         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1541 }
1542 run_test 27d "create file with default settings"
1543
1544 test_27e() {
1545         # LU-5839 adds check for existed layout before setting it
1546         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1547                 skip "Need MDS version at least 2.7.56"
1548
1549         test_mkdir $DIR/$tdir
1550         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1552         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1553 }
1554 run_test 27e "setstripe existing file (should return error)"
1555
1556 test_27f() {
1557         test_mkdir $DIR/$tdir
1558         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1559                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1560         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1561                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1563         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1564 }
1565 run_test 27f "setstripe with bad stripe size (should return error)"
1566
1567 test_27g() {
1568         test_mkdir $DIR/$tdir
1569         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1571                 error "$DIR/$tdir/$tfile has object"
1572 }
1573 run_test 27g "$LFS getstripe with no objects"
1574
1575 test_27i() {
1576         test_mkdir $DIR/$tdir
1577         touch $DIR/$tdir/$tfile || error "touch failed"
1578         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1579                 error "missing objects"
1580 }
1581 run_test 27i "$LFS getstripe with some objects"
1582
1583 test_27j() {
1584         test_mkdir $DIR/$tdir
1585         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1586                 error "setstripe failed" || true
1587 }
1588 run_test 27j "setstripe with bad stripe offset (should return error)"
1589
1590 test_27k() { # bug 2844
1591         test_mkdir $DIR/$tdir
1592         local file=$DIR/$tdir/$tfile
1593         local ll_max_blksize=$((4 * 1024 * 1024))
1594         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1595         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1596         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1597         dd if=/dev/zero of=$file bs=4k count=1
1598         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1599         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1600 }
1601 run_test 27k "limit i_blksize for broken user apps"
1602
1603 test_27l() {
1604         mcreate $DIR/$tfile || error "creating file"
1605         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1606                 error "setstripe should have failed" || true
1607 }
1608 run_test 27l "check setstripe permissions (should return error)"
1609
1610 test_27m() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1612
1613         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1614                    head -n1)
1615         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1616                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1617         fi
1618         trap simple_cleanup_common EXIT
1619         test_mkdir $DIR/$tdir
1620         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1622                 error "dd should fill OST0"
1623         i=2
1624         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1625                 i=$((i + 1))
1626                 [ $i -gt 256 ] && break
1627         done
1628         i=$((i + 1))
1629         touch $DIR/$tdir/$tfile.$i
1630         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1631             awk '{print $1}'| grep -w "0") ] &&
1632                 error "OST0 was full but new created file still use it"
1633         i=$((i + 1))
1634         touch $DIR/$tdir/$tfile.$i
1635         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1636             awk '{print $1}'| grep -w "0") ] &&
1637                 error "OST0 was full but new created file still use it"
1638         simple_cleanup_common
1639 }
1640 run_test 27m "create file while OST0 was full"
1641
1642 sleep_maxage() {
1643         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1644                       awk '{ print $1 * 2; exit; }')
1645         sleep $delay
1646 }
1647
1648 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1649 # if the OST isn't full anymore.
1650 reset_enospc() {
1651         local OSTIDX=${1:-""}
1652
1653         local list=$(comma_list $(osts_nodes))
1654         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1655
1656         do_nodes $list lctl set_param fail_loc=0
1657         sync    # initiate all OST_DESTROYs from MDS to OST
1658         sleep_maxage
1659 }
1660
1661 exhaust_precreations() {
1662         local OSTIDX=$1
1663         local FAILLOC=$2
1664         local FAILIDX=${3:-$OSTIDX}
1665         local ofacet=ost$((OSTIDX + 1))
1666
1667         test_mkdir -p -c1 $DIR/$tdir
1668         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1669         local mfacet=mds$((mdtidx + 1))
1670         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1671
1672         local OST=$(ostname_from_index $OSTIDX)
1673
1674         # on the mdt's osc
1675         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1676         local last_id=$(do_facet $mfacet lctl get_param -n \
1677                         osc.$mdtosc_proc1.prealloc_last_id)
1678         local next_id=$(do_facet $mfacet lctl get_param -n \
1679                         osc.$mdtosc_proc1.prealloc_next_id)
1680
1681         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1682         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1683
1684         test_mkdir -p $DIR/$tdir/${OST}
1685         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1686 #define OBD_FAIL_OST_ENOSPC              0x215
1687         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1688         echo "Creating to objid $last_id on ost $OST..."
1689         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1690         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1691         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1692         sleep_maxage
1693 }
1694
1695 exhaust_all_precreations() {
1696         local i
1697         for (( i=0; i < OSTCOUNT; i++ )) ; do
1698                 exhaust_precreations $i $1 -1
1699         done
1700 }
1701
1702 test_27n() {
1703         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1705         remote_mds_nodsh && skip "remote MDS with nodsh"
1706         remote_ost_nodsh && skip "remote OST with nodsh"
1707
1708         reset_enospc
1709         rm -f $DIR/$tdir/$tfile
1710         exhaust_precreations 0 0x80000215
1711         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1712         touch $DIR/$tdir/$tfile || error "touch failed"
1713         $LFS getstripe $DIR/$tdir/$tfile
1714         reset_enospc
1715 }
1716 run_test 27n "create file with some full OSTs"
1717
1718 test_27o() {
1719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1721         remote_mds_nodsh && skip "remote MDS with nodsh"
1722         remote_ost_nodsh && skip "remote OST with nodsh"
1723
1724         reset_enospc
1725         rm -f $DIR/$tdir/$tfile
1726         exhaust_all_precreations 0x215
1727
1728         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1729
1730         reset_enospc
1731         rm -rf $DIR/$tdir/*
1732 }
1733 run_test 27o "create file with all full OSTs (should error)"
1734
1735 test_27p() {
1736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1738         remote_mds_nodsh && skip "remote MDS with nodsh"
1739         remote_ost_nodsh && skip "remote OST with nodsh"
1740
1741         reset_enospc
1742         rm -f $DIR/$tdir/$tfile
1743         test_mkdir $DIR/$tdir
1744
1745         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1746         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1747         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1748
1749         exhaust_precreations 0 0x80000215
1750         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1751         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1752         $LFS getstripe $DIR/$tdir/$tfile
1753
1754         reset_enospc
1755 }
1756 run_test 27p "append to a truncated file with some full OSTs"
1757
1758 test_27q() {
1759         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1761         remote_mds_nodsh && skip "remote MDS with nodsh"
1762         remote_ost_nodsh && skip "remote OST with nodsh"
1763
1764         reset_enospc
1765         rm -f $DIR/$tdir/$tfile
1766
1767         test_mkdir $DIR/$tdir
1768         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1769         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1770                 error "truncate $DIR/$tdir/$tfile failed"
1771         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1772
1773         exhaust_all_precreations 0x215
1774
1775         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1776         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1777
1778         reset_enospc
1779 }
1780 run_test 27q "append to truncated file with all OSTs full (should error)"
1781
1782 test_27r() {
1783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1785         remote_mds_nodsh && skip "remote MDS with nodsh"
1786         remote_ost_nodsh && skip "remote OST with nodsh"
1787
1788         reset_enospc
1789         rm -f $DIR/$tdir/$tfile
1790         exhaust_precreations 0 0x80000215
1791
1792         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1793
1794         reset_enospc
1795 }
1796 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1797
1798 test_27s() { # bug 10725
1799         test_mkdir $DIR/$tdir
1800         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1801         local stripe_count=0
1802         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1803         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1804                 error "stripe width >= 2^32 succeeded" || true
1805
1806 }
1807 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1808
1809 test_27t() { # bug 10864
1810         WDIR=$(pwd)
1811         WLFS=$(which lfs)
1812         cd $DIR
1813         touch $tfile
1814         $WLFS getstripe $tfile
1815         cd $WDIR
1816 }
1817 run_test 27t "check that utils parse path correctly"
1818
1819 test_27u() { # bug 4900
1820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1821         remote_mds_nodsh && skip "remote MDS with nodsh"
1822
1823         local index
1824         local list=$(comma_list $(mdts_nodes))
1825
1826 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1827         do_nodes $list $LCTL set_param fail_loc=0x139
1828         test_mkdir -p $DIR/$tdir
1829         trap simple_cleanup_common EXIT
1830         createmany -o $DIR/$tdir/t- 1000
1831         do_nodes $list $LCTL set_param fail_loc=0
1832
1833         TLOG=$TMP/$tfile.getstripe
1834         $LFS getstripe $DIR/$tdir > $TLOG
1835         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1836         unlinkmany $DIR/$tdir/t- 1000
1837         trap 0
1838         [[ $OBJS -gt 0 ]] &&
1839                 error "$OBJS objects created on OST-0. See $TLOG" ||
1840                 rm -f $TLOG
1841 }
1842 run_test 27u "skip object creation on OSC w/o objects"
1843
1844 test_27v() { # bug 4900
1845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1847         remote_mds_nodsh && skip "remote MDS with nodsh"
1848         remote_ost_nodsh && skip "remote OST with nodsh"
1849
1850         exhaust_all_precreations 0x215
1851         reset_enospc
1852
1853         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1854
1855         touch $DIR/$tdir/$tfile
1856         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1857         # all except ost1
1858         for (( i=1; i < OSTCOUNT; i++ )); do
1859                 do_facet ost$i lctl set_param fail_loc=0x705
1860         done
1861         local START=`date +%s`
1862         createmany -o $DIR/$tdir/$tfile 32
1863
1864         local FINISH=`date +%s`
1865         local TIMEOUT=`lctl get_param -n timeout`
1866         local PROCESS=$((FINISH - START))
1867         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1868                error "$FINISH - $START >= $TIMEOUT / 2"
1869         sleep $((TIMEOUT / 2 - PROCESS))
1870         reset_enospc
1871 }
1872 run_test 27v "skip object creation on slow OST"
1873
1874 test_27w() { # bug 10997
1875         test_mkdir $DIR/$tdir
1876         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1877         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1878                 error "stripe size $size != 65536" || true
1879         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1880                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1881 }
1882 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1883
1884 test_27wa() {
1885         [[ $OSTCOUNT -lt 2 ]] &&
1886                 skip_env "skipping multiple stripe count/offset test"
1887
1888         test_mkdir $DIR/$tdir
1889         for i in $(seq 1 $OSTCOUNT); do
1890                 offset=$((i - 1))
1891                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1892                         error "setstripe -c $i -i $offset failed"
1893                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1894                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1895                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1896                 [ $index -ne $offset ] &&
1897                         error "stripe offset $index != $offset" || true
1898         done
1899 }
1900 run_test 27wa "check $LFS setstripe -c -i options"
1901
1902 test_27x() {
1903         remote_ost_nodsh && skip "remote OST with nodsh"
1904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1906
1907         OFFSET=$(($OSTCOUNT - 1))
1908         OSTIDX=0
1909         local OST=$(ostname_from_index $OSTIDX)
1910
1911         test_mkdir $DIR/$tdir
1912         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1913         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1914         sleep_maxage
1915         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1916         for i in $(seq 0 $OFFSET); do
1917                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1918                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1919                 error "OST0 was degraded but new created file still use it"
1920         done
1921         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1922 }
1923 run_test 27x "create files while OST0 is degraded"
1924
1925 test_27y() {
1926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1927         remote_mds_nodsh && skip "remote MDS with nodsh"
1928         remote_ost_nodsh && skip "remote OST with nodsh"
1929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1930
1931         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1932         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1933                 osc.$mdtosc.prealloc_last_id)
1934         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1935                 osc.$mdtosc.prealloc_next_id)
1936         local fcount=$((last_id - next_id))
1937         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1938         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1939
1940         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1941                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1942         local OST_DEACTIVE_IDX=-1
1943         local OSC
1944         local OSTIDX
1945         local OST
1946
1947         for OSC in $MDS_OSCS; do
1948                 OST=$(osc_to_ost $OSC)
1949                 OSTIDX=$(index_from_ostuuid $OST)
1950                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1951                         OST_DEACTIVE_IDX=$OSTIDX
1952                 fi
1953                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1954                         echo $OSC "is Deactivated:"
1955                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1956                 fi
1957         done
1958
1959         OSTIDX=$(index_from_ostuuid $OST)
1960         test_mkdir $DIR/$tdir
1961         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1962
1963         for OSC in $MDS_OSCS; do
1964                 OST=$(osc_to_ost $OSC)
1965                 OSTIDX=$(index_from_ostuuid $OST)
1966                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1967                         echo $OST "is degraded:"
1968                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1969                                                 obdfilter.$OST.degraded=1
1970                 fi
1971         done
1972
1973         sleep_maxage
1974         createmany -o $DIR/$tdir/$tfile $fcount
1975
1976         for OSC in $MDS_OSCS; do
1977                 OST=$(osc_to_ost $OSC)
1978                 OSTIDX=$(index_from_ostuuid $OST)
1979                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1980                         echo $OST "is recovered from degraded:"
1981                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1982                                                 obdfilter.$OST.degraded=0
1983                 else
1984                         do_facet $SINGLEMDS lctl --device %$OSC activate
1985                 fi
1986         done
1987
1988         # all osp devices get activated, hence -1 stripe count restored
1989         local stripe_count=0
1990
1991         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1992         # devices get activated.
1993         sleep_maxage
1994         $LFS setstripe -c -1 $DIR/$tfile
1995         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1996         rm -f $DIR/$tfile
1997         [ $stripe_count -ne $OSTCOUNT ] &&
1998                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
1999         return 0
2000 }
2001 run_test 27y "create files while OST0 is degraded and the rest inactive"
2002
2003 check_seq_oid()
2004 {
2005         log "check file $1"
2006
2007         lmm_count=$($LFS getstripe -c $1)
2008         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2009         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2010
2011         local old_ifs="$IFS"
2012         IFS=$'[:]'
2013         fid=($($LFS path2fid $1))
2014         IFS="$old_ifs"
2015
2016         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2017         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2018
2019         # compare lmm_seq and lu_fid->f_seq
2020         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2021         # compare lmm_object_id and lu_fid->oid
2022         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2023
2024         # check the trusted.fid attribute of the OST objects of the file
2025         local have_obdidx=false
2026         local stripe_nr=0
2027         $LFS getstripe $1 | while read obdidx oid hex seq; do
2028                 # skip lines up to and including "obdidx"
2029                 [ -z "$obdidx" ] && break
2030                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2031                 $have_obdidx || continue
2032
2033                 local ost=$((obdidx + 1))
2034                 local dev=$(ostdevname $ost)
2035                 local oid_hex
2036
2037                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2038
2039                 seq=$(echo $seq | sed -e "s/^0x//g")
2040                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2041                         oid_hex=$(echo $oid)
2042                 else
2043                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2044                 fi
2045                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2046
2047                 local ff=""
2048                 #
2049                 # Don't unmount/remount the OSTs if we don't need to do that.
2050                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2051                 # update too, until that use mount/ll_decode_filter_fid/mount.
2052                 # Re-enable when debugfs will understand new filter_fid.
2053                 #
2054                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2055                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2056                                 $dev 2>/dev/null" | grep "parent=")
2057                 fi
2058                 if [ -z "$ff" ]; then
2059                         stop ost$ost
2060                         mount_fstype ost$ost
2061                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2062                                 $(facet_mntpt ost$ost)/$obj_file)
2063                         unmount_fstype ost$ost
2064                         start ost$ost $dev $OST_MOUNT_OPTS
2065                         clients_up
2066                 fi
2067
2068                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2069
2070                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2071
2072                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2073                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2074                 #
2075                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2076                 #       stripe_size=1048576 component_id=1 component_start=0 \
2077                 #       component_end=33554432
2078                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2079                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2080                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2081                 local ff_pstripe
2082                 if grep -q 'stripe=' <<<$ff; then
2083                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2084                 else
2085                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2086                         # into f_ver in this case.  See comment on ff_parent.
2087                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2088                 fi
2089
2090                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2091                 [ $ff_pseq = $lmm_seq ] ||
2092                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2093                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2094                 [ $ff_poid = $lmm_oid ] ||
2095                         error "FF parent OID $ff_poid != $lmm_oid"
2096                 (($ff_pstripe == $stripe_nr)) ||
2097                         error "FF stripe $ff_pstripe != $stripe_nr"
2098
2099                 stripe_nr=$((stripe_nr + 1))
2100                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2101                         continue
2102                 if grep -q 'stripe_count=' <<<$ff; then
2103                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2104                                             -e 's/ .*//' <<<$ff)
2105                         [ $lmm_count = $ff_scnt ] ||
2106                                 error "FF stripe count $lmm_count != $ff_scnt"
2107                 fi
2108         done
2109 }
2110
2111 test_27z() {
2112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2113         remote_ost_nodsh && skip "remote OST with nodsh"
2114
2115         test_mkdir $DIR/$tdir
2116         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2117                 { error "setstripe -c -1 failed"; return 1; }
2118         # We need to send a write to every object to get parent FID info set.
2119         # This _should_ also work for setattr, but does not currently.
2120         # touch $DIR/$tdir/$tfile-1 ||
2121         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2122                 { error "dd $tfile-1 failed"; return 2; }
2123         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2124                 { error "setstripe -c -1 failed"; return 3; }
2125         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2126                 { error "dd $tfile-2 failed"; return 4; }
2127
2128         # make sure write RPCs have been sent to OSTs
2129         sync; sleep 5; sync
2130
2131         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2132         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2133 }
2134 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2135
2136 test_27A() { # b=19102
2137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2138
2139         save_layout_restore_at_exit $MOUNT
2140         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2141         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2142                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2143         local default_size=$($LFS getstripe -S $MOUNT)
2144         local default_offset=$($LFS getstripe -i $MOUNT)
2145         local dsize=$(do_facet $SINGLEMDS \
2146                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2147         [ $default_size -eq $dsize ] ||
2148                 error "stripe size $default_size != $dsize"
2149         [ $default_offset -eq -1 ] ||
2150                 error "stripe offset $default_offset != -1"
2151 }
2152 run_test 27A "check filesystem-wide default LOV EA values"
2153
2154 test_27B() { # LU-2523
2155         test_mkdir $DIR/$tdir
2156         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2157         touch $DIR/$tdir/f0
2158         # open f1 with O_LOV_DELAY_CREATE
2159         # rename f0 onto f1
2160         # call setstripe ioctl on open file descriptor for f1
2161         # close
2162         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2163                 $DIR/$tdir/f0
2164
2165         rm -f $DIR/$tdir/f1
2166         # open f1 with O_LOV_DELAY_CREATE
2167         # unlink f1
2168         # call setstripe ioctl on open file descriptor for f1
2169         # close
2170         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2171
2172         # Allow multiop to fail in imitation of NFS's busted semantics.
2173         true
2174 }
2175 run_test 27B "call setstripe on open unlinked file/rename victim"
2176
2177 test_27C() { #LU-2871
2178         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2179
2180         declare -a ost_idx
2181         local index
2182         local found
2183         local i
2184         local j
2185
2186         test_mkdir $DIR/$tdir
2187         cd $DIR/$tdir
2188         for i in $(seq 0 $((OSTCOUNT - 1))); do
2189                 # set stripe across all OSTs starting from OST$i
2190                 $LFS setstripe -i $i -c -1 $tfile$i
2191                 # get striping information
2192                 ost_idx=($($LFS getstripe $tfile$i |
2193                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2194                 echo ${ost_idx[@]}
2195
2196                 # check the layout
2197                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2198                         error "${#ost_idx[@]} != $OSTCOUNT"
2199
2200                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2201                         found=0
2202                         for j in $(echo ${ost_idx[@]}); do
2203                                 if [ $index -eq $j ]; then
2204                                         found=1
2205                                         break
2206                                 fi
2207                         done
2208                         [ $found = 1 ] ||
2209                                 error "Can not find $index in ${ost_idx[@]}"
2210                 done
2211         done
2212 }
2213 run_test 27C "check full striping across all OSTs"
2214
2215 test_27D() {
2216         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2217         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2218         remote_mds_nodsh && skip "remote MDS with nodsh"
2219
2220         local POOL=${POOL:-testpool}
2221         local first_ost=0
2222         local last_ost=$(($OSTCOUNT - 1))
2223         local ost_step=1
2224         local ost_list=$(seq $first_ost $ost_step $last_ost)
2225         local ost_range="$first_ost $last_ost $ost_step"
2226
2227         if ! combined_mgs_mds ; then
2228                 mount_mgs_client
2229         fi
2230
2231         test_mkdir $DIR/$tdir
2232         pool_add $POOL || error "pool_add failed"
2233         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2234
2235         local skip27D
2236         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2237                 skip27D+="-s 29"
2238         [ $MDS1_VERSION -lt $(version_code 2.9.55) -o \
2239           $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2240                 skip27D+=" -s 30,31"
2241         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2242                 error "llapi_layout_test failed"
2243
2244         destroy_test_pools || error "destroy test pools failed"
2245
2246         if ! combined_mgs_mds ; then
2247                 umount_mgs_client
2248         fi
2249 }
2250 run_test 27D "validate llapi_layout API"
2251
2252 # Verify that default_easize is increased from its initial value after
2253 # accessing a widely striped file.
2254 test_27E() {
2255         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2256         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2257                 skip "client does not have LU-3338 fix"
2258
2259         # 72 bytes is the minimum space required to store striping
2260         # information for a file striped across one OST:
2261         # (sizeof(struct lov_user_md_v3) +
2262         #  sizeof(struct lov_user_ost_data_v1))
2263         local min_easize=72
2264         $LCTL set_param -n llite.*.default_easize $min_easize ||
2265                 error "lctl set_param failed"
2266         local easize=$($LCTL get_param -n llite.*.default_easize)
2267
2268         [ $easize -eq $min_easize ] ||
2269                 error "failed to set default_easize"
2270
2271         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2272                 error "setstripe failed"
2273         cat $DIR/$tfile
2274         rm $DIR/$tfile
2275
2276         easize=$($LCTL get_param -n llite.*.default_easize)
2277
2278         [ $easize -gt $min_easize ] ||
2279                 error "default_easize not updated"
2280 }
2281 run_test 27E "check that default extended attribute size properly increases"
2282
2283 test_27F() { # LU-5346/LU-7975
2284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2285         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2286         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2287                 skip "Need MDS version at least 2.8.51"
2288         remote_ost_nodsh && skip "remote OST with nodsh"
2289
2290         test_mkdir $DIR/$tdir
2291         rm -f $DIR/$tdir/f0
2292         $LFS setstripe -c 2 $DIR/$tdir
2293
2294         # stop all OSTs to reproduce situation for LU-7975 ticket
2295         for num in $(seq $OSTCOUNT); do
2296                 stop ost$num
2297         done
2298
2299         # open/create f0 with O_LOV_DELAY_CREATE
2300         # truncate f0 to a non-0 size
2301         # close
2302         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2303
2304         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2305         # open/write it again to force delayed layout creation
2306         cat /etc/hosts > $DIR/$tdir/f0 &
2307         catpid=$!
2308
2309         # restart OSTs
2310         for num in $(seq $OSTCOUNT); do
2311                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2312                         error "ost$num failed to start"
2313         done
2314
2315         wait $catpid || error "cat failed"
2316
2317         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2318         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2319                 error "wrong stripecount"
2320
2321 }
2322 run_test 27F "Client resend delayed layout creation with non-zero size"
2323
2324 test_27G() { #LU-10629
2325         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2326                 skip "Need MDS version at least 2.11.51"
2327         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2328         remote_mds_nodsh && skip "remote MDS with nodsh"
2329         local POOL=${POOL:-testpool}
2330         local ostrange="0 0 1"
2331
2332         test_mkdir $DIR/$tdir
2333         pool_add $POOL || error "pool_add failed"
2334         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2335         $LFS setstripe -p $POOL $DIR/$tdir
2336
2337         local pool=$($LFS getstripe -p $DIR/$tdir)
2338
2339         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2340
2341         $LFS setstripe -d $DIR/$tdir
2342
2343         pool=$($LFS getstripe -p $DIR/$tdir)
2344
2345         rmdir $DIR/$tdir
2346
2347         [ -z "$pool" ] || error "'$pool' is not empty"
2348 }
2349 run_test 27G "Clear OST pool from stripe"
2350
2351 test_27H() {
2352         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2353                 skip "Need MDS version newer than 2.11.54"
2354         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2355         test_mkdir $DIR/$tdir
2356         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2357         touch $DIR/$tdir/$tfile
2358         $LFS getstripe -c $DIR/$tdir/$tfile
2359         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2360                 error "two-stripe file doesn't have two stripes"
2361
2362         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2363         $LFS getstripe -y $DIR/$tdir/$tfile
2364         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2365              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2366                 error "expected l_ost_idx: [02]$ not matched"
2367
2368         # make sure ost list has been cleared
2369         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2370         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2371                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2372         touch $DIR/$tdir/f3
2373         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2374 }
2375 run_test 27H "Set specific OSTs stripe"
2376
2377 # createtest also checks that device nodes are created and
2378 # then visible correctly (#2091)
2379 test_28() { # bug 2091
2380         test_mkdir $DIR/d28
2381         $CREATETEST $DIR/d28/ct || error "createtest failed"
2382 }
2383 run_test 28 "create/mknod/mkdir with bad file types ============"
2384
2385 test_29() {
2386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2387
2388         sync; sleep 1; sync # flush out any dirty pages from previous tests
2389         cancel_lru_locks
2390         test_mkdir $DIR/d29
2391         touch $DIR/d29/foo
2392         log 'first d29'
2393         ls -l $DIR/d29
2394
2395         declare -i LOCKCOUNTORIG=0
2396         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2397                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2398         done
2399         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2400
2401         declare -i LOCKUNUSEDCOUNTORIG=0
2402         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2403                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2404         done
2405
2406         log 'second d29'
2407         ls -l $DIR/d29
2408         log 'done'
2409
2410         declare -i LOCKCOUNTCURRENT=0
2411         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2412                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2413         done
2414
2415         declare -i LOCKUNUSEDCOUNTCURRENT=0
2416         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2417                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2418         done
2419
2420         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2421                 $LCTL set_param -n ldlm.dump_namespaces ""
2422                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2423                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2424                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2425                 return 2
2426         fi
2427         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2428                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2429                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2430                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2431                 return 3
2432         fi
2433 }
2434 run_test 29 "IT_GETATTR regression  ============================"
2435
2436 test_30a() { # was test_30
2437         cp $(which ls) $DIR || cp /bin/ls $DIR
2438         $DIR/ls / || error "Can't execute binary from lustre"
2439         rm $DIR/ls
2440 }
2441 run_test 30a "execute binary from Lustre (execve) =============="
2442
2443 test_30b() {
2444         cp `which ls` $DIR || cp /bin/ls $DIR
2445         chmod go+rx $DIR/ls
2446         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2447         rm $DIR/ls
2448 }
2449 run_test 30b "execute binary from Lustre as non-root ==========="
2450
2451 test_30c() { # b=22376
2452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2453
2454         cp `which ls` $DIR || cp /bin/ls $DIR
2455         chmod a-rw $DIR/ls
2456         cancel_lru_locks mdc
2457         cancel_lru_locks osc
2458         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2459         rm -f $DIR/ls
2460 }
2461 run_test 30c "execute binary from Lustre without read perms ===="
2462
2463 test_31a() {
2464         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2465         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2466 }
2467 run_test 31a "open-unlink file =================================="
2468
2469 test_31b() {
2470         touch $DIR/f31 || error "touch $DIR/f31 failed"
2471         ln $DIR/f31 $DIR/f31b || error "ln failed"
2472         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2473         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2474 }
2475 run_test 31b "unlink file with multiple links while open ======="
2476
2477 test_31c() {
2478         touch $DIR/f31 || error "touch $DIR/f31 failed"
2479         ln $DIR/f31 $DIR/f31c || error "ln failed"
2480         multiop_bg_pause $DIR/f31 O_uc ||
2481                 error "multiop_bg_pause for $DIR/f31 failed"
2482         MULTIPID=$!
2483         $MULTIOP $DIR/f31c Ouc
2484         kill -USR1 $MULTIPID
2485         wait $MULTIPID
2486 }
2487 run_test 31c "open-unlink file with multiple links ============="
2488
2489 test_31d() {
2490         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2491         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2492 }
2493 run_test 31d "remove of open directory ========================="
2494
2495 test_31e() { # bug 2904
2496         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2497 }
2498 run_test 31e "remove of open non-empty directory ==============="
2499
2500 test_31f() { # bug 4554
2501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2502
2503         set -vx
2504         test_mkdir $DIR/d31f
2505         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2506         cp /etc/hosts $DIR/d31f
2507         ls -l $DIR/d31f
2508         $LFS getstripe $DIR/d31f/hosts
2509         multiop_bg_pause $DIR/d31f D_c || return 1
2510         MULTIPID=$!
2511
2512         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2513         test_mkdir $DIR/d31f
2514         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2515         cp /etc/hosts $DIR/d31f
2516         ls -l $DIR/d31f
2517         $LFS getstripe $DIR/d31f/hosts
2518         multiop_bg_pause $DIR/d31f D_c || return 1
2519         MULTIPID2=$!
2520
2521         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2522         wait $MULTIPID || error "first opendir $MULTIPID failed"
2523
2524         sleep 6
2525
2526         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2527         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2528         set +vx
2529 }
2530 run_test 31f "remove of open directory with open-unlink file ==="
2531
2532 test_31g() {
2533         echo "-- cross directory link --"
2534         test_mkdir -c1 $DIR/${tdir}ga
2535         test_mkdir -c1 $DIR/${tdir}gb
2536         touch $DIR/${tdir}ga/f
2537         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2538         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2539         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2540         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2541         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2542 }
2543 run_test 31g "cross directory link==============="
2544
2545 test_31h() {
2546         echo "-- cross directory link --"
2547         test_mkdir -c1 $DIR/${tdir}
2548         test_mkdir -c1 $DIR/${tdir}/dir
2549         touch $DIR/${tdir}/f
2550         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2551         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2552         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2553         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2554         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2555 }
2556 run_test 31h "cross directory link under child==============="
2557
2558 test_31i() {
2559         echo "-- cross directory link --"
2560         test_mkdir -c1 $DIR/$tdir
2561         test_mkdir -c1 $DIR/$tdir/dir
2562         touch $DIR/$tdir/dir/f
2563         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2564         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2565         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2566         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2567         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2568 }
2569 run_test 31i "cross directory link under parent==============="
2570
2571 test_31j() {
2572         test_mkdir -c1 -p $DIR/$tdir
2573         test_mkdir -c1 -p $DIR/$tdir/dir1
2574         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2575         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2576         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2577         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2578         return 0
2579 }
2580 run_test 31j "link for directory==============="
2581
2582 test_31k() {
2583         test_mkdir -c1 -p $DIR/$tdir
2584         touch $DIR/$tdir/s
2585         touch $DIR/$tdir/exist
2586         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2587         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2588         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2589         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2590         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2591         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2592         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2593         return 0
2594 }
2595 run_test 31k "link to file: the same, non-existing, dir==============="
2596
2597 test_31m() {
2598         mkdir $DIR/d31m
2599         touch $DIR/d31m/s
2600         mkdir $DIR/d31m2
2601         touch $DIR/d31m2/exist
2602         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2603         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2604         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2605         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2606         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2607         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2608         return 0
2609 }
2610 run_test 31m "link to file: the same, non-existing, dir==============="
2611
2612 test_31n() {
2613         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2614         nlink=$(stat --format=%h $DIR/$tfile)
2615         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2616         local fd=$(free_fd)
2617         local cmd="exec $fd<$DIR/$tfile"
2618         eval $cmd
2619         cmd="exec $fd<&-"
2620         trap "eval $cmd" EXIT
2621         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2622         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2623         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2624         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2625         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2626         eval $cmd
2627 }
2628 run_test 31n "check link count of unlinked file"
2629
2630 link_one() {
2631         local TEMPNAME=$(mktemp $1_XXXXXX)
2632         mlink $TEMPNAME $1 2> /dev/null &&
2633                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2634         munlink $TEMPNAME
2635 }
2636
2637 test_31o() { # LU-2901
2638         test_mkdir $DIR/$tdir
2639         for LOOP in $(seq 100); do
2640                 rm -f $DIR/$tdir/$tfile*
2641                 for THREAD in $(seq 8); do
2642                         link_one $DIR/$tdir/$tfile.$LOOP &
2643                 done
2644                 wait
2645                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2646                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2647                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2648                         break || true
2649         done
2650 }
2651 run_test 31o "duplicate hard links with same filename"
2652
2653 test_31p() {
2654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2655
2656         test_mkdir $DIR/$tdir
2657         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2658         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2659
2660         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2661                 error "open unlink test1 failed"
2662         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2663                 error "open unlink test2 failed"
2664
2665         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2666                 error "test1 still exists"
2667         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2668                 error "test2 still exists"
2669 }
2670 run_test 31p "remove of open striped directory"
2671
2672 cleanup_test32_mount() {
2673         local rc=0
2674         trap 0
2675         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2676         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2677         losetup -d $loopdev || true
2678         rm -rf $DIR/$tdir
2679         return $rc
2680 }
2681
2682 test_32a() {
2683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2684
2685         echo "== more mountpoints and symlinks ================="
2686         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2687         trap cleanup_test32_mount EXIT
2688         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2689         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2690                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2691         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2692                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2693         cleanup_test32_mount
2694 }
2695 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2696
2697 test_32b() {
2698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2699
2700         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2701         trap cleanup_test32_mount EXIT
2702         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2703         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2704                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2705         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2706                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2707         cleanup_test32_mount
2708 }
2709 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2710
2711 test_32c() {
2712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2713
2714         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2715         trap cleanup_test32_mount EXIT
2716         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2717         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2718                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2719         test_mkdir -p $DIR/$tdir/d2/test_dir
2720         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2721                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2722         cleanup_test32_mount
2723 }
2724 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2725
2726 test_32d() {
2727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2728
2729         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2730         trap cleanup_test32_mount EXIT
2731         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2732         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2733                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2734         test_mkdir -p $DIR/$tdir/d2/test_dir
2735         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2736                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2737         cleanup_test32_mount
2738 }
2739 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2740
2741 test_32e() {
2742         rm -fr $DIR/$tdir
2743         test_mkdir -p $DIR/$tdir/tmp
2744         local tmp_dir=$DIR/$tdir/tmp
2745         ln -s $DIR/$tdir $tmp_dir/symlink11
2746         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2747         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2748         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2749 }
2750 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2751
2752 test_32f() {
2753         rm -fr $DIR/$tdir
2754         test_mkdir -p $DIR/$tdir/tmp
2755         local tmp_dir=$DIR/$tdir/tmp
2756         ln -s $DIR/$tdir $tmp_dir/symlink11
2757         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2758         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2759         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2760 }
2761 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2762
2763 test_32g() {
2764         local tmp_dir=$DIR/$tdir/tmp
2765         test_mkdir -p $tmp_dir
2766         test_mkdir $DIR/${tdir}2
2767         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2768         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2769         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2770         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2771         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2772         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2773 }
2774 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2775
2776 test_32h() {
2777         rm -fr $DIR/$tdir $DIR/${tdir}2
2778         tmp_dir=$DIR/$tdir/tmp
2779         test_mkdir -p $tmp_dir
2780         test_mkdir $DIR/${tdir}2
2781         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2782         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2783         ls $tmp_dir/symlink12 || error "listing symlink12"
2784         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2785 }
2786 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2787
2788 test_32i() {
2789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2790
2791         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2792         trap cleanup_test32_mount EXIT
2793         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2794         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2795                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2796         touch $DIR/$tdir/test_file
2797         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2798                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2799         cleanup_test32_mount
2800 }
2801 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2802
2803 test_32j() {
2804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2805
2806         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2807         trap cleanup_test32_mount EXIT
2808         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2809         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2810                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2811         touch $DIR/$tdir/test_file
2812         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2813                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2814         cleanup_test32_mount
2815 }
2816 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2817
2818 test_32k() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820
2821         rm -fr $DIR/$tdir
2822         trap cleanup_test32_mount EXIT
2823         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2824         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2825                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2826         test_mkdir -p $DIR/$tdir/d2
2827         touch $DIR/$tdir/d2/test_file || error "touch failed"
2828         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2829                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2830         cleanup_test32_mount
2831 }
2832 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2833
2834 test_32l() {
2835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2836
2837         rm -fr $DIR/$tdir
2838         trap cleanup_test32_mount EXIT
2839         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2840         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2841                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2842         test_mkdir -p $DIR/$tdir/d2
2843         touch $DIR/$tdir/d2/test_file || error "touch failed"
2844         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2845                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2846         cleanup_test32_mount
2847 }
2848 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2849
2850 test_32m() {
2851         rm -fr $DIR/d32m
2852         test_mkdir -p $DIR/d32m/tmp
2853         TMP_DIR=$DIR/d32m/tmp
2854         ln -s $DIR $TMP_DIR/symlink11
2855         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2856         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2857                 error "symlink11 not a link"
2858         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2859                 error "symlink01 not a link"
2860 }
2861 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2862
2863 test_32n() {
2864         rm -fr $DIR/d32n
2865         test_mkdir -p $DIR/d32n/tmp
2866         TMP_DIR=$DIR/d32n/tmp
2867         ln -s $DIR $TMP_DIR/symlink11
2868         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2869         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2870         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2871 }
2872 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2873
2874 test_32o() {
2875         touch $DIR/$tfile
2876         test_mkdir -p $DIR/d32o/tmp
2877         TMP_DIR=$DIR/d32o/tmp
2878         ln -s $DIR/$tfile $TMP_DIR/symlink12
2879         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2880         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2881                 error "symlink12 not a link"
2882         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2883         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2884                 error "$DIR/d32o/tmp/symlink12 not file type"
2885         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2886                 error "$DIR/d32o/symlink02 not file type"
2887 }
2888 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2889
2890 test_32p() {
2891         log 32p_1
2892         rm -fr $DIR/d32p
2893         log 32p_2
2894         rm -f $DIR/$tfile
2895         log 32p_3
2896         touch $DIR/$tfile
2897         log 32p_4
2898         test_mkdir -p $DIR/d32p/tmp
2899         log 32p_5
2900         TMP_DIR=$DIR/d32p/tmp
2901         log 32p_6
2902         ln -s $DIR/$tfile $TMP_DIR/symlink12
2903         log 32p_7
2904         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2905         log 32p_8
2906         cat $DIR/d32p/tmp/symlink12 ||
2907                 error "Can't open $DIR/d32p/tmp/symlink12"
2908         log 32p_9
2909         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2910         log 32p_10
2911 }
2912 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2913
2914 test_32q() {
2915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2916
2917         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2918         trap cleanup_test32_mount EXIT
2919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2920         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2921         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2922                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2923         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2924         cleanup_test32_mount
2925 }
2926 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2927
2928 test_32r() {
2929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2930
2931         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2932         trap cleanup_test32_mount EXIT
2933         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2934         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2935         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2936                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2937         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2938         cleanup_test32_mount
2939 }
2940 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2941
2942 test_33aa() {
2943         rm -f $DIR/$tfile
2944         touch $DIR/$tfile
2945         chmod 444 $DIR/$tfile
2946         chown $RUNAS_ID $DIR/$tfile
2947         log 33_1
2948         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2949         log 33_2
2950 }
2951 run_test 33aa "write file with mode 444 (should return error)"
2952
2953 test_33a() {
2954         rm -fr $DIR/$tdir
2955         test_mkdir $DIR/$tdir
2956         chown $RUNAS_ID $DIR/$tdir
2957         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2958                 error "$RUNAS create $tdir/$tfile failed"
2959         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2960                 error "open RDWR" || true
2961 }
2962 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2963
2964 test_33b() {
2965         rm -fr $DIR/$tdir
2966         test_mkdir $DIR/$tdir
2967         chown $RUNAS_ID $DIR/$tdir
2968         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2969 }
2970 run_test 33b "test open file with malformed flags (No panic)"
2971
2972 test_33c() {
2973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2974         remote_ost_nodsh && skip "remote OST with nodsh"
2975
2976         local ostnum
2977         local ostname
2978         local write_bytes
2979         local all_zeros
2980
2981         all_zeros=:
2982         rm -fr $DIR/$tdir
2983         test_mkdir $DIR/$tdir
2984         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2985
2986         sync
2987         for ostnum in $(seq $OSTCOUNT); do
2988                 # test-framework's OST numbering is one-based, while Lustre's
2989                 # is zero-based
2990                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2991                 # Parsing llobdstat's output sucks; we could grep the /proc
2992                 # path, but that's likely to not be as portable as using the
2993                 # llobdstat utility.  So we parse lctl output instead.
2994                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2995                         obdfilter/$ostname/stats |
2996                         awk '/^write_bytes/ {print $7}' )
2997                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2998                 if (( ${write_bytes:-0} > 0 ))
2999                 then
3000                         all_zeros=false
3001                         break;
3002                 fi
3003         done
3004
3005         $all_zeros || return 0
3006
3007         # Write four bytes
3008         echo foo > $DIR/$tdir/bar
3009         # Really write them
3010         sync
3011
3012         # Total up write_bytes after writing.  We'd better find non-zeros.
3013         for ostnum in $(seq $OSTCOUNT); do
3014                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3015                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3016                         obdfilter/$ostname/stats |
3017                         awk '/^write_bytes/ {print $7}' )
3018                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3019                 if (( ${write_bytes:-0} > 0 ))
3020                 then
3021                         all_zeros=false
3022                         break;
3023                 fi
3024         done
3025
3026         if $all_zeros
3027         then
3028                 for ostnum in $(seq $OSTCOUNT); do
3029                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3030                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3031                         do_facet ost$ostnum lctl get_param -n \
3032                                 obdfilter/$ostname/stats
3033                 done
3034                 error "OST not keeping write_bytes stats (b22312)"
3035         fi
3036 }
3037 run_test 33c "test llobdstat and write_bytes"
3038
3039 test_33d() {
3040         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3042
3043         local MDTIDX=1
3044         local remote_dir=$DIR/$tdir/remote_dir
3045
3046         test_mkdir $DIR/$tdir
3047         $LFS mkdir -i $MDTIDX $remote_dir ||
3048                 error "create remote directory failed"
3049
3050         touch $remote_dir/$tfile
3051         chmod 444 $remote_dir/$tfile
3052         chown $RUNAS_ID $remote_dir/$tfile
3053
3054         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3055
3056         chown $RUNAS_ID $remote_dir
3057         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3058                                         error "create" || true
3059         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3060                                     error "open RDWR" || true
3061         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3062 }
3063 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3064
3065 test_33e() {
3066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3067
3068         mkdir $DIR/$tdir
3069
3070         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3071         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3072         mkdir $DIR/$tdir/local_dir
3073
3074         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3075         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3076         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3077
3078         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3079                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3080
3081         rmdir $DIR/$tdir/* || error "rmdir failed"
3082
3083         umask 777
3084         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3085         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3086         mkdir $DIR/$tdir/local_dir
3087
3088         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3089         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3090         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3091
3092         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3093                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3094
3095         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3096
3097         umask 000
3098         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3099         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3100         mkdir $DIR/$tdir/local_dir
3101
3102         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3103         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3104         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3105
3106         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3107                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3108 }
3109 run_test 33e "mkdir and striped directory should have same mode"
3110
3111 cleanup_33f() {
3112         trap 0
3113         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3114 }
3115
3116 test_33f() {
3117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3118         remote_mds_nodsh && skip "remote MDS with nodsh"
3119
3120         mkdir $DIR/$tdir
3121         chmod go+rwx $DIR/$tdir
3122         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3123         trap cleanup_33f EXIT
3124
3125         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3126                 error "cannot create striped directory"
3127
3128         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3129                 error "cannot create files in striped directory"
3130
3131         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3132                 error "cannot remove files in striped directory"
3133
3134         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3135                 error "cannot remove striped directory"
3136
3137         cleanup_33f
3138 }
3139 run_test 33f "nonroot user can create, access, and remove a striped directory"
3140
3141 test_33g() {
3142         mkdir -p $DIR/$tdir/dir2
3143
3144         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3145         echo $err
3146         [[ $err =~ "exists" ]] || error "Not exists error"
3147 }
3148 run_test 33g "nonroot user create already existing root created file"
3149
3150 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3151 test_34a() {
3152         rm -f $DIR/f34
3153         $MCREATE $DIR/f34 || error "mcreate failed"
3154         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3155                 error "getstripe failed"
3156         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3157         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3158                 error "getstripe failed"
3159         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3160                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3161 }
3162 run_test 34a "truncate file that has not been opened ==========="
3163
3164 test_34b() {
3165         [ ! -f $DIR/f34 ] && test_34a
3166         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3167                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3168         $OPENFILE -f O_RDONLY $DIR/f34
3169         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3170                 error "getstripe failed"
3171         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3172                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3173 }
3174 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3175
3176 test_34c() {
3177         [ ! -f $DIR/f34 ] && test_34a
3178         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3179                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3180         $OPENFILE -f O_RDWR $DIR/f34
3181         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3182                 error "$LFS getstripe failed"
3183         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3184                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3185 }
3186 run_test 34c "O_RDWR opening file-with-size works =============="
3187
3188 test_34d() {
3189         [ ! -f $DIR/f34 ] && test_34a
3190         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3191                 error "dd failed"
3192         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3193                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3194         rm $DIR/f34
3195 }
3196 run_test 34d "write to sparse file ============================="
3197
3198 test_34e() {
3199         rm -f $DIR/f34e
3200         $MCREATE $DIR/f34e || error "mcreate failed"
3201         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3202         $CHECKSTAT -s 1000 $DIR/f34e ||
3203                 error "Size of $DIR/f34e not equal to 1000 bytes"
3204         $OPENFILE -f O_RDWR $DIR/f34e
3205         $CHECKSTAT -s 1000 $DIR/f34e ||
3206                 error "Size of $DIR/f34e not equal to 1000 bytes"
3207 }
3208 run_test 34e "create objects, some with size and some without =="
3209
3210 test_34f() { # bug 6242, 6243
3211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3212
3213         SIZE34F=48000
3214         rm -f $DIR/f34f
3215         $MCREATE $DIR/f34f || error "mcreate failed"
3216         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3217         dd if=$DIR/f34f of=$TMP/f34f
3218         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3219         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3220         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3221         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3222         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3223 }
3224 run_test 34f "read from a file with no objects until EOF ======="
3225
3226 test_34g() {
3227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3228
3229         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3230                 error "dd failed"
3231         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3232         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3233                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3234         cancel_lru_locks osc
3235         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3236                 error "wrong size after lock cancel"
3237
3238         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3239         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3240                 error "expanding truncate failed"
3241         cancel_lru_locks osc
3242         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3243                 error "wrong expanded size after lock cancel"
3244 }
3245 run_test 34g "truncate long file ==============================="
3246
3247 test_34h() {
3248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3249
3250         local gid=10
3251         local sz=1000
3252
3253         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3254         sync # Flush the cache so that multiop below does not block on cache
3255              # flush when getting the group lock
3256         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3257         MULTIPID=$!
3258
3259         # Since just timed wait is not good enough, let's do a sync write
3260         # that way we are sure enough time for a roundtrip + processing
3261         # passed + 2 seconds of extra margin.
3262         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3263         rm $DIR/${tfile}-1
3264         sleep 2
3265
3266         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3267                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3268                 kill -9 $MULTIPID
3269         fi
3270         wait $MULTIPID
3271         local nsz=`stat -c %s $DIR/$tfile`
3272         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3273 }
3274 run_test 34h "ftruncate file under grouplock should not block"
3275
3276 test_35a() {
3277         cp /bin/sh $DIR/f35a
3278         chmod 444 $DIR/f35a
3279         chown $RUNAS_ID $DIR/f35a
3280         $RUNAS $DIR/f35a && error || true
3281         rm $DIR/f35a
3282 }
3283 run_test 35a "exec file with mode 444 (should return and not leak)"
3284
3285 test_36a() {
3286         rm -f $DIR/f36
3287         utime $DIR/f36 || error "utime failed for MDS"
3288 }
3289 run_test 36a "MDS utime check (mknod, utime)"
3290
3291 test_36b() {
3292         echo "" > $DIR/f36
3293         utime $DIR/f36 || error "utime failed for OST"
3294 }
3295 run_test 36b "OST utime check (open, utime)"
3296
3297 test_36c() {
3298         rm -f $DIR/d36/f36
3299         test_mkdir $DIR/d36
3300         chown $RUNAS_ID $DIR/d36
3301         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3302 }
3303 run_test 36c "non-root MDS utime check (mknod, utime)"
3304
3305 test_36d() {
3306         [ ! -d $DIR/d36 ] && test_36c
3307         echo "" > $DIR/d36/f36
3308         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3309 }
3310 run_test 36d "non-root OST utime check (open, utime)"
3311
3312 test_36e() {
3313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3314
3315         test_mkdir $DIR/$tdir
3316         touch $DIR/$tdir/$tfile
3317         $RUNAS utime $DIR/$tdir/$tfile &&
3318                 error "utime worked, expected failure" || true
3319 }
3320 run_test 36e "utime on non-owned file (should return error)"
3321
3322 subr_36fh() {
3323         local fl="$1"
3324         local LANG_SAVE=$LANG
3325         local LC_LANG_SAVE=$LC_LANG
3326         export LANG=C LC_LANG=C # for date language
3327
3328         DATESTR="Dec 20  2000"
3329         test_mkdir $DIR/$tdir
3330         lctl set_param fail_loc=$fl
3331         date; date +%s
3332         cp /etc/hosts $DIR/$tdir/$tfile
3333         sync & # write RPC generated with "current" inode timestamp, but delayed
3334         sleep 1
3335         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3336         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3337         cancel_lru_locks $OSC
3338         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3339         date; date +%s
3340         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3341                 echo "BEFORE: $LS_BEFORE" && \
3342                 echo "AFTER : $LS_AFTER" && \
3343                 echo "WANT  : $DATESTR" && \
3344                 error "$DIR/$tdir/$tfile timestamps changed" || true
3345
3346         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3347 }
3348
3349 test_36f() {
3350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3351
3352         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3353         subr_36fh "0x80000214"
3354 }
3355 run_test 36f "utime on file racing with OST BRW write =========="
3356
3357 test_36g() {
3358         remote_ost_nodsh && skip "remote OST with nodsh"
3359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3360         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3361                 skip "Need MDS version at least 2.12.51"
3362
3363         local fmd_max_age
3364         local fmd
3365         local facet="ost1"
3366         local tgt="obdfilter"
3367
3368         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3369
3370         test_mkdir $DIR/$tdir
3371         fmd_max_age=$(do_facet $facet \
3372                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3373                 head -n 1")
3374
3375         echo "FMD max age: ${fmd_max_age}s"
3376         touch $DIR/$tdir/$tfile
3377         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3378                 gawk '{cnt=cnt+$1}  END{print cnt}')
3379         echo "FMD before: $fmd"
3380         [[ $fmd == 0 ]] &&
3381                 error "FMD wasn't create by touch"
3382         sleep $((fmd_max_age + 12))
3383         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3384                 gawk '{cnt=cnt+$1}  END{print cnt}')
3385         echo "FMD after: $fmd"
3386         [[ $fmd == 0 ]] ||
3387                 error "FMD wasn't expired by ping"
3388 }
3389 run_test 36g "FMD cache expiry ====================="
3390
3391 test_36h() {
3392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3393
3394         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3395         subr_36fh "0x80000227"
3396 }
3397 run_test 36h "utime on file racing with OST BRW write =========="
3398
3399 test_36i() {
3400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3401
3402         test_mkdir $DIR/$tdir
3403         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3404
3405         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3406         local new_mtime=$((mtime + 200))
3407
3408         #change Modify time of striped dir
3409         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3410                         error "change mtime failed"
3411
3412         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3413
3414         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3415 }
3416 run_test 36i "change mtime on striped directory"
3417
3418 # test_37 - duplicate with tests 32q 32r
3419
3420 test_38() {
3421         local file=$DIR/$tfile
3422         touch $file
3423         openfile -f O_DIRECTORY $file
3424         local RC=$?
3425         local ENOTDIR=20
3426         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3427         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3428 }
3429 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3430
3431 test_39a() { # was test_39
3432         touch $DIR/$tfile
3433         touch $DIR/${tfile}2
3434 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3435 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3436 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3437         sleep 2
3438         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3439         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3440                 echo "mtime"
3441                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3442                 echo "atime"
3443                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3444                 echo "ctime"
3445                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3446                 error "O_TRUNC didn't change timestamps"
3447         fi
3448 }
3449 run_test 39a "mtime changed on create"
3450
3451 test_39b() {
3452         test_mkdir -c1 $DIR/$tdir
3453         cp -p /etc/passwd $DIR/$tdir/fopen
3454         cp -p /etc/passwd $DIR/$tdir/flink
3455         cp -p /etc/passwd $DIR/$tdir/funlink
3456         cp -p /etc/passwd $DIR/$tdir/frename
3457         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3458
3459         sleep 1
3460         echo "aaaaaa" >> $DIR/$tdir/fopen
3461         echo "aaaaaa" >> $DIR/$tdir/flink
3462         echo "aaaaaa" >> $DIR/$tdir/funlink
3463         echo "aaaaaa" >> $DIR/$tdir/frename
3464
3465         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3466         local link_new=`stat -c %Y $DIR/$tdir/flink`
3467         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3468         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3469
3470         cat $DIR/$tdir/fopen > /dev/null
3471         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3472         rm -f $DIR/$tdir/funlink2
3473         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3474
3475         for (( i=0; i < 2; i++ )) ; do
3476                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3477                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3478                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3479                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3480
3481                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3482                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3483                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3484                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3485
3486                 cancel_lru_locks $OSC
3487                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3488         done
3489 }
3490 run_test 39b "mtime change on open, link, unlink, rename  ======"
3491
3492 # this should be set to past
3493 TEST_39_MTIME=`date -d "1 year ago" +%s`
3494
3495 # bug 11063
3496 test_39c() {
3497         touch $DIR1/$tfile
3498         sleep 2
3499         local mtime0=`stat -c %Y $DIR1/$tfile`
3500
3501         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3502         local mtime1=`stat -c %Y $DIR1/$tfile`
3503         [ "$mtime1" = $TEST_39_MTIME ] || \
3504                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3505
3506         local d1=`date +%s`
3507         echo hello >> $DIR1/$tfile
3508         local d2=`date +%s`
3509         local mtime2=`stat -c %Y $DIR1/$tfile`
3510         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3511                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3512
3513         mv $DIR1/$tfile $DIR1/$tfile-1
3514
3515         for (( i=0; i < 2; i++ )) ; do
3516                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3517                 [ "$mtime2" = "$mtime3" ] || \
3518                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3519
3520                 cancel_lru_locks $OSC
3521                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3522         done
3523 }
3524 run_test 39c "mtime change on rename ==========================="
3525
3526 # bug 21114
3527 test_39d() {
3528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3529
3530         touch $DIR1/$tfile
3531         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3532
3533         for (( i=0; i < 2; i++ )) ; do
3534                 local mtime=`stat -c %Y $DIR1/$tfile`
3535                 [ $mtime = $TEST_39_MTIME ] || \
3536                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3537
3538                 cancel_lru_locks $OSC
3539                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3540         done
3541 }
3542 run_test 39d "create, utime, stat =============================="
3543
3544 # bug 21114
3545 test_39e() {
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         touch $DIR1/$tfile
3549         local mtime1=`stat -c %Y $DIR1/$tfile`
3550
3551         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3552
3553         for (( i=0; i < 2; i++ )) ; do
3554                 local mtime2=`stat -c %Y $DIR1/$tfile`
3555                 [ $mtime2 = $TEST_39_MTIME ] || \
3556                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3557
3558                 cancel_lru_locks $OSC
3559                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3560         done
3561 }
3562 run_test 39e "create, stat, utime, stat ========================"
3563
3564 # bug 21114
3565 test_39f() {
3566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3567
3568         touch $DIR1/$tfile
3569         mtime1=`stat -c %Y $DIR1/$tfile`
3570
3571         sleep 2
3572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3573
3574         for (( i=0; i < 2; i++ )) ; do
3575                 local mtime2=`stat -c %Y $DIR1/$tfile`
3576                 [ $mtime2 = $TEST_39_MTIME ] || \
3577                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3578
3579                 cancel_lru_locks $OSC
3580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3581         done
3582 }
3583 run_test 39f "create, stat, sleep, utime, stat ================="
3584
3585 # bug 11063
3586 test_39g() {
3587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3588
3589         echo hello >> $DIR1/$tfile
3590         local mtime1=`stat -c %Y $DIR1/$tfile`
3591
3592         sleep 2
3593         chmod o+r $DIR1/$tfile
3594
3595         for (( i=0; i < 2; i++ )) ; do
3596                 local mtime2=`stat -c %Y $DIR1/$tfile`
3597                 [ "$mtime1" = "$mtime2" ] || \
3598                         error "lost mtime: $mtime2, should be $mtime1"
3599
3600                 cancel_lru_locks $OSC
3601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3602         done
3603 }
3604 run_test 39g "write, chmod, stat ==============================="
3605
3606 # bug 11063
3607 test_39h() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         touch $DIR1/$tfile
3611         sleep 1
3612
3613         local d1=`date`
3614         echo hello >> $DIR1/$tfile
3615         local mtime1=`stat -c %Y $DIR1/$tfile`
3616
3617         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3618         local d2=`date`
3619         if [ "$d1" != "$d2" ]; then
3620                 echo "write and touch not within one second"
3621         else
3622                 for (( i=0; i < 2; i++ )) ; do
3623                         local mtime2=`stat -c %Y $DIR1/$tfile`
3624                         [ "$mtime2" = $TEST_39_MTIME ] || \
3625                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3626
3627                         cancel_lru_locks $OSC
3628                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3629                 done
3630         fi
3631 }
3632 run_test 39h "write, utime within one second, stat ============="
3633
3634 test_39i() {
3635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3636
3637         touch $DIR1/$tfile
3638         sleep 1
3639
3640         echo hello >> $DIR1/$tfile
3641         local mtime1=`stat -c %Y $DIR1/$tfile`
3642
3643         mv $DIR1/$tfile $DIR1/$tfile-1
3644
3645         for (( i=0; i < 2; i++ )) ; do
3646                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3647
3648                 [ "$mtime1" = "$mtime2" ] || \
3649                         error "lost mtime: $mtime2, should be $mtime1"
3650
3651                 cancel_lru_locks $OSC
3652                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3653         done
3654 }
3655 run_test 39i "write, rename, stat =============================="
3656
3657 test_39j() {
3658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3659
3660         start_full_debug_logging
3661         touch $DIR1/$tfile
3662         sleep 1
3663
3664         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3665         lctl set_param fail_loc=0x80000412
3666         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3667                 error "multiop failed"
3668         local multipid=$!
3669         local mtime1=`stat -c %Y $DIR1/$tfile`
3670
3671         mv $DIR1/$tfile $DIR1/$tfile-1
3672
3673         kill -USR1 $multipid
3674         wait $multipid || error "multiop close failed"
3675
3676         for (( i=0; i < 2; i++ )) ; do
3677                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3678                 [ "$mtime1" = "$mtime2" ] ||
3679                         error "mtime is lost on close: $mtime2, " \
3680                               "should be $mtime1"
3681
3682                 cancel_lru_locks $OSC
3683                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3684         done
3685         lctl set_param fail_loc=0
3686         stop_full_debug_logging
3687 }
3688 run_test 39j "write, rename, close, stat ======================="
3689
3690 test_39k() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692
3693         touch $DIR1/$tfile
3694         sleep 1
3695
3696         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3697         local multipid=$!
3698         local mtime1=`stat -c %Y $DIR1/$tfile`
3699
3700         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3701
3702         kill -USR1 $multipid
3703         wait $multipid || error "multiop close failed"
3704
3705         for (( i=0; i < 2; i++ )) ; do
3706                 local mtime2=`stat -c %Y $DIR1/$tfile`
3707
3708                 [ "$mtime2" = $TEST_39_MTIME ] || \
3709                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3710
3711                 cancel_lru_locks osc
3712                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3713         done
3714 }
3715 run_test 39k "write, utime, close, stat ========================"
3716
3717 # this should be set to future
3718 TEST_39_ATIME=`date -d "1 year" +%s`
3719
3720 test_39l() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722         remote_mds_nodsh && skip "remote MDS with nodsh"
3723
3724         local atime_diff=$(do_facet $SINGLEMDS \
3725                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3726         rm -rf $DIR/$tdir
3727         mkdir -p $DIR/$tdir
3728
3729         # test setting directory atime to future
3730         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3731         local atime=$(stat -c %X $DIR/$tdir)
3732         [ "$atime" = $TEST_39_ATIME ] ||
3733                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3734
3735         # test setting directory atime from future to now
3736         local now=$(date +%s)
3737         touch -a -d @$now $DIR/$tdir
3738
3739         atime=$(stat -c %X $DIR/$tdir)
3740         [ "$atime" -eq "$now"  ] ||
3741                 error "atime is not updated from future: $atime, $now"
3742
3743         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3744         sleep 3
3745
3746         # test setting directory atime when now > dir atime + atime_diff
3747         local d1=$(date +%s)
3748         ls $DIR/$tdir
3749         local d2=$(date +%s)
3750         cancel_lru_locks mdc
3751         atime=$(stat -c %X $DIR/$tdir)
3752         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3753                 error "atime is not updated  : $atime, should be $d2"
3754
3755         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3756         sleep 3
3757
3758         # test not setting directory atime when now < dir atime + atime_diff
3759         ls $DIR/$tdir
3760         cancel_lru_locks mdc
3761         atime=$(stat -c %X $DIR/$tdir)
3762         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3763                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3764
3765         do_facet $SINGLEMDS \
3766                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3767 }
3768 run_test 39l "directory atime update ==========================="
3769
3770 test_39m() {
3771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3772
3773         touch $DIR1/$tfile
3774         sleep 2
3775         local far_past_mtime=$(date -d "May 29 1953" +%s)
3776         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3777
3778         touch -m -d @$far_past_mtime $DIR1/$tfile
3779         touch -a -d @$far_past_atime $DIR1/$tfile
3780
3781         for (( i=0; i < 2; i++ )) ; do
3782                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3783                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3784                         error "atime or mtime set incorrectly"
3785
3786                 cancel_lru_locks $OSC
3787                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3788         done
3789 }
3790 run_test 39m "test atime and mtime before 1970"
3791
3792 test_39n() { # LU-3832
3793         remote_mds_nodsh && skip "remote MDS with nodsh"
3794
3795         local atime_diff=$(do_facet $SINGLEMDS \
3796                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3797         local atime0
3798         local atime1
3799         local atime2
3800
3801         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3802
3803         rm -rf $DIR/$tfile
3804         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3805         atime0=$(stat -c %X $DIR/$tfile)
3806
3807         sleep 5
3808         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3809         atime1=$(stat -c %X $DIR/$tfile)
3810
3811         sleep 5
3812         cancel_lru_locks mdc
3813         cancel_lru_locks osc
3814         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3815         atime2=$(stat -c %X $DIR/$tfile)
3816
3817         do_facet $SINGLEMDS \
3818                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3819
3820         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3821         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3822 }
3823 run_test 39n "check that O_NOATIME is honored"
3824
3825 test_39o() {
3826         TESTDIR=$DIR/$tdir/$tfile
3827         [ -e $TESTDIR ] && rm -rf $TESTDIR
3828         mkdir -p $TESTDIR
3829         cd $TESTDIR
3830         links1=2
3831         ls
3832         mkdir a b
3833         ls
3834         links2=$(stat -c %h .)
3835         [ $(($links1 + 2)) != $links2 ] &&
3836                 error "wrong links count $(($links1 + 2)) != $links2"
3837         rmdir b
3838         links3=$(stat -c %h .)
3839         [ $(($links1 + 1)) != $links3 ] &&
3840                 error "wrong links count $links1 != $links3"
3841         return 0
3842 }
3843 run_test 39o "directory cached attributes updated after create"
3844
3845 test_39p() {
3846         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3847
3848         local MDTIDX=1
3849         TESTDIR=$DIR/$tdir/$tdir
3850         [ -e $TESTDIR ] && rm -rf $TESTDIR
3851         test_mkdir -p $TESTDIR
3852         cd $TESTDIR
3853         links1=2
3854         ls
3855         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3856         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3857         ls
3858         links2=$(stat -c %h .)
3859         [ $(($links1 + 2)) != $links2 ] &&
3860                 error "wrong links count $(($links1 + 2)) != $links2"
3861         rmdir remote_dir2
3862         links3=$(stat -c %h .)
3863         [ $(($links1 + 1)) != $links3 ] &&
3864                 error "wrong links count $links1 != $links3"
3865         return 0
3866 }
3867 run_test 39p "remote directory cached attributes updated after create ========"
3868
3869
3870 test_39q() { # LU-8041
3871         local testdir=$DIR/$tdir
3872         mkdir -p $testdir
3873         multiop_bg_pause $testdir D_c || error "multiop failed"
3874         local multipid=$!
3875         cancel_lru_locks mdc
3876         kill -USR1 $multipid
3877         local atime=$(stat -c %X $testdir)
3878         [ "$atime" -ne 0 ] || error "atime is zero"
3879 }
3880 run_test 39q "close won't zero out atime"
3881
3882 test_40() {
3883         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3884         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3885                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3886         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3887                 error "$tfile is not 4096 bytes in size"
3888 }
3889 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3890
3891 test_41() {
3892         # bug 1553
3893         small_write $DIR/f41 18
3894 }
3895 run_test 41 "test small file write + fstat ====================="
3896
3897 count_ost_writes() {
3898         lctl get_param -n ${OSC}.*.stats |
3899                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3900                         END { printf("%0.0f", writes) }'
3901 }
3902
3903 # decent default
3904 WRITEBACK_SAVE=500
3905 DIRTY_RATIO_SAVE=40
3906 MAX_DIRTY_RATIO=50
3907 BG_DIRTY_RATIO_SAVE=10
3908 MAX_BG_DIRTY_RATIO=25
3909
3910 start_writeback() {
3911         trap 0
3912         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3913         # dirty_ratio, dirty_background_ratio
3914         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3915                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3916                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3917                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3918         else
3919                 # if file not here, we are a 2.4 kernel
3920                 kill -CONT `pidof kupdated`
3921         fi
3922 }
3923
3924 stop_writeback() {
3925         # setup the trap first, so someone cannot exit the test at the
3926         # exact wrong time and mess up a machine
3927         trap start_writeback EXIT
3928         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3929         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3930                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3931                 sysctl -w vm.dirty_writeback_centisecs=0
3932                 sysctl -w vm.dirty_writeback_centisecs=0
3933                 # save and increase /proc/sys/vm/dirty_ratio
3934                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3935                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3936                 # save and increase /proc/sys/vm/dirty_background_ratio
3937                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3938                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3939         else
3940                 # if file not here, we are a 2.4 kernel
3941                 kill -STOP `pidof kupdated`
3942         fi
3943 }
3944
3945 # ensure that all stripes have some grant before we test client-side cache
3946 setup_test42() {
3947         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3948                 dd if=/dev/zero of=$i bs=4k count=1
3949                 rm $i
3950         done
3951 }
3952
3953 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3954 # file truncation, and file removal.
3955 test_42a() {
3956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3957
3958         setup_test42
3959         cancel_lru_locks $OSC
3960         stop_writeback
3961         sync; sleep 1; sync # just to be safe
3962         BEFOREWRITES=`count_ost_writes`
3963         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3964         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3965         AFTERWRITES=`count_ost_writes`
3966         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3967                 error "$BEFOREWRITES < $AFTERWRITES"
3968         start_writeback
3969 }
3970 run_test 42a "ensure that we don't flush on close"
3971
3972 test_42b() {
3973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3974
3975         setup_test42
3976         cancel_lru_locks $OSC
3977         stop_writeback
3978         sync
3979         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3980         BEFOREWRITES=$(count_ost_writes)
3981         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3982         AFTERWRITES=$(count_ost_writes)
3983         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3984                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3985         fi
3986         BEFOREWRITES=$(count_ost_writes)
3987         sync || error "sync: $?"
3988         AFTERWRITES=$(count_ost_writes)
3989         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3990                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3991         fi
3992         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3993         start_writeback
3994         return 0
3995 }
3996 run_test 42b "test destroy of file with cached dirty data ======"
3997
3998 # if these tests just want to test the effect of truncation,
3999 # they have to be very careful.  consider:
4000 # - the first open gets a {0,EOF}PR lock
4001 # - the first write conflicts and gets a {0, count-1}PW
4002 # - the rest of the writes are under {count,EOF}PW
4003 # - the open for truncate tries to match a {0,EOF}PR
4004 #   for the filesize and cancels the PWs.
4005 # any number of fixes (don't get {0,EOF} on open, match
4006 # composite locks, do smarter file size management) fix
4007 # this, but for now we want these tests to verify that
4008 # the cancellation with truncate intent works, so we
4009 # start the file with a full-file pw lock to match against
4010 # until the truncate.
4011 trunc_test() {
4012         test=$1
4013         file=$DIR/$test
4014         offset=$2
4015         cancel_lru_locks $OSC
4016         stop_writeback
4017         # prime the file with 0,EOF PW to match
4018         touch $file
4019         $TRUNCATE $file 0
4020         sync; sync
4021         # now the real test..
4022         dd if=/dev/zero of=$file bs=1024 count=100
4023         BEFOREWRITES=`count_ost_writes`
4024         $TRUNCATE $file $offset
4025         cancel_lru_locks $OSC
4026         AFTERWRITES=`count_ost_writes`
4027         start_writeback
4028 }
4029
4030 test_42c() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032
4033         trunc_test 42c 1024
4034         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4035                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4036         rm $file
4037 }
4038 run_test 42c "test partial truncate of file with cached dirty data"
4039
4040 test_42d() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         trunc_test 42d 0
4044         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4045                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4046         rm $file
4047 }
4048 run_test 42d "test complete truncate of file with cached dirty data"
4049
4050 test_42e() { # bug22074
4051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4052
4053         local TDIR=$DIR/${tdir}e
4054         local pages=16 # hardcoded 16 pages, don't change it.
4055         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4056         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4057         local max_dirty_mb
4058         local warmup_files
4059
4060         test_mkdir $DIR/${tdir}e
4061         $LFS setstripe -c 1 $TDIR
4062         createmany -o $TDIR/f $files
4063
4064         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4065
4066         # we assume that with $OSTCOUNT files, at least one of them will
4067         # be allocated on OST0.
4068         warmup_files=$((OSTCOUNT * max_dirty_mb))
4069         createmany -o $TDIR/w $warmup_files
4070
4071         # write a large amount of data into one file and sync, to get good
4072         # avail_grant number from OST.
4073         for ((i=0; i<$warmup_files; i++)); do
4074                 idx=$($LFS getstripe -i $TDIR/w$i)
4075                 [ $idx -ne 0 ] && continue
4076                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4077                 break
4078         done
4079         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4080         sync
4081         $LCTL get_param $proc_osc0/cur_dirty_bytes
4082         $LCTL get_param $proc_osc0/cur_grant_bytes
4083
4084         # create as much dirty pages as we can while not to trigger the actual
4085         # RPCs directly. but depends on the env, VFS may trigger flush during this
4086         # period, hopefully we are good.
4087         for ((i=0; i<$warmup_files; i++)); do
4088                 idx=$($LFS getstripe -i $TDIR/w$i)
4089                 [ $idx -ne 0 ] && continue
4090                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4091         done
4092         $LCTL get_param $proc_osc0/cur_dirty_bytes
4093         $LCTL get_param $proc_osc0/cur_grant_bytes
4094
4095         # perform the real test
4096         $LCTL set_param $proc_osc0/rpc_stats 0
4097         for ((;i<$files; i++)); do
4098                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4099                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4100         done
4101         sync
4102         $LCTL get_param $proc_osc0/rpc_stats
4103
4104         local percent=0
4105         local have_ppr=false
4106         $LCTL get_param $proc_osc0/rpc_stats |
4107                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4108                         # skip lines until we are at the RPC histogram data
4109                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4110                         $have_ppr || continue
4111
4112                         # we only want the percent stat for < 16 pages
4113                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4114
4115                         percent=$((percent + WPCT))
4116                         if [[ $percent -gt 15 ]]; then
4117                                 error "less than 16-pages write RPCs" \
4118                                       "$percent% > 15%"
4119                                 break
4120                         fi
4121                 done
4122         rm -rf $TDIR
4123 }
4124 run_test 42e "verify sub-RPC writes are not done synchronously"
4125
4126 test_43A() { # was test_43
4127         test_mkdir $DIR/$tdir
4128         cp -p /bin/ls $DIR/$tdir/$tfile
4129         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4130         pid=$!
4131         # give multiop a chance to open
4132         sleep 1
4133
4134         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4135         kill -USR1 $pid
4136 }
4137 run_test 43A "execution of file opened for write should return -ETXTBSY"
4138
4139 test_43a() {
4140         test_mkdir $DIR/$tdir
4141         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4142                 cp -p multiop $DIR/$tdir/multiop
4143         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4144                 error "multiop open $TMP/$tfile.junk failed"
4145         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4146         MULTIOP_PID=$!
4147         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4148         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4149         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4150 }
4151 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4152
4153 test_43b() {
4154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4155
4156         test_mkdir $DIR/$tdir
4157         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4158                 cp -p multiop $DIR/$tdir/multiop
4159         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4160                 error "multiop open $TMP/$tfile.junk failed"
4161         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4162         MULTIOP_PID=$!
4163         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4164         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4165         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4166 }
4167 run_test 43b "truncate of file being executed should return -ETXTBSY"
4168
4169 test_43c() {
4170         local testdir="$DIR/$tdir"
4171         test_mkdir $testdir
4172         cp $SHELL $testdir/
4173         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4174                 ( cd $testdir && md5sum -c )
4175 }
4176 run_test 43c "md5sum of copy into lustre"
4177
4178 test_44A() { # was test_44
4179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4180
4181         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4182         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4183 }
4184 run_test 44A "zero length read from a sparse stripe"
4185
4186 test_44a() {
4187         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4188                 awk '{ print $2 }')
4189         [ -z "$nstripe" ] && skip "can't get stripe info"
4190         [[ $nstripe -gt $OSTCOUNT ]] &&
4191                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4192
4193         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4194                 awk '{ print $2 }')
4195         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4196                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4197                         awk '{ print $2 }')
4198         fi
4199
4200         OFFSETS="0 $((stride/2)) $((stride-1))"
4201         for offset in $OFFSETS; do
4202                 for i in $(seq 0 $((nstripe-1))); do
4203                         local GLOBALOFFSETS=""
4204                         # size in Bytes
4205                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4206                         local myfn=$DIR/d44a-$size
4207                         echo "--------writing $myfn at $size"
4208                         ll_sparseness_write $myfn $size ||
4209                                 error "ll_sparseness_write"
4210                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4211                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4212                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4213
4214                         for j in $(seq 0 $((nstripe-1))); do
4215                                 # size in Bytes
4216                                 size=$((((j + $nstripe )*$stride + $offset)))
4217                                 ll_sparseness_write $myfn $size ||
4218                                         error "ll_sparseness_write"
4219                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4220                         done
4221                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4222                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4223                         rm -f $myfn
4224                 done
4225         done
4226 }
4227 run_test 44a "test sparse pwrite ==============================="
4228
4229 dirty_osc_total() {
4230         tot=0
4231         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4232                 tot=$(($tot + $d))
4233         done
4234         echo $tot
4235 }
4236 do_dirty_record() {
4237         before=`dirty_osc_total`
4238         echo executing "\"$*\""
4239         eval $*
4240         after=`dirty_osc_total`
4241         echo before $before, after $after
4242 }
4243 test_45() {
4244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4245
4246         f="$DIR/f45"
4247         # Obtain grants from OST if it supports it
4248         echo blah > ${f}_grant
4249         stop_writeback
4250         sync
4251         do_dirty_record "echo blah > $f"
4252         [[ $before -eq $after ]] && error "write wasn't cached"
4253         do_dirty_record "> $f"
4254         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4255         do_dirty_record "echo blah > $f"
4256         [[ $before -eq $after ]] && error "write wasn't cached"
4257         do_dirty_record "sync"
4258         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4259         do_dirty_record "echo blah > $f"
4260         [[ $before -eq $after ]] && error "write wasn't cached"
4261         do_dirty_record "cancel_lru_locks osc"
4262         [[ $before -gt $after ]] ||
4263                 error "lock cancellation didn't lower dirty count"
4264         start_writeback
4265 }
4266 run_test 45 "osc io page accounting ============================"
4267
4268 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4269 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4270 # objects offset and an assert hit when an rpc was built with 1023's mapped
4271 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4272 test_46() {
4273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4274
4275         f="$DIR/f46"
4276         stop_writeback
4277         sync
4278         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4279         sync
4280         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4281         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4282         sync
4283         start_writeback
4284 }
4285 run_test 46 "dirtying a previously written page ================"
4286
4287 # test_47 is removed "Device nodes check" is moved to test_28
4288
4289 test_48a() { # bug 2399
4290         [ "$mds1_FSTYPE" = "zfs" ] &&
4291         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4292                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4293
4294         test_mkdir $DIR/$tdir
4295         cd $DIR/$tdir
4296         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4297         test_mkdir $DIR/$tdir
4298         touch foo || error "'touch foo' failed after recreating cwd"
4299         test_mkdir bar
4300         touch .foo || error "'touch .foo' failed after recreating cwd"
4301         test_mkdir .bar
4302         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4303         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4304         cd . || error "'cd .' failed after recreating cwd"
4305         mkdir . && error "'mkdir .' worked after recreating cwd"
4306         rmdir . && error "'rmdir .' worked after recreating cwd"
4307         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4308         cd .. || error "'cd ..' failed after recreating cwd"
4309 }
4310 run_test 48a "Access renamed working dir (should return errors)="
4311
4312 test_48b() { # bug 2399
4313         rm -rf $DIR/$tdir
4314         test_mkdir $DIR/$tdir
4315         cd $DIR/$tdir
4316         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4317         touch foo && error "'touch foo' worked after removing cwd"
4318         mkdir foo && error "'mkdir foo' worked after removing cwd"
4319         touch .foo && error "'touch .foo' worked after removing cwd"
4320         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4321         ls . > /dev/null && error "'ls .' worked after removing cwd"
4322         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4323         mkdir . && error "'mkdir .' worked after removing cwd"
4324         rmdir . && error "'rmdir .' worked after removing cwd"
4325         ln -s . foo && error "'ln -s .' worked after removing cwd"
4326         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4327 }
4328 run_test 48b "Access removed working dir (should return errors)="
4329
4330 test_48c() { # bug 2350
4331         #lctl set_param debug=-1
4332         #set -vx
4333         rm -rf $DIR/$tdir
4334         test_mkdir -p $DIR/$tdir/dir
4335         cd $DIR/$tdir/dir
4336         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4337         $TRACE touch foo && error "touch foo worked after removing cwd"
4338         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4339         touch .foo && error "touch .foo worked after removing cwd"
4340         mkdir .foo && error "mkdir .foo worked after removing cwd"
4341         $TRACE ls . && error "'ls .' worked after removing cwd"
4342         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4343         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4344         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4345         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4346         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4347 }
4348 run_test 48c "Access removed working subdir (should return errors)"
4349
4350 test_48d() { # bug 2350
4351         #lctl set_param debug=-1
4352         #set -vx
4353         rm -rf $DIR/$tdir
4354         test_mkdir -p $DIR/$tdir/dir
4355         cd $DIR/$tdir/dir
4356         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4357         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4358         $TRACE touch foo && error "'touch foo' worked after removing parent"
4359         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4360         touch .foo && error "'touch .foo' worked after removing parent"
4361         mkdir .foo && error "mkdir .foo worked after removing parent"
4362         $TRACE ls . && error "'ls .' worked after removing parent"
4363         $TRACE ls .. && error "'ls ..' worked after removing parent"
4364         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4365         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4366         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4367         true
4368 }
4369 run_test 48d "Access removed parent subdir (should return errors)"
4370
4371 test_48e() { # bug 4134
4372         #lctl set_param debug=-1
4373         #set -vx
4374         rm -rf $DIR/$tdir
4375         test_mkdir -p $DIR/$tdir/dir
4376         cd $DIR/$tdir/dir
4377         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4378         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4379         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4380         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4381         # On a buggy kernel addition of "touch foo" after cd .. will
4382         # produce kernel oops in lookup_hash_it
4383         touch ../foo && error "'cd ..' worked after recreate parent"
4384         cd $DIR
4385         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4386 }
4387 run_test 48e "Access to recreated parent subdir (should return errors)"
4388
4389 test_49() { # LU-1030
4390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4391         remote_ost_nodsh && skip "remote OST with nodsh"
4392
4393         # get ost1 size - lustre-OST0000
4394         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4395                 awk '{ print $4 }')
4396         # write 800M at maximum
4397         [[ $ost1_size -lt 2 ]] && ost1_size=2
4398         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4399
4400         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4401         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4402         local dd_pid=$!
4403
4404         # change max_pages_per_rpc while writing the file
4405         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4406         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4407         # loop until dd process exits
4408         while ps ax -opid | grep -wq $dd_pid; do
4409                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4410                 sleep $((RANDOM % 5 + 1))
4411         done
4412         # restore original max_pages_per_rpc
4413         $LCTL set_param $osc1_mppc=$orig_mppc
4414         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4415 }
4416 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4417
4418 test_50() {
4419         # bug 1485
4420         test_mkdir $DIR/$tdir
4421         cd $DIR/$tdir
4422         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4423 }
4424 run_test 50 "special situations: /proc symlinks  ==============="
4425
4426 test_51a() {    # was test_51
4427         # bug 1516 - create an empty entry right after ".." then split dir
4428         test_mkdir -c1 $DIR/$tdir
4429         touch $DIR/$tdir/foo
4430         $MCREATE $DIR/$tdir/bar
4431         rm $DIR/$tdir/foo
4432         createmany -m $DIR/$tdir/longfile 201
4433         FNUM=202
4434         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4435                 $MCREATE $DIR/$tdir/longfile$FNUM
4436                 FNUM=$(($FNUM + 1))
4437                 echo -n "+"
4438         done
4439         echo
4440         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4441 }
4442 run_test 51a "special situations: split htree with empty entry =="
4443
4444 cleanup_print_lfs_df () {
4445         trap 0
4446         $LFS df
4447         $LFS df -i
4448 }
4449
4450 test_51b() {
4451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4452
4453         local dir=$DIR/$tdir
4454         local nrdirs=$((65536 + 100))
4455
4456         # cleanup the directory
4457         rm -fr $dir
4458
4459         test_mkdir -c1 $dir
4460
4461         $LFS df
4462         $LFS df -i
4463         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4464         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4465         [[ $numfree -lt $nrdirs ]] &&
4466                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4467
4468         # need to check free space for the directories as well
4469         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4470         numfree=$(( blkfree / $(fs_inode_ksize) ))
4471         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4472
4473         trap cleanup_print_lfs_df EXIT
4474
4475         # create files
4476         createmany -d $dir/d $nrdirs || {
4477                 unlinkmany $dir/d $nrdirs
4478                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4479         }
4480
4481         # really created :
4482         nrdirs=$(ls -U $dir | wc -l)
4483
4484         # unlink all but 100 subdirectories, then check it still works
4485         local left=100
4486         local delete=$((nrdirs - left))
4487
4488         $LFS df
4489         $LFS df -i
4490
4491         # for ldiskfs the nlink count should be 1, but this is OSD specific
4492         # and so this is listed for informational purposes only
4493         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4494         unlinkmany -d $dir/d $delete ||
4495                 error "unlink of first $delete subdirs failed"
4496
4497         echo "nlink between: $(stat -c %h $dir)"
4498         local found=$(ls -U $dir | wc -l)
4499         [ $found -ne $left ] &&
4500                 error "can't find subdirs: found only $found, expected $left"
4501
4502         unlinkmany -d $dir/d $delete $left ||
4503                 error "unlink of second $left subdirs failed"
4504         # regardless of whether the backing filesystem tracks nlink accurately
4505         # or not, the nlink count shouldn't be more than "." and ".." here
4506         local after=$(stat -c %h $dir)
4507         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4508                 echo "nlink after: $after"
4509
4510         cleanup_print_lfs_df
4511 }
4512 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4513
4514 test_51d() {
4515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4516         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4517
4518         test_mkdir $DIR/$tdir
4519         createmany -o $DIR/$tdir/t- 1000
4520         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4521         for N in $(seq 0 $((OSTCOUNT - 1))); do
4522                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4523                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4524                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4525                         '($1 == '$N') { objs += 1 } \
4526                         END { printf("%0.0f", objs) }')
4527                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4528         done
4529         unlinkmany $DIR/$tdir/t- 1000
4530
4531         NLAST=0
4532         for N in $(seq 1 $((OSTCOUNT - 1))); do
4533                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4534                         error "OST $N has less objects vs OST $NLAST" \
4535                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4536                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4537                         error "OST $N has less objects vs OST $NLAST" \
4538                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4539
4540                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4541                         error "OST $N has less #0 objects vs OST $NLAST" \
4542                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4543                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4544                         error "OST $N has less #0 objects vs OST $NLAST" \
4545                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4546                 NLAST=$N
4547         done
4548         rm -f $TMP/$tfile
4549 }
4550 run_test 51d "check object distribution"
4551
4552 test_51e() {
4553         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4554                 skip_env "ldiskfs only test"
4555         fi
4556
4557         test_mkdir -c1 $DIR/$tdir
4558         test_mkdir -c1 $DIR/$tdir/d0
4559
4560         touch $DIR/$tdir/d0/foo
4561         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4562                 error "file exceed 65000 nlink limit!"
4563         unlinkmany $DIR/$tdir/d0/f- 65001
4564         return 0
4565 }
4566 run_test 51e "check file nlink limit"
4567
4568 test_51f() {
4569         test_mkdir $DIR/$tdir
4570
4571         local max=100000
4572         local ulimit_old=$(ulimit -n)
4573         local spare=20 # number of spare fd's for scripts/libraries, etc.
4574         local mdt=$($LFS getstripe -m $DIR/$tdir)
4575         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4576
4577         echo "MDT$mdt numfree=$numfree, max=$max"
4578         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4579         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4580                 while ! ulimit -n $((numfree + spare)); do
4581                         numfree=$((numfree * 3 / 4))
4582                 done
4583                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4584         else
4585                 echo "left ulimit at $ulimit_old"
4586         fi
4587
4588         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4589                 unlinkmany $DIR/$tdir/f $numfree
4590                 error "create+open $numfree files in $DIR/$tdir failed"
4591         }
4592         ulimit -n $ulimit_old
4593
4594         # if createmany exits at 120s there will be fewer than $numfree files
4595         unlinkmany $DIR/$tdir/f $numfree || true
4596 }
4597 run_test 51f "check many open files limit"
4598
4599 test_52a() {
4600         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4601         test_mkdir $DIR/$tdir
4602         touch $DIR/$tdir/foo
4603         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4604         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4605         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4606         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4607         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4608                                         error "link worked"
4609         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4610         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4611         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4612                                                      error "lsattr"
4613         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4614         cp -r $DIR/$tdir $TMP/
4615         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4616 }
4617 run_test 52a "append-only flag test (should return errors)"
4618
4619 test_52b() {
4620         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4621         test_mkdir $DIR/$tdir
4622         touch $DIR/$tdir/foo
4623         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4624         cat test > $DIR/$tdir/foo && error "cat test worked"
4625         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4626         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4627         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4628                                         error "link worked"
4629         echo foo >> $DIR/$tdir/foo && error "echo worked"
4630         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4631         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4632         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4633         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4634                                                         error "lsattr"
4635         chattr -i $DIR/$tdir/foo || error "chattr failed"
4636
4637         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4638 }
4639 run_test 52b "immutable flag test (should return errors) ======="
4640
4641 test_53() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643         remote_mds_nodsh && skip "remote MDS with nodsh"
4644         remote_ost_nodsh && skip "remote OST with nodsh"
4645
4646         local param
4647         local param_seq
4648         local ostname
4649         local mds_last
4650         local mds_last_seq
4651         local ost_last
4652         local ost_last_seq
4653         local ost_last_id
4654         local ostnum
4655         local node
4656         local found=false
4657         local support_last_seq=true
4658
4659         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4660                 support_last_seq=false
4661
4662         # only test MDT0000
4663         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4664         local value
4665         for value in $(do_facet $SINGLEMDS \
4666                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4667                 param=$(echo ${value[0]} | cut -d "=" -f1)
4668                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4669
4670                 if $support_last_seq; then
4671                         param_seq=$(echo $param |
4672                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4673                         mds_last_seq=$(do_facet $SINGLEMDS \
4674                                        $LCTL get_param -n $param_seq)
4675                 fi
4676                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4677
4678                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4679                 node=$(facet_active_host ost$((ostnum+1)))
4680                 param="obdfilter.$ostname.last_id"
4681                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4682                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4683                         ost_last_id=$ost_last
4684
4685                         if $support_last_seq; then
4686                                 ost_last_id=$(echo $ost_last |
4687                                               awk -F':' '{print $2}' |
4688                                               sed -e "s/^0x//g")
4689                                 ost_last_seq=$(echo $ost_last |
4690                                                awk -F':' '{print $1}')
4691                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4692                         fi
4693
4694                         if [[ $ost_last_id != $mds_last ]]; then
4695                                 error "$ost_last_id != $mds_last"
4696                         else
4697                                 found=true
4698                                 break
4699                         fi
4700                 done
4701         done
4702         $found || error "can not match last_seq/last_id for $mdtosc"
4703         return 0
4704 }
4705 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4706
4707 test_54a() {
4708         perl -MSocket -e ';' || skip "no Socket perl module installed"
4709
4710         $SOCKETSERVER $DIR/socket ||
4711                 error "$SOCKETSERVER $DIR/socket failed: $?"
4712         $SOCKETCLIENT $DIR/socket ||
4713                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4714         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4715 }
4716 run_test 54a "unix domain socket test =========================="
4717
4718 test_54b() {
4719         f="$DIR/f54b"
4720         mknod $f c 1 3
4721         chmod 0666 $f
4722         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4723 }
4724 run_test 54b "char device works in lustre ======================"
4725
4726 find_loop_dev() {
4727         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4728         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4729         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4730
4731         for i in $(seq 3 7); do
4732                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4733                 LOOPDEV=$LOOPBASE$i
4734                 LOOPNUM=$i
4735                 break
4736         done
4737 }
4738
4739 cleanup_54c() {
4740         local rc=0
4741         loopdev="$DIR/loop54c"
4742
4743         trap 0
4744         $UMOUNT $DIR/$tdir || rc=$?
4745         losetup -d $loopdev || true
4746         losetup -d $LOOPDEV || true
4747         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4748         return $rc
4749 }
4750
4751 test_54c() {
4752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4753
4754         loopdev="$DIR/loop54c"
4755
4756         find_loop_dev
4757         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4758         trap cleanup_54c EXIT
4759         mknod $loopdev b 7 $LOOPNUM
4760         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4761         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4762         losetup $loopdev $DIR/$tfile ||
4763                 error "can't set up $loopdev for $DIR/$tfile"
4764         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4765         test_mkdir $DIR/$tdir
4766         mount -t ext2 $loopdev $DIR/$tdir ||
4767                 error "error mounting $loopdev on $DIR/$tdir"
4768         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4769                 error "dd write"
4770         df $DIR/$tdir
4771         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4772                 error "dd read"
4773         cleanup_54c
4774 }
4775 run_test 54c "block device works in lustre ====================="
4776
4777 test_54d() {
4778         f="$DIR/f54d"
4779         string="aaaaaa"
4780         mknod $f p
4781         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4782 }
4783 run_test 54d "fifo device works in lustre ======================"
4784
4785 test_54e() {
4786         f="$DIR/f54e"
4787         string="aaaaaa"
4788         cp -aL /dev/console $f
4789         echo $string > $f || error "echo $string to $f failed"
4790 }
4791 run_test 54e "console/tty device works in lustre ======================"
4792
4793 test_56a() {
4794         local numfiles=3
4795         local dir=$DIR/$tdir
4796
4797         rm -rf $dir
4798         test_mkdir -p $dir/dir
4799         for i in $(seq $numfiles); do
4800                 touch $dir/file$i
4801                 touch $dir/dir/file$i
4802         done
4803
4804         local numcomp=$($LFS getstripe --component-count $dir)
4805
4806         [[ $numcomp == 0 ]] && numcomp=1
4807
4808         # test lfs getstripe with --recursive
4809         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4810
4811         [[ $filenum -eq $((numfiles * 2)) ]] ||
4812                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4813         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4814         [[ $filenum -eq $numfiles ]] ||
4815                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4816         echo "$LFS getstripe showed obdidx or l_ost_idx"
4817
4818         # test lfs getstripe with file instead of dir
4819         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4820         [[ $filenum -eq 1 ]] ||
4821                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4822         echo "$LFS getstripe file1 passed"
4823
4824         #test lfs getstripe with --verbose
4825         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4826         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4827                 error "$LFS getstripe --verbose $dir: "\
4828                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4829         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4830                 error "$LFS getstripe $dir: showed lmm_magic"
4831
4832         #test lfs getstripe with -v prints lmm_fid
4833         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4834         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4835                 error "$LFS getstripe -v $dir: "\
4836                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4837         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4838                 error "$LFS getstripe $dir: showed lmm_fid by default"
4839         echo "$LFS getstripe --verbose passed"
4840
4841         #check for FID information
4842         local fid1=$($LFS getstripe --fid $dir/file1)
4843         local fid2=$($LFS getstripe --verbose $dir/file1 |
4844                      awk '/lmm_fid: / { print $2; exit; }')
4845         local fid3=$($LFS path2fid $dir/file1)
4846
4847         [ "$fid1" != "$fid2" ] &&
4848                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4849         [ "$fid1" != "$fid3" ] &&
4850                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4851         echo "$LFS getstripe --fid passed"
4852
4853         #test lfs getstripe with --obd
4854         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4855                 error "$LFS getstripe --obd wrong_uuid: should return error"
4856
4857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4858
4859         local ostidx=1
4860         local obduuid=$(ostuuid_from_index $ostidx)
4861         local found=$($LFS getstripe -r --obd $obduuid $dir |
4862                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4863
4864         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4865         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4866                 ((filenum--))
4867         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4868                 ((filenum--))
4869
4870         [[ $found -eq $filenum ]] ||
4871                 error "$LFS getstripe --obd: found $found expect $filenum"
4872         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4873                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4874                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4875                 error "$LFS getstripe --obd: should not show file on other obd"
4876         echo "$LFS getstripe --obd passed"
4877 }
4878 run_test 56a "check $LFS getstripe"
4879
4880 test_56b() {
4881         local dir=$DIR/$tdir
4882         local numdirs=3
4883
4884         test_mkdir $dir
4885         for i in $(seq $numdirs); do
4886                 test_mkdir $dir/dir$i
4887         done
4888
4889         # test lfs getdirstripe default mode is non-recursion, which is
4890         # different from lfs getstripe
4891         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4892
4893         [[ $dircnt -eq 1 ]] ||
4894                 error "$LFS getdirstripe: found $dircnt, not 1"
4895         dircnt=$($LFS getdirstripe --recursive $dir |
4896                 grep -c lmv_stripe_count)
4897         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4898                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4899 }
4900 run_test 56b "check $LFS getdirstripe"
4901
4902 test_56c() {
4903         remote_ost_nodsh && skip "remote OST with nodsh"
4904
4905         local ost_idx=0
4906         local ost_name=$(ostname_from_index $ost_idx)
4907         local old_status=$(ost_dev_status $ost_idx)
4908
4909         [[ -z "$old_status" ]] ||
4910                 skip_env "OST $ost_name is in $old_status status"
4911
4912         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4913         sleep_maxage
4914
4915         local new_status=$(ost_dev_status $ost_idx)
4916
4917         [[ "$new_status" = "D" ]] ||
4918                 error "OST $ost_name is in status of '$new_status', not 'D'"
4919
4920         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4921         sleep_maxage
4922
4923         new_status=$(ost_dev_status $ost_idx)
4924         [[ -z "$new_status" ]] ||
4925                 error "OST $ost_name is in status of '$new_status', not ''"
4926 }
4927 run_test 56c "check 'lfs df' showing device status"
4928
4929 NUMFILES=3
4930 NUMDIRS=3
4931 setup_56() {
4932         local local_tdir="$1"
4933         local local_numfiles="$2"
4934         local local_numdirs="$3"
4935         local dir_params="$4"
4936         local dir_stripe_params="$5"
4937
4938         if [ ! -d "$local_tdir" ] ; then
4939                 test_mkdir -p $dir_stripe_params $local_tdir
4940                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4941                 for i in $(seq $local_numfiles) ; do
4942                         touch $local_tdir/file$i
4943                 done
4944                 for i in $(seq $local_numdirs) ; do
4945                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4946                         for j in $(seq $local_numfiles) ; do
4947                                 touch $local_tdir/dir$i/file$j
4948                         done
4949                 done
4950         fi
4951 }
4952
4953 setup_56_special() {
4954         local local_tdir=$1
4955         local local_numfiles=$2
4956         local local_numdirs=$3
4957
4958         setup_56 $local_tdir $local_numfiles $local_numdirs
4959
4960         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4961                 for i in $(seq $local_numfiles) ; do
4962                         mknod $local_tdir/loop${i}b b 7 $i
4963                         mknod $local_tdir/null${i}c c 1 3
4964                         ln -s $local_tdir/file1 $local_tdir/link${i}
4965                 done
4966                 for i in $(seq $local_numdirs) ; do
4967                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4968                         mknod $local_tdir/dir$i/null${i}c c 1 3
4969                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4970                 done
4971         fi
4972 }
4973
4974 test_56g() {
4975         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4976         local expected=$(($NUMDIRS + 2))
4977
4978         setup_56 $dir $NUMFILES $NUMDIRS
4979
4980         # test lfs find with -name
4981         for i in $(seq $NUMFILES) ; do
4982                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4983
4984                 [ $nums -eq $expected ] ||
4985                         error "lfs find -name '*$i' $dir wrong: "\
4986                               "found $nums, expected $expected"
4987         done
4988 }
4989 run_test 56g "check lfs find -name"
4990
4991 test_56h() {
4992         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4993         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4994
4995         setup_56 $dir $NUMFILES $NUMDIRS
4996
4997         # test lfs find with ! -name
4998         for i in $(seq $NUMFILES) ; do
4999                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5000
5001                 [ $nums -eq $expected ] ||
5002                         error "lfs find ! -name '*$i' $dir wrong: "\
5003                               "found $nums, expected $expected"
5004         done
5005 }
5006 run_test 56h "check lfs find ! -name"
5007
5008 test_56i() {
5009         local dir=$DIR/$tdir
5010
5011         test_mkdir $dir
5012
5013         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5014         local out=$($cmd)
5015
5016         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5017 }
5018 run_test 56i "check 'lfs find -ost UUID' skips directories"
5019
5020 test_56j() {
5021         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5022
5023         setup_56_special $dir $NUMFILES $NUMDIRS
5024
5025         local expected=$((NUMDIRS + 1))
5026         local cmd="$LFS find -type d $dir"
5027         local nums=$($cmd | wc -l)
5028
5029         [ $nums -eq $expected ] ||
5030                 error "'$cmd' wrong: found $nums, expected $expected"
5031 }
5032 run_test 56j "check lfs find -type d"
5033
5034 test_56k() {
5035         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5036
5037         setup_56_special $dir $NUMFILES $NUMDIRS
5038
5039         local expected=$(((NUMDIRS + 1) * NUMFILES))
5040         local cmd="$LFS find -type f $dir"
5041         local nums=$($cmd | wc -l)
5042
5043         [ $nums -eq $expected ] ||
5044                 error "'$cmd' wrong: found $nums, expected $expected"
5045 }
5046 run_test 56k "check lfs find -type f"
5047
5048 test_56l() {
5049         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5050
5051         setup_56_special $dir $NUMFILES $NUMDIRS
5052
5053         local expected=$((NUMDIRS + NUMFILES))
5054         local cmd="$LFS find -type b $dir"
5055         local nums=$($cmd | wc -l)
5056
5057         [ $nums -eq $expected ] ||
5058                 error "'$cmd' wrong: found $nums, expected $expected"
5059 }
5060 run_test 56l "check lfs find -type b"
5061
5062 test_56m() {
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 c $dir"
5069         local nums=$($cmd | wc -l)
5070         [ $nums -eq $expected ] ||
5071                 error "'$cmd' wrong: found $nums, expected $expected"
5072 }
5073 run_test 56m "check lfs find -type c"
5074
5075 test_56n() {
5076         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5077         setup_56_special $dir $NUMFILES $NUMDIRS
5078
5079         local expected=$((NUMDIRS + NUMFILES))
5080         local cmd="$LFS find -type l $dir"
5081         local nums=$($cmd | wc -l)
5082
5083         [ $nums -eq $expected ] ||
5084                 error "'$cmd' wrong: found $nums, expected $expected"
5085 }
5086 run_test 56n "check lfs find -type l"
5087
5088 test_56o() {
5089         local dir=$DIR/$tdir
5090
5091         setup_56 $dir $NUMFILES $NUMDIRS
5092         utime $dir/file1 > /dev/null || error "utime (1)"
5093         utime $dir/file2 > /dev/null || error "utime (2)"
5094         utime $dir/dir1 > /dev/null || error "utime (3)"
5095         utime $dir/dir2 > /dev/null || error "utime (4)"
5096         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5097         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5098
5099         local expected=4
5100         local nums=$($LFS find -mtime +0 $dir | wc -l)
5101
5102         [ $nums -eq $expected ] ||
5103                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5104
5105         expected=12
5106         cmd="$LFS find -mtime 0 $dir"
5107         nums=$($cmd | wc -l)
5108         [ $nums -eq $expected ] ||
5109                 error "'$cmd' wrong: found $nums, expected $expected"
5110 }
5111 run_test 56o "check lfs find -mtime for old files"
5112
5113 test_56ob() {
5114         local dir=$DIR/$tdir
5115         local expected=1
5116         local count=0
5117
5118         # just to make sure there is something that won't be found
5119         test_mkdir $dir
5120         touch $dir/$tfile.now
5121
5122         for age in year week day hour min; do
5123                 count=$((count + 1))
5124
5125                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5126                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5127                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5128
5129                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5130                 local nums=$($cmd | wc -l)
5131                 [ $nums -eq $expected ] ||
5132                         error "'$cmd' wrong: found $nums, expected $expected"
5133
5134                 cmd="$LFS find $dir -atime $count${age:0:1}"
5135                 nums=$($cmd | wc -l)
5136                 [ $nums -eq $expected ] ||
5137                         error "'$cmd' wrong: found $nums, expected $expected"
5138         done
5139
5140         sleep 2
5141         cmd="$LFS find $dir -ctime +1s -type f"
5142         nums=$($cmd | wc -l)
5143         (( $nums == $count * 2 + 1)) ||
5144                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5145 }
5146 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5147
5148 test_56p() {
5149         [ $RUNAS_ID -eq $UID ] &&
5150                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5151
5152         local dir=$DIR/$tdir
5153
5154         setup_56 $dir $NUMFILES $NUMDIRS
5155         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5156
5157         local expected=$NUMFILES
5158         local cmd="$LFS find -uid $RUNAS_ID $dir"
5159         local nums=$($cmd | wc -l)
5160
5161         [ $nums -eq $expected ] ||
5162                 error "'$cmd' wrong: found $nums, expected $expected"
5163
5164         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5165         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5166         nums=$($cmd | wc -l)
5167         [ $nums -eq $expected ] ||
5168                 error "'$cmd' wrong: found $nums, expected $expected"
5169 }
5170 run_test 56p "check lfs find -uid and ! -uid"
5171
5172 test_56q() {
5173         [ $RUNAS_ID -eq $UID ] &&
5174                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5175
5176         local dir=$DIR/$tdir
5177
5178         setup_56 $dir $NUMFILES $NUMDIRS
5179         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5180
5181         local expected=$NUMFILES
5182         local cmd="$LFS find -gid $RUNAS_GID $dir"
5183         local nums=$($cmd | wc -l)
5184
5185         [ $nums -eq $expected ] ||
5186                 error "'$cmd' wrong: found $nums, expected $expected"
5187
5188         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5189         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5190         nums=$($cmd | wc -l)
5191         [ $nums -eq $expected ] ||
5192                 error "'$cmd' wrong: found $nums, expected $expected"
5193 }
5194 run_test 56q "check lfs find -gid and ! -gid"
5195
5196 test_56r() {
5197         local dir=$DIR/$tdir
5198
5199         setup_56 $dir $NUMFILES $NUMDIRS
5200
5201         local expected=12
5202         local cmd="$LFS find -size 0 -type f $dir"
5203         local nums=$($cmd | wc -l)
5204
5205         [ $nums -eq $expected ] ||
5206                 error "'$cmd' wrong: found $nums, expected $expected"
5207         expected=0
5208         cmd="$LFS find ! -size 0 -type f $dir"
5209         nums=$($cmd | wc -l)
5210         [ $nums -eq $expected ] ||
5211                 error "'$cmd' wrong: found $nums, expected $expected"
5212         echo "test" > $dir/$tfile
5213         echo "test2" > $dir/$tfile.2 && sync
5214         expected=1
5215         cmd="$LFS find -size 5 -type f $dir"
5216         nums=$($cmd | wc -l)
5217         [ $nums -eq $expected ] ||
5218                 error "'$cmd' wrong: found $nums, expected $expected"
5219         expected=1
5220         cmd="$LFS find -size +5 -type f $dir"
5221         nums=$($cmd | wc -l)
5222         [ $nums -eq $expected ] ||
5223                 error "'$cmd' wrong: found $nums, expected $expected"
5224         expected=2
5225         cmd="$LFS find -size +0 -type f $dir"
5226         nums=$($cmd | wc -l)
5227         [ $nums -eq $expected ] ||
5228                 error "'$cmd' wrong: found $nums, expected $expected"
5229         expected=2
5230         cmd="$LFS find ! -size -5 -type f $dir"
5231         nums=$($cmd | wc -l)
5232         [ $nums -eq $expected ] ||
5233                 error "'$cmd' wrong: found $nums, expected $expected"
5234         expected=12
5235         cmd="$LFS find -size -5 -type f $dir"
5236         nums=$($cmd | wc -l)
5237         [ $nums -eq $expected ] ||
5238                 error "'$cmd' wrong: found $nums, expected $expected"
5239 }
5240 run_test 56r "check lfs find -size works"
5241
5242 test_56s() { # LU-611 #LU-9369
5243         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5244
5245         local dir=$DIR/$tdir
5246         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5247
5248         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5249         for i in $(seq $NUMDIRS); do
5250                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5251         done
5252
5253         local expected=$NUMDIRS
5254         local cmd="$LFS find -c $OSTCOUNT $dir"
5255         local nums=$($cmd | wc -l)
5256
5257         [ $nums -eq $expected ] || {
5258                 $LFS getstripe -R $dir
5259                 error "'$cmd' wrong: found $nums, expected $expected"
5260         }
5261
5262         expected=$((NUMDIRS + onestripe))
5263         cmd="$LFS find -stripe-count +0 -type f $dir"
5264         nums=$($cmd | wc -l)
5265         [ $nums -eq $expected ] || {
5266                 $LFS getstripe -R $dir
5267                 error "'$cmd' wrong: found $nums, expected $expected"
5268         }
5269
5270         expected=$onestripe
5271         cmd="$LFS find -stripe-count 1 -type f $dir"
5272         nums=$($cmd | wc -l)
5273         [ $nums -eq $expected ] || {
5274                 $LFS getstripe -R $dir
5275                 error "'$cmd' wrong: found $nums, expected $expected"
5276         }
5277
5278         cmd="$LFS find -stripe-count -2 -type f $dir"
5279         nums=$($cmd | wc -l)
5280         [ $nums -eq $expected ] || {
5281                 $LFS getstripe -R $dir
5282                 error "'$cmd' wrong: found $nums, expected $expected"
5283         }
5284
5285         expected=0
5286         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5287         nums=$($cmd | wc -l)
5288         [ $nums -eq $expected ] || {
5289                 $LFS getstripe -R $dir
5290                 error "'$cmd' wrong: found $nums, expected $expected"
5291         }
5292 }
5293 run_test 56s "check lfs find -stripe-count works"
5294
5295 test_56t() { # LU-611 #LU-9369
5296         local dir=$DIR/$tdir
5297
5298         setup_56 $dir 0 $NUMDIRS
5299         for i in $(seq $NUMDIRS); do
5300                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5301         done
5302
5303         local expected=$NUMDIRS
5304         local cmd="$LFS find -S 8M $dir"
5305         local nums=$($cmd | wc -l)
5306
5307         [ $nums -eq $expected ] || {
5308                 $LFS getstripe -R $dir
5309                 error "'$cmd' wrong: found $nums, expected $expected"
5310         }
5311         rm -rf $dir
5312
5313         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5314
5315         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5316
5317         expected=$(((NUMDIRS + 1) * NUMFILES))
5318         cmd="$LFS find -stripe-size 512k -type f $dir"
5319         nums=$($cmd | wc -l)
5320         [ $nums -eq $expected ] ||
5321                 error "'$cmd' wrong: found $nums, expected $expected"
5322
5323         cmd="$LFS find -stripe-size +320k -type f $dir"
5324         nums=$($cmd | wc -l)
5325         [ $nums -eq $expected ] ||
5326                 error "'$cmd' wrong: found $nums, expected $expected"
5327
5328         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5329         cmd="$LFS find -stripe-size +200k -type f $dir"
5330         nums=$($cmd | wc -l)
5331         [ $nums -eq $expected ] ||
5332                 error "'$cmd' wrong: found $nums, expected $expected"
5333
5334         cmd="$LFS find -stripe-size -640k -type f $dir"
5335         nums=$($cmd | wc -l)
5336         [ $nums -eq $expected ] ||
5337                 error "'$cmd' wrong: found $nums, expected $expected"
5338
5339         expected=4
5340         cmd="$LFS find -stripe-size 256k -type f $dir"
5341         nums=$($cmd | wc -l)
5342         [ $nums -eq $expected ] ||
5343                 error "'$cmd' wrong: found $nums, expected $expected"
5344
5345         cmd="$LFS find -stripe-size -320k -type f $dir"
5346         nums=$($cmd | wc -l)
5347         [ $nums -eq $expected ] ||
5348                 error "'$cmd' wrong: found $nums, expected $expected"
5349
5350         expected=0
5351         cmd="$LFS find -stripe-size 1024k -type f $dir"
5352         nums=$($cmd | wc -l)
5353         [ $nums -eq $expected ] ||
5354                 error "'$cmd' wrong: found $nums, expected $expected"
5355 }
5356 run_test 56t "check lfs find -stripe-size works"
5357
5358 test_56u() { # LU-611
5359         local dir=$DIR/$tdir
5360
5361         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5362
5363         if [[ $OSTCOUNT -gt 1 ]]; then
5364                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5365                 onestripe=4
5366         else
5367                 onestripe=0
5368         fi
5369
5370         local expected=$(((NUMDIRS + 1) * NUMFILES))
5371         local cmd="$LFS find -stripe-index 0 -type f $dir"
5372         local nums=$($cmd | wc -l)
5373
5374         [ $nums -eq $expected ] ||
5375                 error "'$cmd' wrong: found $nums, expected $expected"
5376
5377         expected=$onestripe
5378         cmd="$LFS find -stripe-index 1 -type f $dir"
5379         nums=$($cmd | wc -l)
5380         [ $nums -eq $expected ] ||
5381                 error "'$cmd' wrong: found $nums, expected $expected"
5382
5383         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5384         nums=$($cmd | wc -l)
5385         [ $nums -eq $expected ] ||
5386                 error "'$cmd' wrong: found $nums, expected $expected"
5387
5388         expected=0
5389         # This should produce an error and not return any files
5390         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5391         nums=$($cmd 2>/dev/null | wc -l)
5392         [ $nums -eq $expected ] ||
5393                 error "'$cmd' wrong: found $nums, expected $expected"
5394
5395         if [[ $OSTCOUNT -gt 1 ]]; then
5396                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5397                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5398                 nums=$($cmd | wc -l)
5399                 [ $nums -eq $expected ] ||
5400                         error "'$cmd' wrong: found $nums, expected $expected"
5401         fi
5402 }
5403 run_test 56u "check lfs find -stripe-index works"
5404
5405 test_56v() {
5406         local mdt_idx=0
5407         local dir=$DIR/$tdir
5408
5409         setup_56 $dir $NUMFILES $NUMDIRS
5410
5411         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5412         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5413
5414         for file in $($LFS find -m $UUID $dir); do
5415                 file_midx=$($LFS getstripe -m $file)
5416                 [ $file_midx -eq $mdt_idx ] ||
5417                         error "lfs find -m $UUID != getstripe -m $file_midx"
5418         done
5419 }
5420 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5421
5422 test_56w() {
5423         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5425
5426         local dir=$DIR/$tdir
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5429
5430         local stripe_size=$($LFS getstripe -S -d $dir) ||
5431                 error "$LFS getstripe -S -d $dir failed"
5432         stripe_size=${stripe_size%% *}
5433
5434         local file_size=$((stripe_size * OSTCOUNT))
5435         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5436         local required_space=$((file_num * file_size))
5437         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5438                            head -n1)
5439         [[ $free_space -le $((required_space / 1024)) ]] &&
5440                 skip_env "need $required_space, have $free_space kbytes"
5441
5442         local dd_bs=65536
5443         local dd_count=$((file_size / dd_bs))
5444
5445         # write data into the files
5446         local i
5447         local j
5448         local file
5449
5450         for i in $(seq $NUMFILES); do
5451                 file=$dir/file$i
5452                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5453                         error "write data into $file failed"
5454         done
5455         for i in $(seq $NUMDIRS); do
5456                 for j in $(seq $NUMFILES); do
5457                         file=$dir/dir$i/file$j
5458                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5459                                 error "write data into $file failed"
5460                 done
5461         done
5462
5463         # $LFS_MIGRATE will fail if hard link migration is unsupported
5464         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5465                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5466                         error "creating links to $dir/dir1/file1 failed"
5467         fi
5468
5469         local expected=-1
5470
5471         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5472
5473         # lfs_migrate file
5474         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5475
5476         echo "$cmd"
5477         eval $cmd || error "$cmd failed"
5478
5479         check_stripe_count $dir/file1 $expected
5480
5481         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5482         then
5483                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5484                 # OST 1 if it is on OST 0. This file is small enough to
5485                 # be on only one stripe.
5486                 file=$dir/migr_1_ost
5487                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5488                         error "write data into $file failed"
5489                 local obdidx=$($LFS getstripe -i $file)
5490                 local oldmd5=$(md5sum $file)
5491                 local newobdidx=0
5492
5493                 [[ $obdidx -eq 0 ]] && newobdidx=1
5494                 cmd="$LFS migrate -i $newobdidx $file"
5495                 echo $cmd
5496                 eval $cmd || error "$cmd failed"
5497
5498                 local realobdix=$($LFS getstripe -i $file)
5499                 local newmd5=$(md5sum $file)
5500
5501                 [[ $newobdidx -ne $realobdix ]] &&
5502                         error "new OST is different (was=$obdidx, "\
5503                               "wanted=$newobdidx, got=$realobdix)"
5504                 [[ "$oldmd5" != "$newmd5" ]] &&
5505                         error "md5sum differ: $oldmd5, $newmd5"
5506         fi
5507
5508         # lfs_migrate dir
5509         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5510         echo "$cmd"
5511         eval $cmd || error "$cmd failed"
5512
5513         for j in $(seq $NUMFILES); do
5514                 check_stripe_count $dir/dir1/file$j $expected
5515         done
5516
5517         # lfs_migrate works with lfs find
5518         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5519              $LFS_MIGRATE -y -c $expected"
5520         echo "$cmd"
5521         eval $cmd || error "$cmd failed"
5522
5523         for i in $(seq 2 $NUMFILES); do
5524                 check_stripe_count $dir/file$i $expected
5525         done
5526         for i in $(seq 2 $NUMDIRS); do
5527                 for j in $(seq $NUMFILES); do
5528                 check_stripe_count $dir/dir$i/file$j $expected
5529                 done
5530         done
5531 }
5532 run_test 56w "check lfs_migrate -c stripe_count works"
5533
5534 test_56wb() {
5535         local file1=$DIR/$tdir/file1
5536         local create_pool=false
5537         local initial_pool=$($LFS getstripe -p $DIR)
5538         local pool_list=()
5539         local pool=""
5540
5541         echo -n "Creating test dir..."
5542         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5543         echo "done."
5544
5545         echo -n "Creating test file..."
5546         touch $file1 || error "cannot create file"
5547         echo "done."
5548
5549         echo -n "Detecting existing pools..."
5550         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5551
5552         if [ ${#pool_list[@]} -gt 0 ]; then
5553                 echo "${pool_list[@]}"
5554                 for thispool in "${pool_list[@]}"; do
5555                         if [[ -z "$initial_pool" ||
5556                               "$initial_pool" != "$thispool" ]]; then
5557                                 pool="$thispool"
5558                                 echo "Using existing pool '$pool'"
5559                                 break
5560                         fi
5561                 done
5562         else
5563                 echo "none detected."
5564         fi
5565         if [ -z "$pool" ]; then
5566                 pool=${POOL:-testpool}
5567                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5568                 echo -n "Creating pool '$pool'..."
5569                 create_pool=true
5570                 pool_add $pool &> /dev/null ||
5571                         error "pool_add failed"
5572                 echo "done."
5573
5574                 echo -n "Adding target to pool..."
5575                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5576                         error "pool_add_targets failed"
5577                 echo "done."
5578         fi
5579
5580         echo -n "Setting pool using -p option..."
5581         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5582                 error "migrate failed rc = $?"
5583         echo "done."
5584
5585         echo -n "Verifying test file is in pool after migrating..."
5586         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5587                 error "file was not migrated to pool $pool"
5588         echo "done."
5589
5590         echo -n "Removing test file from pool '$pool'..."
5591         $LFS migrate $file1 &> /dev/null ||
5592                 error "cannot remove from pool"
5593         [ "$($LFS getstripe -p $file1)" ] &&
5594                 error "pool still set"
5595         echo "done."
5596
5597         echo -n "Setting pool using --pool option..."
5598         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5599                 error "migrate failed rc = $?"
5600         echo "done."
5601
5602         # Clean up
5603         rm -f $file1
5604         if $create_pool; then
5605                 destroy_test_pools 2> /dev/null ||
5606                         error "destroy test pools failed"
5607         fi
5608 }
5609 run_test 56wb "check lfs_migrate pool support"
5610
5611 test_56wc() {
5612         local file1="$DIR/$tdir/file1"
5613
5614         echo -n "Creating test dir..."
5615         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5616         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5617         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5618                 error "cannot set stripe"
5619         echo "done"
5620
5621         echo -n "Setting initial stripe for test file..."
5622         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5623                 error "cannot set stripe"
5624         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5625                 error "stripe size not set"
5626         echo "done."
5627
5628         # File currently set to -S 512K -c 1
5629
5630         # Ensure -c and -S options are rejected when -R is set
5631         echo -n "Verifying incompatible options are detected..."
5632         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5633                 error "incompatible -c and -R options not detected"
5634         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5635                 error "incompatible -S and -R options not detected"
5636         echo "done."
5637
5638         # Ensure unrecognized options are passed through to 'lfs migrate'
5639         echo -n "Verifying -S option is passed through to lfs migrate..."
5640         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5641                 error "migration failed"
5642         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5643                 error "file was not restriped"
5644         echo "done."
5645
5646         # File currently set to -S 1M -c 1
5647
5648         # Ensure long options are supported
5649         echo -n "Verifying long options supported..."
5650         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5651                 error "long option without argument not supported"
5652         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5653                 error "long option with argument not supported"
5654         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5655                 error "file not restriped with --stripe-size option"
5656         echo "done."
5657
5658         # File currently set to -S 512K -c 1
5659
5660         if [ "$OSTCOUNT" -gt 1 ]; then
5661                 echo -n "Verifying explicit stripe count can be set..."
5662                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5663                         error "migrate failed"
5664                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5665                         error "file not restriped to explicit count"
5666                 echo "done."
5667         fi
5668
5669         # File currently set to -S 512K -c 1 or -S 512K -c 2
5670
5671         # Ensure parent striping is used if -R is set, and no stripe
5672         # count or size is specified
5673         echo -n "Setting stripe for parent directory..."
5674         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5675                 error "cannot set stripe"
5676         echo "done."
5677
5678         echo -n "Verifying restripe option uses parent stripe settings..."
5679         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5680                 error "migrate failed"
5681         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5682                 error "file not restriped to parent settings"
5683         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5684                 error "file not restriped to parent settings"
5685         echo "done."
5686
5687         # File currently set to -S 1M -c 1
5688
5689         # Ensure striping is preserved if -R is not set, and no stripe
5690         # count or size is specified
5691         echo -n "Verifying striping size preserved when not specified..."
5692         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5693         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5694                 error "cannot set stripe on parent directory"
5695         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5696                 error "migrate failed"
5697         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5698                 error "file was restriped"
5699         echo "done."
5700
5701         # Ensure file name properly detected when final option has no argument
5702         echo -n "Verifying file name properly detected..."
5703         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5704                 error "file name interpreted as option argument"
5705         echo "done."
5706
5707         # Clean up
5708         rm -f "$file1"
5709 }
5710 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5711
5712 test_56wd() {
5713         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5714
5715         local file1=$DIR/$tdir/file1
5716
5717         echo -n "Creating test dir..."
5718         test_mkdir $DIR/$tdir || error "cannot create dir"
5719         echo "done."
5720
5721         echo -n "Creating test file..."
5722         touch $file1
5723         echo "done."
5724
5725         # Ensure 'lfs migrate' will fail by using a non-existent option,
5726         # and make sure rsync is not called to recover
5727         echo -n "Make sure --no-rsync option works..."
5728         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5729                 grep -q 'refusing to fall back to rsync' ||
5730                 error "rsync was called with --no-rsync set"
5731         echo "done."
5732
5733         # Ensure rsync is called without trying 'lfs migrate' first
5734         echo -n "Make sure --rsync option works..."
5735         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5736                 grep -q 'falling back to rsync' &&
5737                 error "lfs migrate was called with --rsync set"
5738         echo "done."
5739
5740         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5741         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5742                 grep -q 'at the same time' ||
5743                 error "--rsync and --no-rsync accepted concurrently"
5744         echo "done."
5745
5746         # Clean up
5747         rm -f $file1
5748 }
5749 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5750
5751 test_56x() {
5752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5753         check_swap_layouts_support
5754
5755         local dir=$DIR/$tdir
5756         local ref1=/etc/passwd
5757         local file1=$dir/file1
5758
5759         test_mkdir $dir || error "creating dir $dir"
5760         $LFS setstripe -c 2 $file1
5761         cp $ref1 $file1
5762         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5763         stripe=$($LFS getstripe -c $file1)
5764         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5765         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5766
5767         # clean up
5768         rm -f $file1
5769 }
5770 run_test 56x "lfs migration support"
5771
5772 test_56xa() {
5773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5774         check_swap_layouts_support
5775
5776         local dir=$DIR/$tdir/$testnum
5777
5778         test_mkdir -p $dir
5779
5780         local ref1=/etc/passwd
5781         local file1=$dir/file1
5782
5783         $LFS setstripe -c 2 $file1
5784         cp $ref1 $file1
5785         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5786
5787         local stripe=$($LFS getstripe -c $file1)
5788
5789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5791
5792         # clean up
5793         rm -f $file1
5794 }
5795 run_test 56xa "lfs migration --block support"
5796
5797 check_migrate_links() {
5798         local dir="$1"
5799         local file1="$dir/file1"
5800         local begin="$2"
5801         local count="$3"
5802         local total_count=$(($begin + $count - 1))
5803         local symlink_count=10
5804         local uniq_count=10
5805
5806         if [ ! -f "$file1" ]; then
5807                 echo -n "creating initial file..."
5808                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5809                         error "cannot setstripe initial file"
5810                 echo "done"
5811
5812                 echo -n "creating symlinks..."
5813                 for s in $(seq 1 $symlink_count); do
5814                         ln -s "$file1" "$dir/slink$s" ||
5815                                 error "cannot create symlinks"
5816                 done
5817                 echo "done"
5818
5819                 echo -n "creating nonlinked files..."
5820                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5821                         error "cannot create nonlinked files"
5822                 echo "done"
5823         fi
5824
5825         # create hard links
5826         if [ ! -f "$dir/file$total_count" ]; then
5827                 echo -n "creating hard links $begin:$total_count..."
5828                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5829                         /dev/null || error "cannot create hard links"
5830                 echo "done"
5831         fi
5832
5833         echo -n "checking number of hard links listed in xattrs..."
5834         local fid=$($LFS getstripe -F "$file1")
5835         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5836
5837         echo "${#paths[*]}"
5838         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5839                         skip "hard link list has unexpected size, skipping test"
5840         fi
5841         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5842                         error "link names should exceed xattrs size"
5843         fi
5844
5845         echo -n "migrating files..."
5846         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5847         local rc=$?
5848         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5849         echo "done"
5850
5851         # make sure all links have been properly migrated
5852         echo -n "verifying files..."
5853         fid=$($LFS getstripe -F "$file1") ||
5854                 error "cannot get fid for file $file1"
5855         for i in $(seq 2 $total_count); do
5856                 local fid2=$($LFS getstripe -F $dir/file$i)
5857
5858                 [ "$fid2" == "$fid" ] ||
5859                         error "migrated hard link has mismatched FID"
5860         done
5861
5862         # make sure hard links were properly detected, and migration was
5863         # performed only once for the entire link set; nonlinked files should
5864         # also be migrated
5865         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5866         local expected=$(($uniq_count + 1))
5867
5868         [ "$actual" -eq  "$expected" ] ||
5869                 error "hard links individually migrated ($actual != $expected)"
5870
5871         # make sure the correct number of hard links are present
5872         local hardlinks=$(stat -c '%h' "$file1")
5873
5874         [ $hardlinks -eq $total_count ] ||
5875                 error "num hard links $hardlinks != $total_count"
5876         echo "done"
5877
5878         return 0
5879 }
5880
5881 test_56xb() {
5882         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5883                 skip "Need MDS version at least 2.10.55"
5884
5885         local dir="$DIR/$tdir"
5886
5887         test_mkdir "$dir" || error "cannot create dir $dir"
5888
5889         echo "testing lfs migrate mode when all links fit within xattrs"
5890         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5891
5892         echo "testing rsync mode when all links fit within xattrs"
5893         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5894
5895         echo "testing lfs migrate mode when all links do not fit within xattrs"
5896         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5897
5898         echo "testing rsync mode when all links do not fit within xattrs"
5899         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5900
5901
5902         # clean up
5903         rm -rf $dir
5904 }
5905 run_test 56xb "lfs migration hard link support"
5906
5907 test_56xc() {
5908         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5909
5910         local dir="$DIR/$tdir"
5911
5912         test_mkdir "$dir" || error "cannot create dir $dir"
5913
5914         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5915         echo -n "Setting initial stripe for 20MB test file..."
5916         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5917         echo "done"
5918         echo -n "Sizing 20MB test file..."
5919         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5920         echo "done"
5921         echo -n "Verifying small file autostripe count is 1..."
5922         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5923                 error "cannot migrate 20MB file"
5924         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5925                 error "cannot get stripe for $dir/20mb"
5926         [ $stripe_count -eq 1 ] ||
5927                 error "unexpected stripe count $stripe_count for 20MB file"
5928         rm -f "$dir/20mb"
5929         echo "done"
5930
5931         # Test 2: File is small enough to fit within the available space on
5932         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5933         # have at least an additional 1KB for each desired stripe for test 3
5934         echo -n "Setting stripe for 1GB test file..."
5935         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5936         echo "done"
5937         echo -n "Sizing 1GB test file..."
5938         # File size is 1GB + 3KB
5939         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5940                 error "cannot create 1GB test file"
5941         echo "done"
5942         echo -n "Migrating 1GB file..."
5943         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5944                 error "cannot migrate file"
5945         echo "done"
5946         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5947         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5948                 error "cannot get stripe for $dir/1gb"
5949         [ $stripe_count -eq 2 ] ||
5950                 error "unexpected stripe count $stripe_count (expected 2)"
5951         echo "done"
5952
5953         # Test 3: File is too large to fit within the available space on
5954         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5955         if [ $OSTCOUNT -ge 3 ]; then
5956                 # The required available space is calculated as
5957                 # file size (1GB + 3KB) / OST count (3).
5958                 local kb_per_ost=349526
5959
5960                 echo -n "Migrating 1GB file..."
5961                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5962                         /dev/null || error "cannot migrate file"
5963                 echo "done"
5964
5965                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5966                 echo -n "Verifying autostripe count with limited space..."
5967                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5968                         error "unexpected stripe count $stripe_count (wanted 3)"
5969                 echo "done"
5970         fi
5971
5972         # clean up
5973         rm -rf $dir
5974 }
5975 run_test 56xc "lfs migration autostripe"
5976
5977 test_56y() {
5978         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5979                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5980
5981         local res=""
5982         local dir=$DIR/$tdir
5983         local f1=$dir/file1
5984         local f2=$dir/file2
5985
5986         test_mkdir -p $dir || error "creating dir $dir"
5987         touch $f1 || error "creating std file $f1"
5988         $MULTIOP $f2 H2c || error "creating released file $f2"
5989
5990         # a directory can be raid0, so ask only for files
5991         res=$($LFS find $dir -L raid0 -type f | wc -l)
5992         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5993
5994         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5995         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5996
5997         # only files can be released, so no need to force file search
5998         res=$($LFS find $dir -L released)
5999         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6000
6001         res=$($LFS find $dir -type f \! -L released)
6002         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6003 }
6004 run_test 56y "lfs find -L raid0|released"
6005
6006 test_56z() { # LU-4824
6007         # This checks to make sure 'lfs find' continues after errors
6008         # There are two classes of errors that should be caught:
6009         # - If multiple paths are provided, all should be searched even if one
6010         #   errors out
6011         # - If errors are encountered during the search, it should not terminate
6012         #   early
6013         local dir=$DIR/$tdir
6014         local i
6015
6016         test_mkdir $dir
6017         for i in d{0..9}; do
6018                 test_mkdir $dir/$i
6019         done
6020         touch $dir/d{0..9}/$tfile
6021         $LFS find $DIR/non_existent_dir $dir &&
6022                 error "$LFS find did not return an error"
6023         # Make a directory unsearchable. This should NOT be the last entry in
6024         # directory order.  Arbitrarily pick the 6th entry
6025         chmod 700 $($LFS find $dir -type d | sed '6!d')
6026
6027         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6028
6029         # The user should be able to see 10 directories and 9 files
6030         [ $count == 19 ] || error "$LFS find did not continue after error"
6031 }
6032 run_test 56z "lfs find should continue after an error"
6033
6034 test_56aa() { # LU-5937
6035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6036
6037         local dir=$DIR/$tdir
6038
6039         mkdir $dir
6040         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6041
6042         createmany -o $dir/striped_dir/${tfile}- 1024
6043         local dirs=$($LFS find --size +8k $dir/)
6044
6045         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6046 }
6047 run_test 56aa "lfs find --size under striped dir"
6048
6049 test_56ab() { # LU-10705
6050         test_mkdir $DIR/$tdir
6051         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6052         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6053         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6054         # Flush writes to ensure valid blocks.  Need to be more thorough for
6055         # ZFS, since blocks are not allocated/returned to client immediately.
6056         sync_all_data
6057         wait_zfs_commit ost1 2
6058         cancel_lru_locks osc
6059         ls -ls $DIR/$tdir
6060
6061         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6062
6063         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6064
6065         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6066         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6067
6068         rm -f $DIR/$tdir/$tfile.[123]
6069 }
6070 run_test 56ab "lfs find --blocks"
6071
6072 test_56ba() {
6073         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6074                 skip "Need MDS version at least 2.10.50"
6075
6076         # Create composite files with one component
6077         local dir=$DIR/$tdir
6078
6079         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6080         # Create composite files with three components
6081         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6082         # Create non-composite files
6083         createmany -o $dir/${tfile}- 10
6084
6085         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6086
6087         [[ $nfiles == 10 ]] ||
6088                 error "lfs find -E 1M found $nfiles != 10 files"
6089
6090         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6091         [[ $nfiles == 25 ]] ||
6092                 error "lfs find ! -E 1M found $nfiles != 25 files"
6093
6094         # All files have a component that starts at 0
6095         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6096         [[ $nfiles == 35 ]] ||
6097                 error "lfs find --component-start 0 - $nfiles != 35 files"
6098
6099         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6100         [[ $nfiles == 15 ]] ||
6101                 error "lfs find --component-start 2M - $nfiles != 15 files"
6102
6103         # All files created here have a componenet that does not starts at 2M
6104         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6105         [[ $nfiles == 35 ]] ||
6106                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6107
6108         # Find files with a specified number of components
6109         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6110         [[ $nfiles == 15 ]] ||
6111                 error "lfs find --component-count 3 - $nfiles != 15 files"
6112
6113         # Remember non-composite files have a component count of zero
6114         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6115         [[ $nfiles == 10 ]] ||
6116                 error "lfs find --component-count 0 - $nfiles != 10 files"
6117
6118         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6119         [[ $nfiles == 20 ]] ||
6120                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6121
6122         # All files have a flag called "init"
6123         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6124         [[ $nfiles == 35 ]] ||
6125                 error "lfs find --component-flags init - $nfiles != 35 files"
6126
6127         # Multi-component files will have a component not initialized
6128         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6129         [[ $nfiles == 15 ]] ||
6130                 error "lfs find !--component-flags init - $nfiles != 15 files"
6131
6132         rm -rf $dir
6133
6134 }
6135 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6136
6137 test_56ca() {
6138         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6139                 skip "Need MDS version at least 2.10.57"
6140
6141         local td=$DIR/$tdir
6142         local tf=$td/$tfile
6143         local dir
6144         local nfiles
6145         local cmd
6146         local i
6147         local j
6148
6149         # create mirrored directories and mirrored files
6150         mkdir $td || error "mkdir $td failed"
6151         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6152         createmany -o $tf- 10 || error "create $tf- failed"
6153
6154         for i in $(seq 2); do
6155                 dir=$td/dir$i
6156                 mkdir $dir || error "mkdir $dir failed"
6157                 $LFS mirror create -N$((3 + i)) $dir ||
6158                         error "create mirrored dir $dir failed"
6159                 createmany -o $dir/$tfile- 10 ||
6160                         error "create $dir/$tfile- failed"
6161         done
6162
6163         # change the states of some mirrored files
6164         echo foo > $tf-6
6165         for i in $(seq 2); do
6166                 dir=$td/dir$i
6167                 for j in $(seq 4 9); do
6168                         echo foo > $dir/$tfile-$j
6169                 done
6170         done
6171
6172         # find mirrored files with specific mirror count
6173         cmd="$LFS find --mirror-count 3 --type f $td"
6174         nfiles=$($cmd | wc -l)
6175         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6176
6177         cmd="$LFS find ! --mirror-count 3 --type f $td"
6178         nfiles=$($cmd | wc -l)
6179         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6180
6181         cmd="$LFS find --mirror-count +2 --type f $td"
6182         nfiles=$($cmd | wc -l)
6183         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6184
6185         cmd="$LFS find --mirror-count -6 --type f $td"
6186         nfiles=$($cmd | wc -l)
6187         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6188
6189         # find mirrored files with specific file state
6190         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6191         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6192
6193         cmd="$LFS find --mirror-state=ro --type f $td"
6194         nfiles=$($cmd | wc -l)
6195         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6196
6197         cmd="$LFS find ! --mirror-state=ro --type f $td"
6198         nfiles=$($cmd | wc -l)
6199         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6200
6201         cmd="$LFS find --mirror-state=wp --type f $td"
6202         nfiles=$($cmd | wc -l)
6203         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6204
6205         cmd="$LFS find ! --mirror-state=sp --type f $td"
6206         nfiles=$($cmd | wc -l)
6207         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6208 }
6209 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6210
6211 test_57a() {
6212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6213         # note test will not do anything if MDS is not local
6214         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6215                 skip_env "ldiskfs only test"
6216         fi
6217         remote_mds_nodsh && skip "remote MDS with nodsh"
6218
6219         local MNTDEV="osd*.*MDT*.mntdev"
6220         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6221         [ -z "$DEV" ] && error "can't access $MNTDEV"
6222         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6223                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6224                         error "can't access $DEV"
6225                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6226                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6227                 rm $TMP/t57a.dump
6228         done
6229 }
6230 run_test 57a "verify MDS filesystem created with large inodes =="
6231
6232 test_57b() {
6233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6234         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6235                 skip_env "ldiskfs only test"
6236         fi
6237         remote_mds_nodsh && skip "remote MDS with nodsh"
6238
6239         local dir=$DIR/$tdir
6240         local filecount=100
6241         local file1=$dir/f1
6242         local fileN=$dir/f$filecount
6243
6244         rm -rf $dir || error "removing $dir"
6245         test_mkdir -c1 $dir
6246         local mdtidx=$($LFS getstripe -m $dir)
6247         local mdtname=MDT$(printf %04x $mdtidx)
6248         local facet=mds$((mdtidx + 1))
6249
6250         echo "mcreating $filecount files"
6251         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6252
6253         # verify that files do not have EAs yet
6254         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6255                 error "$file1 has an EA"
6256         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6257                 error "$fileN has an EA"
6258
6259         sync
6260         sleep 1
6261         df $dir  #make sure we get new statfs data
6262         local mdsfree=$(do_facet $facet \
6263                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6264         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6265         local file
6266
6267         echo "opening files to create objects/EAs"
6268         for file in $(seq -f $dir/f%g 1 $filecount); do
6269                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6270                         error "opening $file"
6271         done
6272
6273         # verify that files have EAs now
6274         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6275         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6276
6277         sleep 1  #make sure we get new statfs data
6278         df $dir
6279         local mdsfree2=$(do_facet $facet \
6280                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6281         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6282
6283         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6284                 if [ "$mdsfree" != "$mdsfree2" ]; then
6285                         error "MDC before $mdcfree != after $mdcfree2"
6286                 else
6287                         echo "MDC before $mdcfree != after $mdcfree2"
6288                         echo "unable to confirm if MDS has large inodes"
6289                 fi
6290         fi
6291         rm -rf $dir
6292 }
6293 run_test 57b "default LOV EAs are stored inside large inodes ==="
6294
6295 test_58() {
6296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6297         [ -z "$(which wiretest 2>/dev/null)" ] &&
6298                         skip_env "could not find wiretest"
6299
6300         wiretest
6301 }
6302 run_test 58 "verify cross-platform wire constants =============="
6303
6304 test_59() {
6305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6306
6307         echo "touch 130 files"
6308         createmany -o $DIR/f59- 130
6309         echo "rm 130 files"
6310         unlinkmany $DIR/f59- 130
6311         sync
6312         # wait for commitment of removal
6313         wait_delete_completed
6314 }
6315 run_test 59 "verify cancellation of llog records async ========="
6316
6317 TEST60_HEAD="test_60 run $RANDOM"
6318 test_60a() {
6319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6320         remote_mgs_nodsh && skip "remote MGS with nodsh"
6321         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6322                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6323                         skip_env "missing subtest run-llog.sh"
6324
6325         log "$TEST60_HEAD - from kernel mode"
6326         do_facet mgs "$LCTL dk > /dev/null"
6327         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6328         do_facet mgs $LCTL dk > $TMP/$tfile
6329
6330         # LU-6388: test llog_reader
6331         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6332         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6333         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6334                         skip_env "missing llog_reader"
6335         local fstype=$(facet_fstype mgs)
6336         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6337                 skip_env "Only for ldiskfs or zfs type mgs"
6338
6339         local mntpt=$(facet_mntpt mgs)
6340         local mgsdev=$(mgsdevname 1)
6341         local fid_list
6342         local fid
6343         local rec_list
6344         local rec
6345         local rec_type
6346         local obj_file
6347         local path
6348         local seq
6349         local oid
6350         local pass=true
6351
6352         #get fid and record list
6353         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6354                 tail -n 4))
6355         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6356                 tail -n 4))
6357         #remount mgs as ldiskfs or zfs type
6358         stop mgs || error "stop mgs failed"
6359         mount_fstype mgs || error "remount mgs failed"
6360         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6361                 fid=${fid_list[i]}
6362                 rec=${rec_list[i]}
6363                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6364                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6365                 oid=$((16#$oid))
6366
6367                 case $fstype in
6368                         ldiskfs )
6369                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6370                         zfs )
6371                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6372                 esac
6373                 echo "obj_file is $obj_file"
6374                 do_facet mgs $llog_reader $obj_file
6375
6376                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6377                         awk '{ print $3 }' | sed -e "s/^type=//g")
6378                 if [ $rec_type != $rec ]; then
6379                         echo "FAILED test_60a wrong record type $rec_type," \
6380                               "should be $rec"
6381                         pass=false
6382                         break
6383                 fi
6384
6385                 #check obj path if record type is LLOG_LOGID_MAGIC
6386                 if [ "$rec" == "1064553b" ]; then
6387                         path=$(do_facet mgs $llog_reader $obj_file |
6388                                 grep "path=" | awk '{ print $NF }' |
6389                                 sed -e "s/^path=//g")
6390                         if [ $obj_file != $mntpt/$path ]; then
6391                                 echo "FAILED test_60a wrong obj path" \
6392                                       "$montpt/$path, should be $obj_file"
6393                                 pass=false
6394                                 break
6395                         fi
6396                 fi
6397         done
6398         rm -f $TMP/$tfile
6399         #restart mgs before "error", otherwise it will block the next test
6400         stop mgs || error "stop mgs failed"
6401         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6402         $pass || error "test failed, see FAILED test_60a messages for specifics"
6403 }
6404 run_test 60a "llog_test run from kernel module and test llog_reader"
6405
6406 test_60b() { # bug 6411
6407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6408
6409         dmesg > $DIR/$tfile
6410         LLOG_COUNT=$(do_facet mgs dmesg |
6411                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6412                           /llog_[a-z]*.c:[0-9]/ {
6413                                 if (marker)
6414                                         from_marker++
6415                                 from_begin++
6416                           }
6417                           END {
6418                                 if (marker)
6419                                         print from_marker
6420                                 else
6421                                         print from_begin
6422                           }")
6423
6424         [[ $LLOG_COUNT -gt 120 ]] &&
6425                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6426 }
6427 run_test 60b "limit repeated messages from CERROR/CWARN"
6428
6429 test_60c() {
6430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6431
6432         echo "create 5000 files"
6433         createmany -o $DIR/f60c- 5000
6434 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6435         lctl set_param fail_loc=0x80000137
6436         unlinkmany $DIR/f60c- 5000
6437         lctl set_param fail_loc=0
6438 }
6439 run_test 60c "unlink file when mds full"
6440
6441 test_60d() {
6442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6443
6444         SAVEPRINTK=$(lctl get_param -n printk)
6445         # verify "lctl mark" is even working"
6446         MESSAGE="test message ID $RANDOM $$"
6447         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6448         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6449
6450         lctl set_param printk=0 || error "set lnet.printk failed"
6451         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6452         MESSAGE="new test message ID $RANDOM $$"
6453         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6454         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6455         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6456
6457         lctl set_param -n printk="$SAVEPRINTK"
6458 }
6459 run_test 60d "test printk console message masking"
6460
6461 test_60e() {
6462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6463         remote_mds_nodsh && skip "remote MDS with nodsh"
6464
6465         touch $DIR/$tfile
6466 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6467         do_facet mds1 lctl set_param fail_loc=0x15b
6468         rm $DIR/$tfile
6469 }
6470 run_test 60e "no space while new llog is being created"
6471
6472 test_60g() {
6473         local pid
6474
6475         test_mkdir -c $MDSCOUNT $DIR/$tdir
6476         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6477
6478         (
6479                 local index=0
6480                 while true; do
6481                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6482                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6483                         index=$((index + 1))
6484                 done
6485         ) &
6486
6487         pid=$!
6488
6489         for i in $(seq 100); do 
6490                 # define OBD_FAIL_OSD_TXN_START    0x19a
6491                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6492                 usleep 100
6493         done
6494
6495         kill -9 $pid
6496
6497         mkdir $DIR/$tdir/new || error "mkdir failed"
6498         rmdir $DIR/$tdir/new || error "rmdir failed"
6499 }
6500 run_test 60g "transaction abort won't cause MDT hung"
6501
6502 test_61a() {
6503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6504
6505         f="$DIR/f61"
6506         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6507         cancel_lru_locks osc
6508         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6509         sync
6510 }
6511 run_test 61a "mmap() writes don't make sync hang ================"
6512
6513 test_61b() {
6514         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6515 }
6516 run_test 61b "mmap() of unstriped file is successful"
6517
6518 # bug 2330 - insufficient obd_match error checking causes LBUG
6519 test_62() {
6520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6521
6522         f="$DIR/f62"
6523         echo foo > $f
6524         cancel_lru_locks osc
6525         lctl set_param fail_loc=0x405
6526         cat $f && error "cat succeeded, expect -EIO"
6527         lctl set_param fail_loc=0
6528 }
6529 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6530 # match every page all of the time.
6531 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6532
6533 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6534 # Though this test is irrelevant anymore, it helped to reveal some
6535 # other grant bugs (LU-4482), let's keep it.
6536 test_63a() {   # was test_63
6537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6538
6539         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6540
6541         for i in `seq 10` ; do
6542                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6543                 sleep 5
6544                 kill $!
6545                 sleep 1
6546         done
6547
6548         rm -f $DIR/f63 || true
6549 }
6550 run_test 63a "Verify oig_wait interruption does not crash ======="
6551
6552 # bug 2248 - async write errors didn't return to application on sync
6553 # bug 3677 - async write errors left page locked
6554 test_63b() {
6555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6556
6557         debugsave
6558         lctl set_param debug=-1
6559
6560         # ensure we have a grant to do async writes
6561         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6562         rm $DIR/$tfile
6563
6564         sync    # sync lest earlier test intercept the fail_loc
6565
6566         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6567         lctl set_param fail_loc=0x80000406
6568         $MULTIOP $DIR/$tfile Owy && \
6569                 error "sync didn't return ENOMEM"
6570         sync; sleep 2; sync     # do a real sync this time to flush page
6571         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6572                 error "locked page left in cache after async error" || true
6573         debugrestore
6574 }
6575 run_test 63b "async write errors should be returned to fsync ==="
6576
6577 test_64a () {
6578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6579
6580         df $DIR
6581         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6582 }
6583 run_test 64a "verify filter grant calculations (in kernel) ====="
6584
6585 test_64b () {
6586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6587
6588         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6589 }
6590 run_test 64b "check out-of-space detection on client"
6591
6592 test_64c() {
6593         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6594 }
6595 run_test 64c "verify grant shrink"
6596
6597 # this does exactly what osc_request.c:osc_announce_cached() does in
6598 # order to calculate max amount of grants to ask from server
6599 want_grant() {
6600         local tgt=$1
6601
6602         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6603         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6604
6605         ((rpc_in_flight ++));
6606         nrpages=$((nrpages * rpc_in_flight))
6607
6608         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6609
6610         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6611
6612         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6613         local undirty=$((nrpages * PAGE_SIZE))
6614
6615         local max_extent_pages
6616         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6617             grep grant_max_extent_size | awk '{print $2}')
6618         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6619         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6620         local grant_extent_tax
6621         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6622             grep grant_extent_tax | awk '{print $2}')
6623
6624         undirty=$((undirty + nrextents * grant_extent_tax))
6625
6626         echo $undirty
6627 }
6628
6629 # this is size of unit for grant allocation. It should be equal to
6630 # what tgt_grant.c:tgt_grant_chunk() calculates
6631 grant_chunk() {
6632         local tgt=$1
6633         local max_brw_size
6634         local grant_extent_tax
6635
6636         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6637             grep max_brw_size | awk '{print $2}')
6638
6639         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6640             grep grant_extent_tax | awk '{print $2}')
6641
6642         echo $(((max_brw_size + grant_extent_tax) * 2))
6643 }
6644
6645 test_64d() {
6646         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6647                 skip "OST < 2.10.55 doesn't limit grants enough"
6648
6649         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6650         local file=$DIR/$tfile
6651
6652         [[ $($LCTL get_param osc.${tgt}.import |
6653              grep "connect_flags:.*grant_param") ]] ||
6654                 skip "no grant_param connect flag"
6655
6656         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6657
6658         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6659
6660         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6661         stack_trap "rm -f $file" EXIT
6662
6663         $LFS setstripe $file -i 0 -c 1
6664         dd if=/dev/zero of=$file bs=1M count=1000 &
6665         ddpid=$!
6666
6667         while true
6668         do
6669                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6670                 if [[ $cur_grant -gt $max_cur_granted ]]
6671                 then
6672                         kill $ddpid
6673                         error "cur_grant $cur_grant > $max_cur_granted"
6674                 fi
6675                 kill -0 $ddpid
6676                 [[ $? -ne 0 ]] && break;
6677                 sleep 2
6678         done
6679
6680         rm -f $DIR/$tfile
6681         wait_delete_completed
6682         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6683 }
6684 run_test 64d "check grant limit exceed"
6685
6686 # bug 1414 - set/get directories' stripe info
6687 test_65a() {
6688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6689
6690         test_mkdir $DIR/$tdir
6691         touch $DIR/$tdir/f1
6692         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6693 }
6694 run_test 65a "directory with no stripe info"
6695
6696 test_65b() {
6697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6698
6699         test_mkdir $DIR/$tdir
6700         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6701
6702         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6703                                                 error "setstripe"
6704         touch $DIR/$tdir/f2
6705         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6706 }
6707 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6708
6709 test_65c() {
6710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6711         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6712
6713         test_mkdir $DIR/$tdir
6714         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6715
6716         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6717                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6718         touch $DIR/$tdir/f3
6719         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6720 }
6721 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6722
6723 test_65d() {
6724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6725
6726         test_mkdir $DIR/$tdir
6727         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6728         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6729
6730         if [[ $STRIPECOUNT -le 0 ]]; then
6731                 sc=1
6732         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6733 #LOV_MAX_STRIPE_COUNT is 2000
6734                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6735         else
6736                 sc=$(($STRIPECOUNT - 1))
6737         fi
6738         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6739         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6740         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6741                 error "lverify failed"
6742 }
6743 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6744
6745 test_65e() {
6746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6747
6748         test_mkdir $DIR/$tdir
6749
6750         $LFS setstripe $DIR/$tdir || error "setstripe"
6751         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6752                                         error "no stripe info failed"
6753         touch $DIR/$tdir/f6
6754         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6755 }
6756 run_test 65e "directory setstripe defaults"
6757
6758 test_65f() {
6759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6760
6761         test_mkdir $DIR/${tdir}f
6762         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6763                 error "setstripe succeeded" || true
6764 }
6765 run_test 65f "dir setstripe permission (should return error) ==="
6766
6767 test_65g() {
6768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6769
6770         test_mkdir $DIR/$tdir
6771         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6772
6773         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6774                 error "setstripe -S failed"
6775         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6776         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6777                 error "delete default stripe failed"
6778 }
6779 run_test 65g "directory setstripe -d"
6780
6781 test_65h() {
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         test_mkdir $DIR/$tdir/dd1
6790         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6791                 error "stripe info inherit failed"
6792 }
6793 run_test 65h "directory stripe info inherit ===================="
6794
6795 test_65i() {
6796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6797
6798         save_layout_restore_at_exit $MOUNT
6799
6800         # bug6367: set non-default striping on root directory
6801         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6802
6803         # bug12836: getstripe on -1 default directory striping
6804         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6805
6806         # bug12836: getstripe -v on -1 default directory striping
6807         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6808
6809         # bug12836: new find on -1 default directory striping
6810         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6811 }
6812 run_test 65i "various tests to set root directory striping"
6813
6814 test_65j() { # bug6367
6815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6816
6817         sync; sleep 1
6818
6819         # if we aren't already remounting for each test, do so for this test
6820         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6821                 cleanup || error "failed to unmount"
6822                 setup
6823         fi
6824
6825         save_layout_restore_at_exit $MOUNT
6826
6827         $LFS setstripe -d $MOUNT || error "setstripe failed"
6828 }
6829 run_test 65j "set default striping on root directory (bug 6367)="
6830
6831 cleanup_65k() {
6832         rm -rf $DIR/$tdir
6833         wait_delete_completed
6834         do_facet $SINGLEMDS "lctl set_param -n \
6835                 osp.$ost*MDT0000.max_create_count=$max_count"
6836         do_facet $SINGLEMDS "lctl set_param -n \
6837                 osp.$ost*MDT0000.create_count=$count"
6838         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6839         echo $INACTIVE_OSC "is Activate"
6840
6841         wait_osc_import_state mds ost$ostnum FULL
6842 }
6843
6844 test_65k() { # bug11679
6845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6847         remote_mds_nodsh && skip "remote MDS with nodsh"
6848
6849         local disable_precreate=true
6850         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6851                 disable_precreate=false
6852
6853         echo "Check OST status: "
6854         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6855                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6856
6857         for OSC in $MDS_OSCS; do
6858                 echo $OSC "is active"
6859                 do_facet $SINGLEMDS lctl --device %$OSC activate
6860         done
6861
6862         for INACTIVE_OSC in $MDS_OSCS; do
6863                 local ost=$(osc_to_ost $INACTIVE_OSC)
6864                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6865                                lov.*md*.target_obd |
6866                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6867
6868                 mkdir -p $DIR/$tdir
6869                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6870                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6871
6872                 echo "Deactivate: " $INACTIVE_OSC
6873                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6874
6875                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6876                               osp.$ost*MDT0000.create_count")
6877                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6878                                   osp.$ost*MDT0000.max_create_count")
6879                 $disable_precreate &&
6880                         do_facet $SINGLEMDS "lctl set_param -n \
6881                                 osp.$ost*MDT0000.max_create_count=0"
6882
6883                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6884                         [ -f $DIR/$tdir/$idx ] && continue
6885                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6886                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6887                                 { cleanup_65k;
6888                                   error "setstripe $idx should succeed"; }
6889                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6890                 done
6891                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6892                 rmdir $DIR/$tdir
6893
6894                 do_facet $SINGLEMDS "lctl set_param -n \
6895                         osp.$ost*MDT0000.max_create_count=$max_count"
6896                 do_facet $SINGLEMDS "lctl set_param -n \
6897                         osp.$ost*MDT0000.create_count=$count"
6898                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6899                 echo $INACTIVE_OSC "is Activate"
6900
6901                 wait_osc_import_state mds ost$ostnum FULL
6902         done
6903 }
6904 run_test 65k "validate manual striping works properly with deactivated OSCs"
6905
6906 test_65l() { # bug 12836
6907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6908
6909         test_mkdir -p $DIR/$tdir/test_dir
6910         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6911         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6912 }
6913 run_test 65l "lfs find on -1 stripe dir ========================"
6914
6915 test_65m() {
6916         local layout=$(save_layout $MOUNT)
6917         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6918                 restore_layout $MOUNT $layout
6919                 error "setstripe should fail by non-root users"
6920         }
6921         true
6922 }
6923 run_test 65m "normal user can't set filesystem default stripe"
6924
6925 test_65n() {
6926         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6927         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6928                 skip "Need MDS version at least 2.12.50"
6929         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6930
6931         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6932         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6933         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6934
6935         local root_layout=$(save_layout $MOUNT)
6936         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6937
6938         # new subdirectory under root directory should not inherit
6939         # the default layout from root
6940         local dir1=$MOUNT/$tdir-1
6941         mkdir $dir1 || error "mkdir $dir1 failed"
6942         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6943                 error "$dir1 shouldn't have LOV EA"
6944
6945         # delete the default layout on root directory
6946         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6947
6948         local dir2=$MOUNT/$tdir-2
6949         mkdir $dir2 || error "mkdir $dir2 failed"
6950         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6951                 error "$dir2 shouldn't have LOV EA"
6952
6953         # set a new striping pattern on root directory
6954         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6955         local new_def_stripe_size=$((def_stripe_size * 2))
6956         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6957                 error "set stripe size on $MOUNT failed"
6958
6959         # new file created in $dir2 should inherit the new stripe size from
6960         # the filesystem default
6961         local file2=$dir2/$tfile-2
6962         touch $file2 || error "touch $file2 failed"
6963
6964         local file2_stripe_size=$($LFS getstripe -S $file2)
6965         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6966                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6967
6968         local dir3=$MOUNT/$tdir-3
6969         mkdir $dir3 || error "mkdir $dir3 failed"
6970         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6971                 error "$dir3 shouldn't have LOV EA"
6972
6973         # set OST pool on root directory
6974         local pool=$TESTNAME
6975         pool_add $pool || error "add $pool failed"
6976         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6977                 error "add targets to $pool failed"
6978
6979         $LFS setstripe -p $pool $MOUNT ||
6980                 error "set OST pool on $MOUNT failed"
6981
6982         # new file created in $dir3 should inherit the pool from
6983         # the filesystem default
6984         local file3=$dir3/$tfile-3
6985         touch $file3 || error "touch $file3 failed"
6986
6987         local file3_pool=$($LFS getstripe -p $file3)
6988         [[ "$file3_pool" = "$pool" ]] ||
6989                 error "$file3 didn't inherit OST pool $pool"
6990
6991         local dir4=$MOUNT/$tdir-4
6992         mkdir $dir4 || error "mkdir $dir4 failed"
6993         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6994                 error "$dir4 shouldn't have LOV EA"
6995
6996         # new file created in $dir4 should inherit the pool from
6997         # the filesystem default
6998         local file4=$dir4/$tfile-4
6999         touch $file4 || error "touch $file4 failed"
7000
7001         local file4_pool=$($LFS getstripe -p $file4)
7002         [[ "$file4_pool" = "$pool" ]] ||
7003                 error "$file4 didn't inherit OST pool $pool"
7004
7005         # new subdirectory under non-root directory should inherit
7006         # the default layout from its parent directory
7007         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7008                 error "set directory layout on $dir4 failed"
7009
7010         local dir5=$dir4/$tdir-5
7011         mkdir $dir5 || error "mkdir $dir5 failed"
7012
7013         local dir4_layout=$(get_layout_param $dir4)
7014         local dir5_layout=$(get_layout_param $dir5)
7015         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7016                 error "$dir5 should inherit the default layout from $dir4"
7017 }
7018 run_test 65n "don't inherit default layout from root for new subdirectories"
7019
7020 # bug 2543 - update blocks count on client
7021 test_66() {
7022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7023
7024         COUNT=${COUNT:-8}
7025         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7026         sync; sync_all_data; sync; sync_all_data
7027         cancel_lru_locks osc
7028         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7029         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7030 }
7031 run_test 66 "update inode blocks count on client ==============="
7032
7033 meminfo() {
7034         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7035 }
7036
7037 swap_used() {
7038         swapon -s | awk '($1 == "'$1'") { print $4 }'
7039 }
7040
7041 # bug5265, obdfilter oa2dentry return -ENOENT
7042 # #define OBD_FAIL_SRV_ENOENT 0x217
7043 test_69() {
7044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7045         remote_ost_nodsh && skip "remote OST with nodsh"
7046
7047         f="$DIR/$tfile"
7048         $LFS setstripe -c 1 -i 0 $f
7049
7050         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7051
7052         do_facet ost1 lctl set_param fail_loc=0x217
7053         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7054         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7055
7056         do_facet ost1 lctl set_param fail_loc=0
7057         $DIRECTIO write $f 0 2 || error "write error"
7058
7059         cancel_lru_locks osc
7060         $DIRECTIO read $f 0 1 || error "read error"
7061
7062         do_facet ost1 lctl set_param fail_loc=0x217
7063         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7064
7065         do_facet ost1 lctl set_param fail_loc=0
7066         rm -f $f
7067 }
7068 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7069
7070 test_71() {
7071         test_mkdir $DIR/$tdir
7072         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7073         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7074 }
7075 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7076
7077 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079         [ "$RUNAS_ID" = "$UID" ] &&
7080                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7081         # Check that testing environment is properly set up. Skip if not
7082         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7083                 skip_env "User $RUNAS_ID does not exist - skipping"
7084
7085         touch $DIR/$tfile
7086         chmod 777 $DIR/$tfile
7087         chmod ug+s $DIR/$tfile
7088         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7089                 error "$RUNAS dd $DIR/$tfile failed"
7090         # See if we are still setuid/sgid
7091         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7092                 error "S/gid is not dropped on write"
7093         # Now test that MDS is updated too
7094         cancel_lru_locks mdc
7095         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7096                 error "S/gid is not dropped on MDS"
7097         rm -f $DIR/$tfile
7098 }
7099 run_test 72a "Test that remove suid works properly (bug5695) ===="
7100
7101 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7102         local perm
7103
7104         [ "$RUNAS_ID" = "$UID" ] &&
7105                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7106         [ "$RUNAS_ID" -eq 0 ] &&
7107                 skip_env "RUNAS_ID = 0 -- skipping"
7108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7109         # Check that testing environment is properly set up. Skip if not
7110         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7111                 skip_env "User $RUNAS_ID does not exist - skipping"
7112
7113         touch $DIR/${tfile}-f{g,u}
7114         test_mkdir $DIR/${tfile}-dg
7115         test_mkdir $DIR/${tfile}-du
7116         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7117         chmod g+s $DIR/${tfile}-{f,d}g
7118         chmod u+s $DIR/${tfile}-{f,d}u
7119         for perm in 777 2777 4777; do
7120                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7121                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7122                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7123                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7124         done
7125         true
7126 }
7127 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7128
7129 # bug 3462 - multiple simultaneous MDC requests
7130 test_73() {
7131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7132
7133         test_mkdir $DIR/d73-1
7134         test_mkdir $DIR/d73-2
7135         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7136         pid1=$!
7137
7138         lctl set_param fail_loc=0x80000129
7139         $MULTIOP $DIR/d73-1/f73-2 Oc &
7140         sleep 1
7141         lctl set_param fail_loc=0
7142
7143         $MULTIOP $DIR/d73-2/f73-3 Oc &
7144         pid3=$!
7145
7146         kill -USR1 $pid1
7147         wait $pid1 || return 1
7148
7149         sleep 25
7150
7151         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7152         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7153         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7154
7155         rm -rf $DIR/d73-*
7156 }
7157 run_test 73 "multiple MDC requests (should not deadlock)"
7158
7159 test_74a() { # bug 6149, 6184
7160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7161
7162         touch $DIR/f74a
7163         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7164         #
7165         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7166         # will spin in a tight reconnection loop
7167         $LCTL set_param fail_loc=0x8000030e
7168         # get any lock that won't be difficult - lookup works.
7169         ls $DIR/f74a
7170         $LCTL set_param fail_loc=0
7171         rm -f $DIR/f74a
7172         true
7173 }
7174 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7175
7176 test_74b() { # bug 13310
7177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7178
7179         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7180         #
7181         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7182         # will spin in a tight reconnection loop
7183         $LCTL set_param fail_loc=0x8000030e
7184         # get a "difficult" lock
7185         touch $DIR/f74b
7186         $LCTL set_param fail_loc=0
7187         rm -f $DIR/f74b
7188         true
7189 }
7190 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7191
7192 test_74c() {
7193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7194
7195         #define OBD_FAIL_LDLM_NEW_LOCK
7196         $LCTL set_param fail_loc=0x319
7197         touch $DIR/$tfile && error "touch successful"
7198         $LCTL set_param fail_loc=0
7199         true
7200 }
7201 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7202
7203 num_inodes() {
7204         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7205 }
7206
7207 test_76() { # Now for bug 20433, added originally in bug 1443
7208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7209
7210         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7211
7212         cancel_lru_locks osc
7213         BEFORE_INODES=$(num_inodes)
7214         echo "before inodes: $BEFORE_INODES"
7215         local COUNT=1000
7216         [ "$SLOW" = "no" ] && COUNT=100
7217         for i in $(seq $COUNT); do
7218                 touch $DIR/$tfile
7219                 rm -f $DIR/$tfile
7220         done
7221         cancel_lru_locks osc
7222         AFTER_INODES=$(num_inodes)
7223         echo "after inodes: $AFTER_INODES"
7224         local wait=0
7225         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7226                 sleep 2
7227                 AFTER_INODES=$(num_inodes)
7228                 wait=$((wait+2))
7229                 echo "wait $wait seconds inodes: $AFTER_INODES"
7230                 if [ $wait -gt 30 ]; then
7231                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7232                 fi
7233         done
7234 }
7235 run_test 76 "confirm clients recycle inodes properly ===="
7236
7237
7238 export ORIG_CSUM=""
7239 set_checksums()
7240 {
7241         # Note: in sptlrpc modes which enable its own bulk checksum, the
7242         # original crc32_le bulk checksum will be automatically disabled,
7243         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7244         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7245         # In this case set_checksums() will not be no-op, because sptlrpc
7246         # bulk checksum will be enabled all through the test.
7247
7248         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7249         lctl set_param -n osc.*.checksums $1
7250         return 0
7251 }
7252
7253 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7254                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7255 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7256                              tr -d [] | head -n1)}
7257 set_checksum_type()
7258 {
7259         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7260         log "set checksum type to $1"
7261         return 0
7262 }
7263 F77_TMP=$TMP/f77-temp
7264 F77SZ=8
7265 setup_f77() {
7266         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7267                 error "error writing to $F77_TMP"
7268 }
7269
7270 test_77a() { # bug 10889
7271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7272         $GSS && skip_env "could not run with gss"
7273
7274         [ ! -f $F77_TMP ] && setup_f77
7275         set_checksums 1
7276         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7277         set_checksums 0
7278         rm -f $DIR/$tfile
7279 }
7280 run_test 77a "normal checksum read/write operation"
7281
7282 test_77b() { # bug 10889
7283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7284         $GSS && skip_env "could not run with gss"
7285
7286         [ ! -f $F77_TMP ] && setup_f77
7287         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7288         $LCTL set_param fail_loc=0x80000409
7289         set_checksums 1
7290
7291         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7292                 error "dd error: $?"
7293         $LCTL set_param fail_loc=0
7294
7295         for algo in $CKSUM_TYPES; do
7296                 cancel_lru_locks osc
7297                 set_checksum_type $algo
7298                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7299                 $LCTL set_param fail_loc=0x80000408
7300                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7301                 $LCTL set_param fail_loc=0
7302         done
7303         set_checksums 0
7304         set_checksum_type $ORIG_CSUM_TYPE
7305         rm -f $DIR/$tfile
7306 }
7307 run_test 77b "checksum error on client write, read"
7308
7309 cleanup_77c() {
7310         trap 0
7311         set_checksums 0
7312         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7313         $check_ost &&
7314                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7315         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7316         $check_ost && [ -n "$ost_file_prefix" ] &&
7317                 do_facet ost1 rm -f ${ost_file_prefix}\*
7318 }
7319
7320 test_77c() {
7321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7322         $GSS && skip_env "could not run with gss"
7323         remote_ost_nodsh && skip "remote OST with nodsh"
7324
7325         local bad1
7326         local osc_file_prefix
7327         local osc_file
7328         local check_ost=false
7329         local ost_file_prefix
7330         local ost_file
7331         local orig_cksum
7332         local dump_cksum
7333         local fid
7334
7335         # ensure corruption will occur on first OSS/OST
7336         $LFS setstripe -i 0 $DIR/$tfile
7337
7338         [ ! -f $F77_TMP ] && setup_f77
7339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7340                 error "dd write error: $?"
7341         fid=$($LFS path2fid $DIR/$tfile)
7342
7343         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7344         then
7345                 check_ost=true
7346                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7347                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7348         else
7349                 echo "OSS do not support bulk pages dump upon error"
7350         fi
7351
7352         osc_file_prefix=$($LCTL get_param -n debug_path)
7353         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7354
7355         trap cleanup_77c EXIT
7356
7357         set_checksums 1
7358         # enable bulk pages dump upon error on Client
7359         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7360         # enable bulk pages dump upon error on OSS
7361         $check_ost &&
7362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7363
7364         # flush Client cache to allow next read to reach OSS
7365         cancel_lru_locks osc
7366
7367         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7368         $LCTL set_param fail_loc=0x80000408
7369         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7370         $LCTL set_param fail_loc=0
7371
7372         rm -f $DIR/$tfile
7373
7374         # check cksum dump on Client
7375         osc_file=$(ls ${osc_file_prefix}*)
7376         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7377         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7378         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7379         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7380         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7381                      cksum)
7382         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7383         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7384                 error "dump content does not match on Client"
7385
7386         $check_ost || skip "No need to check cksum dump on OSS"
7387
7388         # check cksum dump on OSS
7389         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7390         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7391         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7392         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7393         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7394                 error "dump content does not match on OSS"
7395
7396         cleanup_77c
7397 }
7398 run_test 77c "checksum error on client read with debug"
7399
7400 test_77d() { # bug 10889
7401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7402         $GSS && skip_env "could not run with gss"
7403
7404         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7405         $LCTL set_param fail_loc=0x80000409
7406         set_checksums 1
7407         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7408                 error "direct write: rc=$?"
7409         $LCTL set_param fail_loc=0
7410         set_checksums 0
7411
7412         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7413         $LCTL set_param fail_loc=0x80000408
7414         set_checksums 1
7415         cancel_lru_locks osc
7416         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7417                 error "direct read: rc=$?"
7418         $LCTL set_param fail_loc=0
7419         set_checksums 0
7420 }
7421 run_test 77d "checksum error on OST direct write, read"
7422
7423 test_77f() { # bug 10889
7424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7425         $GSS && skip_env "could not run with gss"
7426
7427         set_checksums 1
7428         for algo in $CKSUM_TYPES; do
7429                 cancel_lru_locks osc
7430                 set_checksum_type $algo
7431                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7432                 $LCTL set_param fail_loc=0x409
7433                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7434                         error "direct write succeeded"
7435                 $LCTL set_param fail_loc=0
7436         done
7437         set_checksum_type $ORIG_CSUM_TYPE
7438         set_checksums 0
7439 }
7440 run_test 77f "repeat checksum error on write (expect error)"
7441
7442 test_77g() { # bug 10889
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444         $GSS && skip_env "could not run with gss"
7445         remote_ost_nodsh && skip "remote OST with nodsh"
7446
7447         [ ! -f $F77_TMP ] && setup_f77
7448
7449         local file=$DIR/$tfile
7450         stack_trap "rm -f $file" EXIT
7451
7452         $LFS setstripe -c 1 -i 0 $file
7453         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7454         do_facet ost1 lctl set_param fail_loc=0x8000021a
7455         set_checksums 1
7456         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7457                 error "write error: rc=$?"
7458         do_facet ost1 lctl set_param fail_loc=0
7459         set_checksums 0
7460
7461         cancel_lru_locks osc
7462         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7463         do_facet ost1 lctl set_param fail_loc=0x8000021b
7464         set_checksums 1
7465         cmp $F77_TMP $file || error "file compare failed"
7466         do_facet ost1 lctl set_param fail_loc=0
7467         set_checksums 0
7468 }
7469 run_test 77g "checksum error on OST write, read"
7470
7471 test_77k() { # LU-10906
7472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7473         $GSS && skip_env "could not run with gss"
7474
7475         local cksum_param="osc.$FSNAME*.checksums"
7476         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7477         local checksum
7478         local i
7479
7480         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7481         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7482         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7483                 EXIT
7484
7485         for i in 0 1; do
7486                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7487                         error "failed to set checksum=$i on MGS"
7488                 wait_update $HOSTNAME "$get_checksum" $i
7489                 #remount
7490                 echo "remount client, checksum should be $i"
7491                 remount_client $MOUNT || "failed to remount client"
7492                 checksum=$(eval $get_checksum)
7493                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7494         done
7495         # remove persistent param to avoid races with checksum mountopt below
7496         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7497                 error "failed to delete checksum on MGS"
7498
7499         for opt in "checksum" "nochecksum"; do
7500                 #remount with mount option
7501                 echo "remount client with option $opt, checksum should be $i"
7502                 umount_client $MOUNT || "failed to umount client"
7503                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7504                         "failed to mount client with option '$opt'"
7505                 checksum=$(eval $get_checksum)
7506                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7507                 i=$((i - 1))
7508         done
7509
7510         remount_client $MOUNT || "failed to remount client"
7511 }
7512 run_test 77k "enable/disable checksum correctly"
7513
7514 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7515 rm -f $F77_TMP
7516 unset F77_TMP
7517
7518 cleanup_test_78() {
7519         trap 0
7520         rm -f $DIR/$tfile
7521 }
7522
7523 test_78() { # bug 10901
7524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7525         remote_ost || skip_env "local OST"
7526
7527         NSEQ=5
7528         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7529         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7530         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7531         echo "MemTotal: $MEMTOTAL"
7532
7533         # reserve 256MB of memory for the kernel and other running processes,
7534         # and then take 1/2 of the remaining memory for the read/write buffers.
7535         if [ $MEMTOTAL -gt 512 ] ;then
7536                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7537         else
7538                 # for those poor memory-starved high-end clusters...
7539                 MEMTOTAL=$((MEMTOTAL / 2))
7540         fi
7541         echo "Mem to use for directio: $MEMTOTAL"
7542
7543         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7544         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7545         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7546         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7547                 head -n1)
7548         echo "Smallest OST: $SMALLESTOST"
7549         [[ $SMALLESTOST -lt 10240 ]] &&
7550                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7551
7552         trap cleanup_test_78 EXIT
7553
7554         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7555                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7556
7557         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7558         echo "File size: $F78SIZE"
7559         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7560         for i in $(seq 1 $NSEQ); do
7561                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7562                 echo directIO rdwr round $i of $NSEQ
7563                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7564         done
7565
7566         cleanup_test_78
7567 }
7568 run_test 78 "handle large O_DIRECT writes correctly ============"
7569
7570 test_79() { # bug 12743
7571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7572
7573         wait_delete_completed
7574
7575         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7576         BKFREE=$(calc_osc_kbytes kbytesfree)
7577         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7578
7579         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7580         DFTOTAL=`echo $STRING | cut -d, -f1`
7581         DFUSED=`echo $STRING  | cut -d, -f2`
7582         DFAVAIL=`echo $STRING | cut -d, -f3`
7583         DFFREE=$(($DFTOTAL - $DFUSED))
7584
7585         ALLOWANCE=$((64 * $OSTCOUNT))
7586
7587         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7588            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7589                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7590         fi
7591         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7592            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7593                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7594         fi
7595         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7596            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7597                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7598         fi
7599 }
7600 run_test 79 "df report consistency check ======================="
7601
7602 test_80() { # bug 10718
7603         remote_ost_nodsh && skip "remote OST with nodsh"
7604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7605
7606         # relax strong synchronous semantics for slow backends like ZFS
7607         local soc="obdfilter.*.sync_on_lock_cancel"
7608         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7609         local hosts=
7610         if [ "$soc_old" != "never" ] &&
7611                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7612                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7613                                 facet_active_host $host; done | sort -u)
7614                         do_nodes $hosts lctl set_param $soc=never
7615         fi
7616
7617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7618         sync; sleep 1; sync
7619         local BEFORE=`date +%s`
7620         cancel_lru_locks osc
7621         local AFTER=`date +%s`
7622         local DIFF=$((AFTER-BEFORE))
7623         if [ $DIFF -gt 1 ] ; then
7624                 error "elapsed for 1M@1T = $DIFF"
7625         fi
7626
7627         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7628
7629         rm -f $DIR/$tfile
7630 }
7631 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7632
7633 test_81a() { # LU-456
7634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7635         remote_ost_nodsh && skip "remote OST with nodsh"
7636
7637         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7638         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7639         do_facet ost1 lctl set_param fail_loc=0x80000228
7640
7641         # write should trigger a retry and success
7642         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7643         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7644         RC=$?
7645         if [ $RC -ne 0 ] ; then
7646                 error "write should success, but failed for $RC"
7647         fi
7648 }
7649 run_test 81a "OST should retry write when get -ENOSPC ==============="
7650
7651 test_81b() { # LU-456
7652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7653         remote_ost_nodsh && skip "remote OST with nodsh"
7654
7655         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7656         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7657         do_facet ost1 lctl set_param fail_loc=0x228
7658
7659         # write should retry several times and return -ENOSPC finally
7660         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7661         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7662         RC=$?
7663         ENOSPC=28
7664         if [ $RC -ne $ENOSPC ] ; then
7665                 error "dd should fail for -ENOSPC, but succeed."
7666         fi
7667 }
7668 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7669
7670 test_82() { # LU-1031
7671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7672         local gid1=14091995
7673         local gid2=16022000
7674
7675         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7676         local MULTIPID1=$!
7677         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7678         local MULTIPID2=$!
7679         kill -USR1 $MULTIPID2
7680         sleep 2
7681         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7682                 error "First grouplock does not block second one"
7683         else
7684                 echo "Second grouplock blocks first one"
7685         fi
7686         kill -USR1 $MULTIPID1
7687         wait $MULTIPID1
7688         wait $MULTIPID2
7689 }
7690 run_test 82 "Basic grouplock test"
7691
7692 test_99() {
7693         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7694
7695         test_mkdir $DIR/$tdir.cvsroot
7696         chown $RUNAS_ID $DIR/$tdir.cvsroot
7697
7698         cd $TMP
7699         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7700
7701         cd /etc/init.d
7702         # some versions of cvs import exit(1) when asked to import links or
7703         # files they can't read.  ignore those files.
7704         local toignore=$(find . -type l -printf '-I %f\n' -o \
7705                          ! -perm /4 -printf '-I %f\n')
7706         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7707                 $tdir.reposname vtag rtag
7708
7709         cd $DIR
7710         test_mkdir $DIR/$tdir.reposname
7711         chown $RUNAS_ID $DIR/$tdir.reposname
7712         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7713
7714         cd $DIR/$tdir.reposname
7715         $RUNAS touch foo99
7716         $RUNAS cvs add -m 'addmsg' foo99
7717         $RUNAS cvs update
7718         $RUNAS cvs commit -m 'nomsg' foo99
7719         rm -fr $DIR/$tdir.cvsroot
7720 }
7721 run_test 99 "cvs strange file/directory operations"
7722
7723 test_100() {
7724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7725         [[ "$NETTYPE" =~ tcp ]] ||
7726                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7727         remote_ost_nodsh && skip "remote OST with nodsh"
7728         remote_mds_nodsh && skip "remote MDS with nodsh"
7729         remote_servers ||
7730                 skip "useless for local single node setup"
7731
7732         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7733                 [ "$PROT" != "tcp" ] && continue
7734                 RPORT=$(echo $REMOTE | cut -d: -f2)
7735                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7736
7737                 rc=0
7738                 LPORT=`echo $LOCAL | cut -d: -f2`
7739                 if [ $LPORT -ge 1024 ]; then
7740                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7741                         netstat -tna
7742                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7743                 fi
7744         done
7745         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7746 }
7747 run_test 100 "check local port using privileged port ==========="
7748
7749 function get_named_value()
7750 {
7751     local tag
7752
7753     tag=$1
7754     while read ;do
7755         line=$REPLY
7756         case $line in
7757         $tag*)
7758             echo $line | sed "s/^$tag[ ]*//"
7759             break
7760             ;;
7761         esac
7762     done
7763 }
7764
7765 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7766                    awk '/^max_cached_mb/ { print $2 }')
7767
7768 cleanup_101a() {
7769         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7770         trap 0
7771 }
7772
7773 test_101a() {
7774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7775         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7776
7777         local s
7778         local discard
7779         local nreads=10000
7780         local cache_limit=32
7781
7782         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7783         trap cleanup_101a EXIT
7784         $LCTL set_param -n llite.*.read_ahead_stats 0
7785         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7786
7787         #
7788         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7789         #
7790         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7791         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7792
7793         discard=0
7794         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7795                 get_named_value 'read but discarded' | cut -d" " -f1); do
7796                         discard=$(($discard + $s))
7797         done
7798         cleanup_101a
7799
7800         if [[ $(($discard * 10)) -gt $nreads ]]; then
7801                 $LCTL get_param osc.*-osc*.rpc_stats
7802                 $LCTL get_param llite.*.read_ahead_stats
7803                 error "too many ($discard) discarded pages"
7804         fi
7805         rm -f $DIR/$tfile || true
7806 }
7807 run_test 101a "check read-ahead for random reads"
7808
7809 setup_test101bc() {
7810         test_mkdir $DIR/$tdir
7811         local ssize=$1
7812         local FILE_LENGTH=$2
7813         STRIPE_OFFSET=0
7814
7815         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7816
7817         local list=$(comma_list $(osts_nodes))
7818         set_osd_param $list '' read_cache_enable 0
7819         set_osd_param $list '' writethrough_cache_enable 0
7820
7821         trap cleanup_test101bc EXIT
7822         # prepare the read-ahead file
7823         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7824
7825         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7826                                 count=$FILE_SIZE_MB 2> /dev/null
7827
7828 }
7829
7830 cleanup_test101bc() {
7831         trap 0
7832         rm -rf $DIR/$tdir
7833         rm -f $DIR/$tfile
7834
7835         local list=$(comma_list $(osts_nodes))
7836         set_osd_param $list '' read_cache_enable 1
7837         set_osd_param $list '' writethrough_cache_enable 1
7838 }
7839
7840 calc_total() {
7841         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7842 }
7843
7844 ra_check_101() {
7845         local READ_SIZE=$1
7846         local STRIPE_SIZE=$2
7847         local FILE_LENGTH=$3
7848         local RA_INC=1048576
7849         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7850         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7851                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7852         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7853                         get_named_value 'read but discarded' |
7854                         cut -d" " -f1 | calc_total)
7855         if [[ $DISCARD -gt $discard_limit ]]; then
7856                 $LCTL get_param llite.*.read_ahead_stats
7857                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7858         else
7859                 echo "Read-ahead success for size ${READ_SIZE}"
7860         fi
7861 }
7862
7863 test_101b() {
7864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7865         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7866
7867         local STRIPE_SIZE=1048576
7868         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7869
7870         if [ $SLOW == "yes" ]; then
7871                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7872         else
7873                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7874         fi
7875
7876         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7877
7878         # prepare the read-ahead file
7879         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7880         cancel_lru_locks osc
7881         for BIDX in 2 4 8 16 32 64 128 256
7882         do
7883                 local BSIZE=$((BIDX*4096))
7884                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7885                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7886                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7887                 $LCTL set_param -n llite.*.read_ahead_stats 0
7888                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7889                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7890                 cancel_lru_locks osc
7891                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7892         done
7893         cleanup_test101bc
7894         true
7895 }
7896 run_test 101b "check stride-io mode read-ahead ================="
7897
7898 test_101c() {
7899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7900
7901         local STRIPE_SIZE=1048576
7902         local FILE_LENGTH=$((STRIPE_SIZE*100))
7903         local nreads=10000
7904         local rsize=65536
7905         local osc_rpc_stats
7906
7907         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7908
7909         cancel_lru_locks osc
7910         $LCTL set_param osc.*.rpc_stats 0
7911         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7912         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7913                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7914                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7915                 local size
7916
7917                 if [ $lines -le 20 ]; then
7918                         continue
7919                 fi
7920                 for size in 1 2 4 8; do
7921                         local rpc=$(echo "$stats" |
7922                                     awk '($1 == "'$size':") {print $2; exit; }')
7923                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7924                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7925                 done
7926                 echo "$osc_rpc_stats check passed!"
7927         done
7928         cleanup_test101bc
7929         true
7930 }
7931 run_test 101c "check stripe_size aligned read-ahead ================="
7932
7933 set_read_ahead() {
7934         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7935         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7936 }
7937
7938 test_101d() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940
7941         local file=$DIR/$tfile
7942         local sz_MB=${FILESIZE_101d:-500}
7943         local ra_MB=${READAHEAD_MB:-40}
7944
7945         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7946         [ $free_MB -lt $sz_MB ] &&
7947                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7948
7949         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7950         $LFS setstripe -c -1 $file || error "setstripe failed"
7951
7952         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7953         echo Cancel LRU locks on lustre client to flush the client cache
7954         cancel_lru_locks osc
7955
7956         echo Disable read-ahead
7957         local old_READAHEAD=$(set_read_ahead 0)
7958
7959         echo Reading the test file $file with read-ahead disabled
7960         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7961
7962         echo Cancel LRU locks on lustre client to flush the client cache
7963         cancel_lru_locks osc
7964         echo Enable read-ahead with ${ra_MB}MB
7965         set_read_ahead $ra_MB
7966
7967         echo Reading the test file $file with read-ahead enabled
7968         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7969
7970         echo "read-ahead disabled time read $raOFF"
7971         echo "read-ahead enabled  time read $raON"
7972
7973         set_read_ahead $old_READAHEAD
7974         rm -f $file
7975         wait_delete_completed
7976
7977         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7978                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7979 }
7980 run_test 101d "file read with and without read-ahead enabled"
7981
7982 test_101e() {
7983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7984
7985         local file=$DIR/$tfile
7986         local size_KB=500  #KB
7987         local count=100
7988         local bsize=1024
7989
7990         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7991         local need_KB=$((count * size_KB))
7992         [[ $free_KB -le $need_KB ]] &&
7993                 skip_env "Need free space $need_KB, have $free_KB"
7994
7995         echo "Creating $count ${size_KB}K test files"
7996         for ((i = 0; i < $count; i++)); do
7997                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7998         done
7999
8000         echo "Cancel LRU locks on lustre client to flush the client cache"
8001         cancel_lru_locks $OSC
8002
8003         echo "Reset readahead stats"
8004         $LCTL set_param -n llite.*.read_ahead_stats 0
8005
8006         for ((i = 0; i < $count; i++)); do
8007                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8008         done
8009
8010         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8011                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8012
8013         for ((i = 0; i < $count; i++)); do
8014                 rm -rf $file.$i 2>/dev/null
8015         done
8016
8017         #10000 means 20% reads are missing in readahead
8018         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8019 }
8020 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8021
8022 test_101f() {
8023         which iozone || skip_env "no iozone installed"
8024
8025         local old_debug=$($LCTL get_param debug)
8026         old_debug=${old_debug#*=}
8027         $LCTL set_param debug="reada mmap"
8028
8029         # create a test file
8030         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8031
8032         echo Cancel LRU locks on lustre client to flush the client cache
8033         cancel_lru_locks osc
8034
8035         echo Reset readahead stats
8036         $LCTL set_param -n llite.*.read_ahead_stats 0
8037
8038         echo mmap read the file with small block size
8039         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8040                 > /dev/null 2>&1
8041
8042         echo checking missing pages
8043         $LCTL get_param llite.*.read_ahead_stats
8044         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8045                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8046
8047         $LCTL set_param debug="$old_debug"
8048         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8049         rm -f $DIR/$tfile
8050 }
8051 run_test 101f "check mmap read performance"
8052
8053 test_101g_brw_size_test() {
8054         local mb=$1
8055         local pages=$((mb * 1048576 / PAGE_SIZE))
8056         local file=$DIR/$tfile
8057
8058         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8059                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8060         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8061                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8062                         return 2
8063         done
8064
8065         stack_trap "rm -f $file" EXIT
8066         $LCTL set_param -n osc.*.rpc_stats=0
8067
8068         # 10 RPCs should be enough for the test
8069         local count=10
8070         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8071                 { error "dd write ${mb} MB blocks failed"; return 3; }
8072         cancel_lru_locks osc
8073         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8074                 { error "dd write ${mb} MB blocks failed"; return 4; }
8075
8076         # calculate number of full-sized read and write RPCs
8077         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8078                 sed -n '/pages per rpc/,/^$/p' |
8079                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8080                 END { print reads,writes }'))
8081         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8082                 return 5
8083         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8084                 return 6
8085
8086         return 0
8087 }
8088
8089 test_101g() {
8090         remote_ost_nodsh && skip "remote OST with nodsh"
8091
8092         local rpcs
8093         local osts=$(get_facets OST)
8094         local list=$(comma_list $(osts_nodes))
8095         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8096         local brw_size="obdfilter.*.brw_size"
8097
8098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8099
8100         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8101         if [ $OST1_VERSION -ge $(version_code 2.8.52) -o \
8102              \( $OST1_VERSION -ge $(version_code 2.7.17) -a \
8103                 $OST1_VERSION -lt $(version_code 2.7.50) \) ] &&
8104            [ $CLIENT_VERSION -ge $(version_code 2.8.52) -o \
8105              \( $CLIENT_VERSION -ge $(version_code 2.7.17) -a \
8106                 $CLIENT_VERSION -lt $(version_code 2.7.50) \) ]; then
8107                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] && suffix="M"
8108                 if [[ $orig_mb -lt 16 ]]; then
8109                         save_lustre_params $osts "$brw_size" > $p
8110                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8111                                 error "set 16MB RPC size failed"
8112
8113                         echo "remount client to enable new RPC size"
8114                         remount_client $MOUNT || error "remount_client failed"
8115                 fi
8116
8117                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8118                 # should be able to set brw_size=12, but no rpc_stats for that
8119                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8120         fi
8121
8122         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8123
8124         if [[ $orig_mb -lt 16 ]]; then
8125                 restore_lustre_params < $p
8126                 remount_client $MOUNT || error "remount_client restore failed"
8127         fi
8128
8129         rm -f $p $DIR/$tfile
8130 }
8131 run_test 101g "Big bulk(4/16 MiB) readahead"
8132
8133 setup_test102() {
8134         test_mkdir $DIR/$tdir
8135         chown $RUNAS_ID $DIR/$tdir
8136         STRIPE_SIZE=65536
8137         STRIPE_OFFSET=1
8138         STRIPE_COUNT=$OSTCOUNT
8139         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8140
8141         trap cleanup_test102 EXIT
8142         cd $DIR
8143         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8144         cd $DIR/$tdir
8145         for num in 1 2 3 4; do
8146                 for count in $(seq 1 $STRIPE_COUNT); do
8147                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8148                                 local size=`expr $STRIPE_SIZE \* $num`
8149                                 local file=file"$num-$idx-$count"
8150                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8151                         done
8152                 done
8153         done
8154
8155         cd $DIR
8156         $1 tar cf $TMP/f102.tar $tdir --xattrs
8157 }
8158
8159 cleanup_test102() {
8160         trap 0
8161         rm -f $TMP/f102.tar
8162         rm -rf $DIR/d0.sanity/d102
8163 }
8164
8165 test_102a() {
8166         [ "$UID" != 0 ] && skip "must run as root"
8167         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8168                 skip_env "must have user_xattr"
8169
8170         [ -z "$(which setfattr 2>/dev/null)" ] &&
8171                 skip_env "could not find setfattr"
8172
8173         local testfile=$DIR/$tfile
8174
8175         touch $testfile
8176         echo "set/get xattr..."
8177         setfattr -n trusted.name1 -v value1 $testfile ||
8178                 error "setfattr -n trusted.name1=value1 $testfile failed"
8179         getfattr -n trusted.name1 $testfile 2> /dev/null |
8180           grep "trusted.name1=.value1" ||
8181                 error "$testfile missing trusted.name1=value1"
8182
8183         setfattr -n user.author1 -v author1 $testfile ||
8184                 error "setfattr -n user.author1=author1 $testfile failed"
8185         getfattr -n user.author1 $testfile 2> /dev/null |
8186           grep "user.author1=.author1" ||
8187                 error "$testfile missing trusted.author1=author1"
8188
8189         echo "listxattr..."
8190         setfattr -n trusted.name2 -v value2 $testfile ||
8191                 error "$testfile unable to set trusted.name2"
8192         setfattr -n trusted.name3 -v value3 $testfile ||
8193                 error "$testfile unable to set trusted.name3"
8194         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8195             grep "trusted.name" | wc -l) -eq 3 ] ||
8196                 error "$testfile missing 3 trusted.name xattrs"
8197
8198         setfattr -n user.author2 -v author2 $testfile ||
8199                 error "$testfile unable to set user.author2"
8200         setfattr -n user.author3 -v author3 $testfile ||
8201                 error "$testfile unable to set user.author3"
8202         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8203             grep "user.author" | wc -l) -eq 3 ] ||
8204                 error "$testfile missing 3 user.author xattrs"
8205
8206         echo "remove xattr..."
8207         setfattr -x trusted.name1 $testfile ||
8208                 error "$testfile error deleting trusted.name1"
8209         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8210                 error "$testfile did not delete trusted.name1 xattr"
8211
8212         setfattr -x user.author1 $testfile ||
8213                 error "$testfile error deleting user.author1"
8214         echo "set lustre special xattr ..."
8215         $LFS setstripe -c1 $testfile
8216         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8217                 awk -F "=" '/trusted.lov/ { print $2 }' )
8218         setfattr -n "trusted.lov" -v $lovea $testfile ||
8219                 error "$testfile doesn't ignore setting trusted.lov again"
8220         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8221                 error "$testfile allow setting invalid trusted.lov"
8222         rm -f $testfile
8223 }
8224 run_test 102a "user xattr test =================================="
8225
8226 test_102b() {
8227         [ -z "$(which setfattr 2>/dev/null)" ] &&
8228                 skip_env "could not find setfattr"
8229         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8230
8231         # b10930: get/set/list trusted.lov xattr
8232         echo "get/set/list trusted.lov xattr ..."
8233         local testfile=$DIR/$tfile
8234         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8235                 error "setstripe failed"
8236         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8237                 error "getstripe failed"
8238         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8239                 error "can't get trusted.lov from $testfile"
8240
8241         local testfile2=${testfile}2
8242         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8243                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8244
8245         $MCREATE $testfile2
8246         setfattr -n trusted.lov -v $value $testfile2
8247         local stripe_size=$($LFS getstripe -S $testfile2)
8248         local stripe_count=$($LFS getstripe -c $testfile2)
8249         [[ $stripe_size -eq 65536 ]] ||
8250                 error "stripe size $stripe_size != 65536"
8251         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8252                 error "stripe count $stripe_count != $STRIPECOUNT"
8253         rm -f $DIR/$tfile
8254 }
8255 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8256
8257 test_102c() {
8258         [ -z "$(which setfattr 2>/dev/null)" ] &&
8259                 skip_env "could not find setfattr"
8260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8261
8262         # b10930: get/set/list lustre.lov xattr
8263         echo "get/set/list lustre.lov xattr ..."
8264         test_mkdir $DIR/$tdir
8265         chown $RUNAS_ID $DIR/$tdir
8266         local testfile=$DIR/$tdir/$tfile
8267         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8268                 error "setstripe failed"
8269         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8270                 error "getstripe failed"
8271         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8272         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8273
8274         local testfile2=${testfile}2
8275         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8276                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8277
8278         $RUNAS $MCREATE $testfile2
8279         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8280         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8281         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8282         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8283         [ $stripe_count -eq $STRIPECOUNT ] ||
8284                 error "stripe count $stripe_count != $STRIPECOUNT"
8285 }
8286 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8287
8288 compare_stripe_info1() {
8289         local stripe_index_all_zero=true
8290
8291         for num in 1 2 3 4; do
8292                 for count in $(seq 1 $STRIPE_COUNT); do
8293                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8294                                 local size=$((STRIPE_SIZE * num))
8295                                 local file=file"$num-$offset-$count"
8296                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8297                                 [[ $stripe_size -ne $size ]] &&
8298                                     error "$file: size $stripe_size != $size"
8299                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8300                                 # allow fewer stripes to be created, ORI-601
8301                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8302                                     error "$file: count $stripe_count != $count"
8303                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8304                                 [[ $stripe_index -ne 0 ]] &&
8305                                         stripe_index_all_zero=false
8306                         done
8307                 done
8308         done
8309         $stripe_index_all_zero &&
8310                 error "all files are being extracted starting from OST index 0"
8311         return 0
8312 }
8313
8314 have_xattrs_include() {
8315         tar --help | grep -q xattrs-include &&
8316                 echo --xattrs-include="lustre.*"
8317 }
8318
8319 test_102d() {
8320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8321         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8322
8323         XINC=$(have_xattrs_include)
8324         setup_test102
8325         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8326         cd $DIR/$tdir/$tdir
8327         compare_stripe_info1
8328 }
8329 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8330
8331 test_102f() {
8332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8334
8335         XINC=$(have_xattrs_include)
8336         setup_test102
8337         test_mkdir $DIR/$tdir.restore
8338         cd $DIR
8339         tar cf - --xattrs $tdir | tar xf - \
8340                 -C $DIR/$tdir.restore --xattrs $XINC
8341         cd $DIR/$tdir.restore/$tdir
8342         compare_stripe_info1
8343 }
8344 run_test 102f "tar copy files, not keep osts"
8345
8346 grow_xattr() {
8347         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8348                 skip "must have user_xattr"
8349         [ -z "$(which setfattr 2>/dev/null)" ] &&
8350                 skip_env "could not find setfattr"
8351         [ -z "$(which getfattr 2>/dev/null)" ] &&
8352                 skip_env "could not find getfattr"
8353
8354         local xsize=${1:-1024}  # in bytes
8355         local file=$DIR/$tfile
8356         local value="$(generate_string $xsize)"
8357         local xbig=trusted.big
8358
8359         touch $file
8360         log "save $xbig on $file"
8361         setfattr -n $xbig -v $value $file ||
8362                 error "saving $xbig on $file failed"
8363
8364         local orig=$(get_xattr_value $xbig $file)
8365         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8366
8367         local xsml=trusted.sml
8368         log "save $xsml on $file"
8369         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8370
8371         local new=$(get_xattr_value $xbig $file)
8372         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8373
8374         log "grow $xsml on $file"
8375         setfattr -n $xsml -v "$value" $file ||
8376                 error "growing $xsml on $file failed"
8377
8378         new=$(get_xattr_value $xbig $file)
8379         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8380         log "$xbig still valid after growing $xsml"
8381
8382         rm -f $file
8383 }
8384
8385 test_102h() { # bug 15777
8386         grow_xattr 1024
8387 }
8388 run_test 102h "grow xattr from inside inode to external block"
8389
8390 test_102ha() {
8391         large_xattr_enabled || skip_env "ea_inode feature disabled"
8392
8393         grow_xattr $(max_xattr_size)
8394 }
8395 run_test 102ha "grow xattr from inside inode to external inode"
8396
8397 test_102i() { # bug 17038
8398         [ -z "$(which getfattr 2>/dev/null)" ] &&
8399                 skip "could not find getfattr"
8400
8401         touch $DIR/$tfile
8402         ln -s $DIR/$tfile $DIR/${tfile}link
8403         getfattr -n trusted.lov $DIR/$tfile ||
8404                 error "lgetxattr on $DIR/$tfile failed"
8405         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8406                 grep -i "no such attr" ||
8407                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8408         rm -f $DIR/$tfile $DIR/${tfile}link
8409 }
8410 run_test 102i "lgetxattr test on symbolic link ============"
8411
8412 test_102j() {
8413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8415
8416         XINC=$(have_xattrs_include)
8417         setup_test102 "$RUNAS"
8418         chown $RUNAS_ID $DIR/$tdir
8419         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8420         cd $DIR/$tdir/$tdir
8421         compare_stripe_info1 "$RUNAS"
8422 }
8423 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8424
8425 test_102k() {
8426         [ -z "$(which setfattr 2>/dev/null)" ] &&
8427                 skip "could not find setfattr"
8428
8429         touch $DIR/$tfile
8430         # b22187 just check that does not crash for regular file.
8431         setfattr -n trusted.lov $DIR/$tfile
8432         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8433         local test_kdir=$DIR/$tdir
8434         test_mkdir $test_kdir
8435         local default_size=$($LFS getstripe -S $test_kdir)
8436         local default_count=$($LFS getstripe -c $test_kdir)
8437         local default_offset=$($LFS getstripe -i $test_kdir)
8438         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8439                 error 'dir setstripe failed'
8440         setfattr -n trusted.lov $test_kdir
8441         local stripe_size=$($LFS getstripe -S $test_kdir)
8442         local stripe_count=$($LFS getstripe -c $test_kdir)
8443         local stripe_offset=$($LFS getstripe -i $test_kdir)
8444         [ $stripe_size -eq $default_size ] ||
8445                 error "stripe size $stripe_size != $default_size"
8446         [ $stripe_count -eq $default_count ] ||
8447                 error "stripe count $stripe_count != $default_count"
8448         [ $stripe_offset -eq $default_offset ] ||
8449                 error "stripe offset $stripe_offset != $default_offset"
8450         rm -rf $DIR/$tfile $test_kdir
8451 }
8452 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8453
8454 test_102l() {
8455         [ -z "$(which getfattr 2>/dev/null)" ] &&
8456                 skip "could not find getfattr"
8457
8458         # LU-532 trusted. xattr is invisible to non-root
8459         local testfile=$DIR/$tfile
8460
8461         touch $testfile
8462
8463         echo "listxattr as user..."
8464         chown $RUNAS_ID $testfile
8465         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8466             grep -q "trusted" &&
8467                 error "$testfile trusted xattrs are user visible"
8468
8469         return 0;
8470 }
8471 run_test 102l "listxattr size test =================================="
8472
8473 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8474         local path=$DIR/$tfile
8475         touch $path
8476
8477         listxattr_size_check $path || error "listattr_size_check $path failed"
8478 }
8479 run_test 102m "Ensure listxattr fails on small bufffer ========"
8480
8481 cleanup_test102
8482
8483 getxattr() { # getxattr path name
8484         # Return the base64 encoding of the value of xattr name on path.
8485         local path=$1
8486         local name=$2
8487
8488         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8489         # file: $path
8490         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8491         #
8492         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8493
8494         getfattr --absolute-names --encoding=base64 --name=$name $path |
8495                 awk -F= -v name=$name '$1 == name {
8496                         print substr($0, index($0, "=") + 1);
8497         }'
8498 }
8499
8500 test_102n() { # LU-4101 mdt: protect internal xattrs
8501         [ -z "$(which setfattr 2>/dev/null)" ] &&
8502                 skip "could not find setfattr"
8503         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8504         then
8505                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8506         fi
8507
8508         local file0=$DIR/$tfile.0
8509         local file1=$DIR/$tfile.1
8510         local xattr0=$TMP/$tfile.0
8511         local xattr1=$TMP/$tfile.1
8512         local namelist="lov lma lmv link fid version som hsm"
8513         local name
8514         local value
8515
8516         rm -rf $file0 $file1 $xattr0 $xattr1
8517         touch $file0 $file1
8518
8519         # Get 'before' xattrs of $file1.
8520         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8521
8522         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8523                 namelist+=" lfsck_namespace"
8524         for name in $namelist; do
8525                 # Try to copy xattr from $file0 to $file1.
8526                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8527
8528                 setfattr --name=trusted.$name --value="$value" $file1 ||
8529                         error "setxattr 'trusted.$name' failed"
8530
8531                 # Try to set a garbage xattr.
8532                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8533
8534                 if [[ x$name == "xlov" ]]; then
8535                         setfattr --name=trusted.lov --value="$value" $file1 &&
8536                         error "setxattr invalid 'trusted.lov' success"
8537                 else
8538                         setfattr --name=trusted.$name --value="$value" $file1 ||
8539                                 error "setxattr invalid 'trusted.$name' failed"
8540                 fi
8541
8542                 # Try to remove the xattr from $file1. We don't care if this
8543                 # appears to succeed or fail, we just don't want there to be
8544                 # any changes or crashes.
8545                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8546         done
8547
8548         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8549         then
8550                 name="lfsck_ns"
8551                 # Try to copy xattr from $file0 to $file1.
8552                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8553
8554                 setfattr --name=trusted.$name --value="$value" $file1 ||
8555                         error "setxattr 'trusted.$name' failed"
8556
8557                 # Try to set a garbage xattr.
8558                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8559
8560                 setfattr --name=trusted.$name --value="$value" $file1 ||
8561                         error "setxattr 'trusted.$name' failed"
8562
8563                 # Try to remove the xattr from $file1. We don't care if this
8564                 # appears to succeed or fail, we just don't want there to be
8565                 # any changes or crashes.
8566                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8567         fi
8568
8569         # Get 'after' xattrs of file1.
8570         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8571
8572         if ! diff $xattr0 $xattr1; then
8573                 error "before and after xattrs of '$file1' differ"
8574         fi
8575
8576         rm -rf $file0 $file1 $xattr0 $xattr1
8577
8578         return 0
8579 }
8580 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8581
8582 test_102p() { # LU-4703 setxattr did not check ownership
8583         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8584                 skip "MDS needs to be at least 2.5.56"
8585
8586         local testfile=$DIR/$tfile
8587
8588         touch $testfile
8589
8590         echo "setfacl as user..."
8591         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8592         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8593
8594         echo "setfattr as user..."
8595         setfacl -m "u:$RUNAS_ID:---" $testfile
8596         $RUNAS setfattr -x system.posix_acl_access $testfile
8597         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8598 }
8599 run_test 102p "check setxattr(2) correctly fails without permission"
8600
8601 test_102q() {
8602         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8603                 skip "MDS needs to be at least 2.6.92"
8604
8605         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8606 }
8607 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8608
8609 test_102r() {
8610         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8611                 skip "MDS needs to be at least 2.6.93"
8612
8613         touch $DIR/$tfile || error "touch"
8614         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8615         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8616         rm $DIR/$tfile || error "rm"
8617
8618         #normal directory
8619         mkdir -p $DIR/$tdir || error "mkdir"
8620         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8621         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8622         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8623                 error "$testfile error deleting user.author1"
8624         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8625                 grep "user.$(basename $tdir)" &&
8626                 error "$tdir did not delete user.$(basename $tdir)"
8627         rmdir $DIR/$tdir || error "rmdir"
8628
8629         #striped directory
8630         test_mkdir $DIR/$tdir
8631         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8632         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8633         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8634                 error "$testfile error deleting user.author1"
8635         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8636                 grep "user.$(basename $tdir)" &&
8637                 error "$tdir did not delete user.$(basename $tdir)"
8638         rmdir $DIR/$tdir || error "rm striped dir"
8639 }
8640 run_test 102r "set EAs with empty values"
8641
8642 test_102s() {
8643         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8644                 skip "MDS needs to be at least 2.11.52"
8645
8646         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8647
8648         save_lustre_params client "llite.*.xattr_cache" > $save
8649
8650         for cache in 0 1; do
8651                 lctl set_param llite.*.xattr_cache=$cache
8652
8653                 rm -f $DIR/$tfile
8654                 touch $DIR/$tfile || error "touch"
8655                 for prefix in lustre security system trusted user; do
8656                         # Note getxattr() may fail with 'Operation not
8657                         # supported' or 'No such attribute' depending
8658                         # on prefix and cache.
8659                         getfattr -n $prefix.n102s $DIR/$tfile &&
8660                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8661                 done
8662         done
8663
8664         restore_lustre_params < $save
8665 }
8666 run_test 102s "getting nonexistent xattrs should fail"
8667
8668 test_102t() {
8669         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8670                 skip "MDS needs to be at least 2.11.52"
8671
8672         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8673
8674         save_lustre_params client "llite.*.xattr_cache" > $save
8675
8676         for cache in 0 1; do
8677                 lctl set_param llite.*.xattr_cache=$cache
8678
8679                 for buf_size in 0 256; do
8680                         rm -f $DIR/$tfile
8681                         touch $DIR/$tfile || error "touch"
8682                         setfattr -n user.multiop $DIR/$tfile
8683                         $MULTIOP $DIR/$tfile oa$buf_size ||
8684                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8685                 done
8686         done
8687
8688         restore_lustre_params < $save
8689 }
8690 run_test 102t "zero length xattr values handled correctly"
8691
8692 run_acl_subtest()
8693 {
8694     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8695     return $?
8696 }
8697
8698 test_103a() {
8699         [ "$UID" != 0 ] && skip "must run as root"
8700         $GSS && skip_env "could not run under gss"
8701         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8702                 skip_env "must have acl enabled"
8703         [ -z "$(which setfacl 2>/dev/null)" ] &&
8704                 skip_env "could not find setfacl"
8705         remote_mds_nodsh && skip "remote MDS with nodsh"
8706
8707         gpasswd -a daemon bin                           # LU-5641
8708         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8709
8710         declare -a identity_old
8711
8712         for num in $(seq $MDSCOUNT); do
8713                 switch_identity $num true || identity_old[$num]=$?
8714         done
8715
8716         SAVE_UMASK=$(umask)
8717         umask 0022
8718         mkdir -p $DIR/$tdir
8719         cd $DIR/$tdir
8720
8721         echo "performing cp ..."
8722         run_acl_subtest cp || error "run_acl_subtest cp failed"
8723         echo "performing getfacl-noacl..."
8724         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8725         echo "performing misc..."
8726         run_acl_subtest misc || error  "misc test failed"
8727         echo "performing permissions..."
8728         run_acl_subtest permissions || error "permissions failed"
8729         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8730         if [ $MDS1_VERSION -gt $(version_code 2.8.55) -o \
8731              \( $MDS1_VERSION -lt $(version_code 2.6) -a \
8732              $MDS1_VERSION -ge $(version_code 2.5.29) \) ]
8733         then
8734                 echo "performing permissions xattr..."
8735                 run_acl_subtest permissions_xattr ||
8736                         error "permissions_xattr failed"
8737         fi
8738         echo "performing setfacl..."
8739         run_acl_subtest setfacl || error  "setfacl test failed"
8740
8741         # inheritance test got from HP
8742         echo "performing inheritance..."
8743         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8744         chmod +x make-tree || error "chmod +x failed"
8745         run_acl_subtest inheritance || error "inheritance test failed"
8746         rm -f make-tree
8747
8748         echo "LU-974 ignore umask when acl is enabled..."
8749         run_acl_subtest 974 || error "LU-974 umask test failed"
8750         if [ $MDSCOUNT -ge 2 ]; then
8751                 run_acl_subtest 974_remote ||
8752                         error "LU-974 umask test failed under remote dir"
8753         fi
8754
8755         echo "LU-2561 newly created file is same size as directory..."
8756         if [ "$mds1_FSTYPE" != "zfs" ]; then
8757                 run_acl_subtest 2561 || error "LU-2561 test failed"
8758         else
8759                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8760         fi
8761
8762         run_acl_subtest 4924 || error "LU-4924 test failed"
8763
8764         cd $SAVE_PWD
8765         umask $SAVE_UMASK
8766
8767         for num in $(seq $MDSCOUNT); do
8768                 if [ "${identity_old[$num]}" = 1 ]; then
8769                         switch_identity $num false || identity_old[$num]=$?
8770                 fi
8771         done
8772 }
8773 run_test 103a "acl test"
8774
8775 test_103b() {
8776         declare -a pids
8777         local U
8778
8779         for U in {0..511}; do
8780                 {
8781                 local O=$(printf "%04o" $U)
8782
8783                 umask $(printf "%04o" $((511 ^ $O)))
8784                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8785                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8786
8787                 (( $S == ($O & 0666) )) ||
8788                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8789
8790                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8791                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8792                 (( $S == ($O & 0666) )) ||
8793                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8794
8795                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8796                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8797                 (( $S == ($O & 0666) )) ||
8798                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8799                 rm -f $DIR/$tfile.[smp]$0
8800                 } &
8801                 local pid=$!
8802
8803                 # limit the concurrently running threads to 64. LU-11878
8804                 local idx=$((U % 64))
8805                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8806                 pids[idx]=$pid
8807         done
8808         wait
8809 }
8810 run_test 103b "umask lfs setstripe"
8811
8812 test_103c() {
8813         mkdir -p $DIR/$tdir
8814         cp -rp $DIR/$tdir $DIR/$tdir.bak
8815
8816         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8817                 error "$DIR/$tdir shouldn't contain default ACL"
8818         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8819                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8820         true
8821 }
8822 run_test 103c "'cp -rp' won't set empty acl"
8823
8824 test_104a() {
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826
8827         touch $DIR/$tfile
8828         lfs df || error "lfs df failed"
8829         lfs df -ih || error "lfs df -ih failed"
8830         lfs df -h $DIR || error "lfs df -h $DIR failed"
8831         lfs df -i $DIR || error "lfs df -i $DIR failed"
8832         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8833         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8834
8835         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8836         lctl --device %$OSC deactivate
8837         lfs df || error "lfs df with deactivated OSC failed"
8838         lctl --device %$OSC activate
8839         # wait the osc back to normal
8840         wait_osc_import_ready client ost
8841
8842         lfs df || error "lfs df with reactivated OSC failed"
8843         rm -f $DIR/$tfile
8844 }
8845 run_test 104a "lfs df [-ih] [path] test ========================="
8846
8847 test_104b() {
8848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8849         [ $RUNAS_ID -eq $UID ] &&
8850                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8851
8852         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8853                         grep "Permission denied" | wc -l)))
8854         if [ $denied_cnt -ne 0 ]; then
8855                 error "lfs check servers test failed"
8856         fi
8857 }
8858 run_test 104b "$RUNAS lfs check servers test ===================="
8859
8860 test_105a() {
8861         # doesn't work on 2.4 kernels
8862         touch $DIR/$tfile
8863         if $(flock_is_enabled); then
8864                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8865         else
8866                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8867         fi
8868         rm -f $DIR/$tfile
8869 }
8870 run_test 105a "flock when mounted without -o flock test ========"
8871
8872 test_105b() {
8873         touch $DIR/$tfile
8874         if $(flock_is_enabled); then
8875                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8876         else
8877                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8878         fi
8879         rm -f $DIR/$tfile
8880 }
8881 run_test 105b "fcntl when mounted without -o flock test ========"
8882
8883 test_105c() {
8884         touch $DIR/$tfile
8885         if $(flock_is_enabled); then
8886                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8887         else
8888                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8889         fi
8890         rm -f $DIR/$tfile
8891 }
8892 run_test 105c "lockf when mounted without -o flock test"
8893
8894 test_105d() { # bug 15924
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896
8897         test_mkdir $DIR/$tdir
8898         flock_is_enabled || skip_env "mount w/o flock enabled"
8899         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8900         $LCTL set_param fail_loc=0x80000315
8901         flocks_test 2 $DIR/$tdir
8902 }
8903 run_test 105d "flock race (should not freeze) ========"
8904
8905 test_105e() { # bug 22660 && 22040
8906         flock_is_enabled || skip_env "mount w/o flock enabled"
8907
8908         touch $DIR/$tfile
8909         flocks_test 3 $DIR/$tfile
8910 }
8911 run_test 105e "Two conflicting flocks from same process"
8912
8913 test_106() { #bug 10921
8914         test_mkdir $DIR/$tdir
8915         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8916         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8917 }
8918 run_test 106 "attempt exec of dir followed by chown of that dir"
8919
8920 test_107() {
8921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8922
8923         CDIR=`pwd`
8924         local file=core
8925
8926         cd $DIR
8927         rm -f $file
8928
8929         local save_pattern=$(sysctl -n kernel.core_pattern)
8930         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8931         sysctl -w kernel.core_pattern=$file
8932         sysctl -w kernel.core_uses_pid=0
8933
8934         ulimit -c unlimited
8935         sleep 60 &
8936         SLEEPPID=$!
8937
8938         sleep 1
8939
8940         kill -s 11 $SLEEPPID
8941         wait $SLEEPPID
8942         if [ -e $file ]; then
8943                 size=`stat -c%s $file`
8944                 [ $size -eq 0 ] && error "Fail to create core file $file"
8945         else
8946                 error "Fail to create core file $file"
8947         fi
8948         rm -f $file
8949         sysctl -w kernel.core_pattern=$save_pattern
8950         sysctl -w kernel.core_uses_pid=$save_uses_pid
8951         cd $CDIR
8952 }
8953 run_test 107 "Coredump on SIG"
8954
8955 test_110() {
8956         test_mkdir $DIR/$tdir
8957         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8958         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8959                 error "mkdir with 256 char should fail, but did not"
8960         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8961                 error "create with 255 char failed"
8962         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8963                 error "create with 256 char should fail, but did not"
8964
8965         ls -l $DIR/$tdir
8966         rm -rf $DIR/$tdir
8967 }
8968 run_test 110 "filename length checking"
8969
8970 #
8971 # Purpose: To verify dynamic thread (OSS) creation.
8972 #
8973 test_115() {
8974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8975         remote_ost_nodsh && skip "remote OST with nodsh"
8976
8977         # Lustre does not stop service threads once they are started.
8978         # Reset number of running threads to default.
8979         stopall
8980         setupall
8981
8982         local OSTIO_pre
8983         local save_params="$TMP/sanity-$TESTNAME.parameters"
8984
8985         # Get ll_ost_io count before I/O
8986         OSTIO_pre=$(do_facet ost1 \
8987                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
8988         # Exit if lustre is not running (ll_ost_io not running).
8989         [ -z "$OSTIO_pre" ] && error "no OSS threads"
8990
8991         echo "Starting with $OSTIO_pre threads"
8992         local thread_max=$((OSTIO_pre * 2))
8993         local rpc_in_flight=$((thread_max * 2))
8994         # Number of I/O Process proposed to be started.
8995         local nfiles
8996         local facets=$(get_facets OST)
8997
8998         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
8999         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9000
9001         # Set in_flight to $rpc_in_flight
9002         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9003                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9004         nfiles=${rpc_in_flight}
9005         # Set ost thread_max to $thread_max
9006         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9007
9008         # 5 Minutes should be sufficient for max number of OSS
9009         # threads(thread_max) to be created.
9010         local timeout=300
9011
9012         # Start I/O.
9013         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9014         test_mkdir $DIR/$tdir
9015         for i in $(seq $nfiles); do
9016                 local file=$DIR/$tdir/${tfile}-$i
9017                 $LFS setstripe -c -1 -i 0 $file
9018                 ($WTL $file $timeout)&
9019         done
9020
9021         # I/O Started - Wait for thread_started to reach thread_max or report
9022         # error if thread_started is more than thread_max.
9023         echo "Waiting for thread_started to reach thread_max"
9024         local thread_started=0
9025         local end_time=$((SECONDS + timeout))
9026
9027         while [ $SECONDS -le $end_time ] ; do
9028                 echo -n "."
9029                 # Get ost i/o thread_started count.
9030                 thread_started=$(do_facet ost1 \
9031                         "$LCTL get_param \
9032                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9033                 # Break out if thread_started is equal/greater than thread_max
9034                 if [[ $thread_started -ge $thread_max ]]; then
9035                         echo ll_ost_io thread_started $thread_started, \
9036                                 equal/greater than thread_max $thread_max
9037                         break
9038                 fi
9039                 sleep 1
9040         done
9041
9042         # Cleanup - We have the numbers, Kill i/o jobs if running.
9043         jobcount=($(jobs -p))
9044         for i in $(seq 0 $((${#jobcount[@]}-1)))
9045         do
9046                 kill -9 ${jobcount[$i]}
9047                 if [ $? -ne 0 ] ; then
9048                         echo Warning: \
9049                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9050                 fi
9051         done
9052
9053         # Cleanup files left by WTL binary.
9054         for i in $(seq $nfiles); do
9055                 local file=$DIR/$tdir/${tfile}-$i
9056                 rm -rf $file
9057                 if [ $? -ne 0 ] ; then
9058                         echo "Warning: Failed to delete file $file"
9059                 fi
9060         done
9061
9062         restore_lustre_params <$save_params
9063         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9064
9065         # Error out if no new thread has started or Thread started is greater
9066         # than thread max.
9067         if [[ $thread_started -le $OSTIO_pre ||
9068                         $thread_started -gt $thread_max ]]; then
9069                 error "ll_ost_io: thread_started $thread_started" \
9070                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9071                       "No new thread started or thread started greater " \
9072                       "than thread_max."
9073         fi
9074 }
9075 run_test 115 "verify dynamic thread creation===================="
9076
9077 free_min_max () {
9078         wait_delete_completed
9079         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9080         echo "OST kbytes available: ${AVAIL[@]}"
9081         MAXV=${AVAIL[0]}
9082         MAXI=0
9083         MINV=${AVAIL[0]}
9084         MINI=0
9085         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9086                 #echo OST $i: ${AVAIL[i]}kb
9087                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9088                         MAXV=${AVAIL[i]}
9089                         MAXI=$i
9090                 fi
9091                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9092                         MINV=${AVAIL[i]}
9093                         MINI=$i
9094                 fi
9095         done
9096         echo "Min free space: OST $MINI: $MINV"
9097         echo "Max free space: OST $MAXI: $MAXV"
9098 }
9099
9100 test_116a() { # was previously test_116()
9101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9103         remote_mds_nodsh && skip "remote MDS with nodsh"
9104
9105         echo -n "Free space priority "
9106         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9107                 head -n1
9108         declare -a AVAIL
9109         free_min_max
9110
9111         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9112         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9113         trap simple_cleanup_common EXIT
9114
9115         # Check if we need to generate uneven OSTs
9116         test_mkdir -p $DIR/$tdir/OST${MINI}
9117         local FILL=$((MINV / 4))
9118         local DIFF=$((MAXV - MINV))
9119         local DIFF2=$((DIFF * 100 / MINV))
9120
9121         local threshold=$(do_facet $SINGLEMDS \
9122                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9123         threshold=${threshold%%%}
9124         echo -n "Check for uneven OSTs: "
9125         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9126
9127         if [[ $DIFF2 -gt $threshold ]]; then
9128                 echo "ok"
9129                 echo "Don't need to fill OST$MINI"
9130         else
9131                 # generate uneven OSTs. Write 2% over the QOS threshold value
9132                 echo "no"
9133                 DIFF=$((threshold - DIFF2 + 2))
9134                 DIFF2=$((MINV * DIFF / 100))
9135                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9136                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9137                         error "setstripe failed"
9138                 DIFF=$((DIFF2 / 2048))
9139                 i=0
9140                 while [ $i -lt $DIFF ]; do
9141                         i=$((i + 1))
9142                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9143                                 bs=2M count=1 2>/dev/null
9144                         echo -n .
9145                 done
9146                 echo .
9147                 sync
9148                 sleep_maxage
9149                 free_min_max
9150         fi
9151
9152         DIFF=$((MAXV - MINV))
9153         DIFF2=$((DIFF * 100 / MINV))
9154         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9155         if [ $DIFF2 -gt $threshold ]; then
9156                 echo "ok"
9157         else
9158                 echo "failed - QOS mode won't be used"
9159                 simple_cleanup_common
9160                 skip "QOS imbalance criteria not met"
9161         fi
9162
9163         MINI1=$MINI
9164         MINV1=$MINV
9165         MAXI1=$MAXI
9166         MAXV1=$MAXV
9167
9168         # now fill using QOS
9169         $LFS setstripe -c 1 $DIR/$tdir
9170         FILL=$((FILL / 200))
9171         if [ $FILL -gt 600 ]; then
9172                 FILL=600
9173         fi
9174         echo "writing $FILL files to QOS-assigned OSTs"
9175         i=0
9176         while [ $i -lt $FILL ]; do
9177                 i=$((i + 1))
9178                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9179                         count=1 2>/dev/null
9180                 echo -n .
9181         done
9182         echo "wrote $i 200k files"
9183         sync
9184         sleep_maxage
9185
9186         echo "Note: free space may not be updated, so measurements might be off"
9187         free_min_max
9188         DIFF2=$((MAXV - MINV))
9189         echo "free space delta: orig $DIFF final $DIFF2"
9190         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9191         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9192         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9193         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9194         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9195         if [[ $DIFF -gt 0 ]]; then
9196                 FILL=$((DIFF2 * 100 / DIFF - 100))
9197                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9198         fi
9199
9200         # Figure out which files were written where
9201         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9202                awk '/'$MINI1': / {print $2; exit}')
9203         echo $UUID
9204         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9205         echo "$MINC files created on smaller OST $MINI1"
9206         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9207                awk '/'$MAXI1': / {print $2; exit}')
9208         echo $UUID
9209         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9210         echo "$MAXC files created on larger OST $MAXI1"
9211         if [[ $MINC -gt 0 ]]; then
9212                 FILL=$((MAXC * 100 / MINC - 100))
9213                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9214         fi
9215         [[ $MAXC -gt $MINC ]] ||
9216                 error_ignore LU-9 "stripe QOS didn't balance free space"
9217         simple_cleanup_common
9218 }
9219 run_test 116a "stripe QOS: free space balance ==================="
9220
9221 test_116b() { # LU-2093
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223         remote_mds_nodsh && skip "remote MDS with nodsh"
9224
9225 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9226         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9227                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9228         [ -z "$old_rr" ] && skip "no QOS"
9229         do_facet $SINGLEMDS lctl set_param \
9230                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9231         mkdir -p $DIR/$tdir
9232         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9233         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9234         do_facet $SINGLEMDS lctl set_param fail_loc=0
9235         rm -rf $DIR/$tdir
9236         do_facet $SINGLEMDS lctl set_param \
9237                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9238 }
9239 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9240
9241 test_117() # bug 10891
9242 {
9243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9244
9245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9246         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9247         lctl set_param fail_loc=0x21e
9248         > $DIR/$tfile || error "truncate failed"
9249         lctl set_param fail_loc=0
9250         echo "Truncate succeeded."
9251         rm -f $DIR/$tfile
9252 }
9253 run_test 117 "verify osd extend =========="
9254
9255 NO_SLOW_RESENDCOUNT=4
9256 export OLD_RESENDCOUNT=""
9257 set_resend_count () {
9258         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9259         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9260         lctl set_param -n $PROC_RESENDCOUNT $1
9261         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9262 }
9263
9264 # for reduce test_118* time (b=14842)
9265 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9266
9267 # Reset async IO behavior after error case
9268 reset_async() {
9269         FILE=$DIR/reset_async
9270
9271         # Ensure all OSCs are cleared
9272         $LFS setstripe -c -1 $FILE
9273         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9274         sync
9275         rm $FILE
9276 }
9277
9278 test_118a() #bug 11710
9279 {
9280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9281
9282         reset_async
9283
9284         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9285         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9286         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9287
9288         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9289                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9290                 return 1;
9291         fi
9292         rm -f $DIR/$tfile
9293 }
9294 run_test 118a "verify O_SYNC works =========="
9295
9296 test_118b()
9297 {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299         remote_ost_nodsh && skip "remote OST with nodsh"
9300
9301         reset_async
9302
9303         #define OBD_FAIL_SRV_ENOENT 0x217
9304         set_nodes_failloc "$(osts_nodes)" 0x217
9305         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9306         RC=$?
9307         set_nodes_failloc "$(osts_nodes)" 0
9308         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9309         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9310                     grep -c writeback)
9311
9312         if [[ $RC -eq 0 ]]; then
9313                 error "Must return error due to dropped pages, rc=$RC"
9314                 return 1;
9315         fi
9316
9317         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9318                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9319                 return 1;
9320         fi
9321
9322         echo "Dirty pages not leaked on ENOENT"
9323
9324         # Due to the above error the OSC will issue all RPCs syncronously
9325         # until a subsequent RPC completes successfully without error.
9326         $MULTIOP $DIR/$tfile Ow4096yc
9327         rm -f $DIR/$tfile
9328
9329         return 0
9330 }
9331 run_test 118b "Reclaim dirty pages on fatal error =========="
9332
9333 test_118c()
9334 {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         # for 118c, restore the original resend count, LU-1940
9338         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9339                                 set_resend_count $OLD_RESENDCOUNT
9340         remote_ost_nodsh && skip "remote OST with nodsh"
9341
9342         reset_async
9343
9344         #define OBD_FAIL_OST_EROFS               0x216
9345         set_nodes_failloc "$(osts_nodes)" 0x216
9346
9347         # multiop should block due to fsync until pages are written
9348         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9349         MULTIPID=$!
9350         sleep 1
9351
9352         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9353                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9354         fi
9355
9356         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9357                     grep -c writeback)
9358         if [[ $WRITEBACK -eq 0 ]]; then
9359                 error "No page in writeback, writeback=$WRITEBACK"
9360         fi
9361
9362         set_nodes_failloc "$(osts_nodes)" 0
9363         wait $MULTIPID
9364         RC=$?
9365         if [[ $RC -ne 0 ]]; then
9366                 error "Multiop fsync failed, rc=$RC"
9367         fi
9368
9369         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9370         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9371                     grep -c writeback)
9372         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9373                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9374         fi
9375
9376         rm -f $DIR/$tfile
9377         echo "Dirty pages flushed via fsync on EROFS"
9378         return 0
9379 }
9380 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9381
9382 # continue to use small resend count to reduce test_118* time (b=14842)
9383 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9384
9385 test_118d()
9386 {
9387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9388         remote_ost_nodsh && skip "remote OST with nodsh"
9389
9390         reset_async
9391
9392         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9393         set_nodes_failloc "$(osts_nodes)" 0x214
9394         # multiop should block due to fsync until pages are written
9395         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9396         MULTIPID=$!
9397         sleep 1
9398
9399         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9400                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9401         fi
9402
9403         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9404                     grep -c writeback)
9405         if [[ $WRITEBACK -eq 0 ]]; then
9406                 error "No page in writeback, writeback=$WRITEBACK"
9407         fi
9408
9409         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9410         set_nodes_failloc "$(osts_nodes)" 0
9411
9412         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9413         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9414                     grep -c writeback)
9415         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9416                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9417         fi
9418
9419         rm -f $DIR/$tfile
9420         echo "Dirty pages gaurenteed flushed via fsync"
9421         return 0
9422 }
9423 run_test 118d "Fsync validation inject a delay of the bulk =========="
9424
9425 test_118f() {
9426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9427
9428         reset_async
9429
9430         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9431         lctl set_param fail_loc=0x8000040a
9432
9433         # Should simulate EINVAL error which is fatal
9434         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9435         RC=$?
9436         if [[ $RC -eq 0 ]]; then
9437                 error "Must return error due to dropped pages, rc=$RC"
9438         fi
9439
9440         lctl set_param fail_loc=0x0
9441
9442         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
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 [[ $LOCKED -ne 0 ]]; then
9447                 error "Locked pages remain in cache, locked=$LOCKED"
9448         fi
9449
9450         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9451                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9452         fi
9453
9454         rm -f $DIR/$tfile
9455         echo "No pages locked after fsync"
9456
9457         reset_async
9458         return 0
9459 }
9460 run_test 118f "Simulate unrecoverable OSC side error =========="
9461
9462 test_118g() {
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464
9465         reset_async
9466
9467         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9468         lctl set_param fail_loc=0x406
9469
9470         # simulate local -ENOMEM
9471         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9472         RC=$?
9473
9474         lctl set_param fail_loc=0
9475         if [[ $RC -eq 0 ]]; then
9476                 error "Must return error due to dropped pages, rc=$RC"
9477         fi
9478
9479         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9480         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9481         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9482                         grep -c writeback)
9483         if [[ $LOCKED -ne 0 ]]; then
9484                 error "Locked pages remain in cache, locked=$LOCKED"
9485         fi
9486
9487         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9488                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9489         fi
9490
9491         rm -f $DIR/$tfile
9492         echo "No pages locked after fsync"
9493
9494         reset_async
9495         return 0
9496 }
9497 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9498
9499 test_118h() {
9500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9501         remote_ost_nodsh && skip "remote OST with nodsh"
9502
9503         reset_async
9504
9505         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9506         set_nodes_failloc "$(osts_nodes)" 0x20e
9507         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9508         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9509         RC=$?
9510
9511         set_nodes_failloc "$(osts_nodes)" 0
9512         if [[ $RC -eq 0 ]]; then
9513                 error "Must return error due to dropped pages, rc=$RC"
9514         fi
9515
9516         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9517         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9518         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9519                     grep -c writeback)
9520         if [[ $LOCKED -ne 0 ]]; then
9521                 error "Locked pages remain in cache, locked=$LOCKED"
9522         fi
9523
9524         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9525                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9526         fi
9527
9528         rm -f $DIR/$tfile
9529         echo "No pages locked after fsync"
9530
9531         return 0
9532 }
9533 run_test 118h "Verify timeout in handling recoverables errors  =========="
9534
9535 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9536
9537 test_118i() {
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539         remote_ost_nodsh && skip "remote OST with nodsh"
9540
9541         reset_async
9542
9543         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9544         set_nodes_failloc "$(osts_nodes)" 0x20e
9545
9546         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9547         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9548         PID=$!
9549         sleep 5
9550         set_nodes_failloc "$(osts_nodes)" 0
9551
9552         wait $PID
9553         RC=$?
9554         if [[ $RC -ne 0 ]]; then
9555                 error "got error, but should be not, rc=$RC"
9556         fi
9557
9558         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9559         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9560         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9561         if [[ $LOCKED -ne 0 ]]; then
9562                 error "Locked pages remain in cache, locked=$LOCKED"
9563         fi
9564
9565         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9566                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9567         fi
9568
9569         rm -f $DIR/$tfile
9570         echo "No pages locked after fsync"
9571
9572         return 0
9573 }
9574 run_test 118i "Fix error before timeout in recoverable error  =========="
9575
9576 [ "$SLOW" = "no" ] && set_resend_count 4
9577
9578 test_118j() {
9579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9580         remote_ost_nodsh && skip "remote OST with nodsh"
9581
9582         reset_async
9583
9584         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9585         set_nodes_failloc "$(osts_nodes)" 0x220
9586
9587         # return -EIO from OST
9588         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9589         RC=$?
9590         set_nodes_failloc "$(osts_nodes)" 0x0
9591         if [[ $RC -eq 0 ]]; then
9592                 error "Must return error due to dropped pages, rc=$RC"
9593         fi
9594
9595         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9596         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9597         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9598         if [[ $LOCKED -ne 0 ]]; then
9599                 error "Locked pages remain in cache, locked=$LOCKED"
9600         fi
9601
9602         # in recoverable error on OST we want resend and stay until it finished
9603         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9604                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9605         fi
9606
9607         rm -f $DIR/$tfile
9608         echo "No pages locked after fsync"
9609
9610         return 0
9611 }
9612 run_test 118j "Simulate unrecoverable OST side error =========="
9613
9614 test_118k()
9615 {
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617         remote_ost_nodsh && skip "remote OSTs with nodsh"
9618
9619         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9620         set_nodes_failloc "$(osts_nodes)" 0x20e
9621         test_mkdir $DIR/$tdir
9622
9623         for ((i=0;i<10;i++)); do
9624                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9625                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9626                 SLEEPPID=$!
9627                 sleep 0.500s
9628                 kill $SLEEPPID
9629                 wait $SLEEPPID
9630         done
9631
9632         set_nodes_failloc "$(osts_nodes)" 0
9633         rm -rf $DIR/$tdir
9634 }
9635 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9636
9637 test_118l() # LU-646
9638 {
9639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9640
9641         test_mkdir $DIR/$tdir
9642         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9643         rm -rf $DIR/$tdir
9644 }
9645 run_test 118l "fsync dir"
9646
9647 test_118m() # LU-3066
9648 {
9649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9650
9651         test_mkdir $DIR/$tdir
9652         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9653         rm -rf $DIR/$tdir
9654 }
9655 run_test 118m "fdatasync dir ========="
9656
9657 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9658
9659 test_118n()
9660 {
9661         local begin
9662         local end
9663
9664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9665         remote_ost_nodsh && skip "remote OSTs with nodsh"
9666
9667         # Sleep to avoid a cached response.
9668         #define OBD_STATFS_CACHE_SECONDS 1
9669         sleep 2
9670
9671         # Inject a 10 second delay in the OST_STATFS handler.
9672         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9673         set_nodes_failloc "$(osts_nodes)" 0x242
9674
9675         begin=$SECONDS
9676         stat --file-system $MOUNT > /dev/null
9677         end=$SECONDS
9678
9679         set_nodes_failloc "$(osts_nodes)" 0
9680
9681         if ((end - begin > 20)); then
9682             error "statfs took $((end - begin)) seconds, expected 10"
9683         fi
9684 }
9685 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9686
9687 test_119a() # bug 11737
9688 {
9689         BSIZE=$((512 * 1024))
9690         directio write $DIR/$tfile 0 1 $BSIZE
9691         # We ask to read two blocks, which is more than a file size.
9692         # directio will indicate an error when requested and actual
9693         # sizes aren't equeal (a normal situation in this case) and
9694         # print actual read amount.
9695         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9696         if [ "$NOB" != "$BSIZE" ]; then
9697                 error "read $NOB bytes instead of $BSIZE"
9698         fi
9699         rm -f $DIR/$tfile
9700 }
9701 run_test 119a "Short directIO read must return actual read amount"
9702
9703 test_119b() # bug 11737
9704 {
9705         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9706
9707         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9708         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9709         sync
9710         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9711                 error "direct read failed"
9712         rm -f $DIR/$tfile
9713 }
9714 run_test 119b "Sparse directIO read must return actual read amount"
9715
9716 test_119c() # bug 13099
9717 {
9718         BSIZE=1048576
9719         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9720         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9721         rm -f $DIR/$tfile
9722 }
9723 run_test 119c "Testing for direct read hitting hole"
9724
9725 test_119d() # bug 15950
9726 {
9727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9728
9729         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9730         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9731         BSIZE=1048576
9732         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9733         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9734         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9735         lctl set_param fail_loc=0x40d
9736         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9737         pid_dio=$!
9738         sleep 1
9739         cat $DIR/$tfile > /dev/null &
9740         lctl set_param fail_loc=0
9741         pid_reads=$!
9742         wait $pid_dio
9743         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9744         sleep 2
9745         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9746         error "the read rpcs have not completed in 2s"
9747         rm -f $DIR/$tfile
9748         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9749 }
9750 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9751
9752 test_120a() {
9753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9754         remote_mds_nodsh && skip "remote MDS with nodsh"
9755         test_mkdir -i0 -c1 $DIR/$tdir
9756         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9757                 skip_env "no early lock cancel on server"
9758
9759         lru_resize_disable mdc
9760         lru_resize_disable osc
9761         cancel_lru_locks mdc
9762         # asynchronous object destroy at MDT could cause bl ast to client
9763         cancel_lru_locks osc
9764
9765         stat $DIR/$tdir > /dev/null
9766         can1=$(do_facet mds1 \
9767                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9768                awk '/ldlm_cancel/ {print $2}')
9769         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9770                awk '/ldlm_bl_callback/ {print $2}')
9771         test_mkdir -i0 -c1 $DIR/$tdir/d1
9772         can2=$(do_facet mds1 \
9773                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9774                awk '/ldlm_cancel/ {print $2}')
9775         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9776                awk '/ldlm_bl_callback/ {print $2}')
9777         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9778         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9779         lru_resize_enable mdc
9780         lru_resize_enable osc
9781 }
9782 run_test 120a "Early Lock Cancel: mkdir test"
9783
9784 test_120b() {
9785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9786         remote_mds_nodsh && skip "remote MDS with nodsh"
9787         test_mkdir $DIR/$tdir
9788         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9789                 skip_env "no early lock cancel on server"
9790
9791         lru_resize_disable mdc
9792         lru_resize_disable osc
9793         cancel_lru_locks mdc
9794         stat $DIR/$tdir > /dev/null
9795         can1=$(do_facet $SINGLEMDS \
9796                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9797                awk '/ldlm_cancel/ {print $2}')
9798         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9799                awk '/ldlm_bl_callback/ {print $2}')
9800         touch $DIR/$tdir/f1
9801         can2=$(do_facet $SINGLEMDS \
9802                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9803                awk '/ldlm_cancel/ {print $2}')
9804         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9805                awk '/ldlm_bl_callback/ {print $2}')
9806         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9807         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9808         lru_resize_enable mdc
9809         lru_resize_enable osc
9810 }
9811 run_test 120b "Early Lock Cancel: create test"
9812
9813 test_120c() {
9814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9815         remote_mds_nodsh && skip "remote MDS with nodsh"
9816         test_mkdir -i0 -c1 $DIR/$tdir
9817         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9818                 skip "no early lock cancel on server"
9819
9820         lru_resize_disable mdc
9821         lru_resize_disable osc
9822         test_mkdir -i0 -c1 $DIR/$tdir/d1
9823         test_mkdir -i0 -c1 $DIR/$tdir/d2
9824         touch $DIR/$tdir/d1/f1
9825         cancel_lru_locks mdc
9826         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9827         can1=$(do_facet mds1 \
9828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9829                awk '/ldlm_cancel/ {print $2}')
9830         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9831                awk '/ldlm_bl_callback/ {print $2}')
9832         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9833         can2=$(do_facet mds1 \
9834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9835                awk '/ldlm_cancel/ {print $2}')
9836         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9837                awk '/ldlm_bl_callback/ {print $2}')
9838         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9839         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9840         lru_resize_enable mdc
9841         lru_resize_enable osc
9842 }
9843 run_test 120c "Early Lock Cancel: link test"
9844
9845 test_120d() {
9846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9847         remote_mds_nodsh && skip "remote MDS with nodsh"
9848         test_mkdir -i0 -c1 $DIR/$tdir
9849         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9850                 skip_env "no early lock cancel on server"
9851
9852         lru_resize_disable mdc
9853         lru_resize_disable osc
9854         touch $DIR/$tdir
9855         cancel_lru_locks mdc
9856         stat $DIR/$tdir > /dev/null
9857         can1=$(do_facet mds1 \
9858                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9859                awk '/ldlm_cancel/ {print $2}')
9860         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9861                awk '/ldlm_bl_callback/ {print $2}')
9862         chmod a+x $DIR/$tdir
9863         can2=$(do_facet mds1 \
9864                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9865                awk '/ldlm_cancel/ {print $2}')
9866         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9867                awk '/ldlm_bl_callback/ {print $2}')
9868         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9869         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9870         lru_resize_enable mdc
9871         lru_resize_enable osc
9872 }
9873 run_test 120d "Early Lock Cancel: setattr test"
9874
9875 test_120e() {
9876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9877         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9878                 skip_env "no early lock cancel on server"
9879         remote_mds_nodsh && skip "remote MDS with nodsh"
9880
9881         local dlmtrace_set=false
9882
9883         test_mkdir -i0 -c1 $DIR/$tdir
9884         lru_resize_disable mdc
9885         lru_resize_disable osc
9886         ! $LCTL get_param debug | grep -q dlmtrace &&
9887                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9888         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9889         cancel_lru_locks mdc
9890         cancel_lru_locks osc
9891         dd if=$DIR/$tdir/f1 of=/dev/null
9892         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9893         # XXX client can not do early lock cancel of OST lock
9894         # during unlink (LU-4206), so cancel osc lock now.
9895         sleep 2
9896         cancel_lru_locks osc
9897         can1=$(do_facet mds1 \
9898                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9899                awk '/ldlm_cancel/ {print $2}')
9900         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9901                awk '/ldlm_bl_callback/ {print $2}')
9902         unlink $DIR/$tdir/f1
9903         sleep 5
9904         can2=$(do_facet mds1 \
9905                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9906                awk '/ldlm_cancel/ {print $2}')
9907         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9908                awk '/ldlm_bl_callback/ {print $2}')
9909         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9910                 $LCTL dk $TMP/cancel.debug.txt
9911         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9912                 $LCTL dk $TMP/blocking.debug.txt
9913         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9914         lru_resize_enable mdc
9915         lru_resize_enable osc
9916 }
9917 run_test 120e "Early Lock Cancel: unlink test"
9918
9919 test_120f() {
9920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9921         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9922                 skip_env "no early lock cancel on server"
9923         remote_mds_nodsh && skip "remote MDS with nodsh"
9924
9925         test_mkdir -i0 -c1 $DIR/$tdir
9926         lru_resize_disable mdc
9927         lru_resize_disable osc
9928         test_mkdir -i0 -c1 $DIR/$tdir/d1
9929         test_mkdir -i0 -c1 $DIR/$tdir/d2
9930         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9931         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9932         cancel_lru_locks mdc
9933         cancel_lru_locks osc
9934         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9935         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9936         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9937         # XXX client can not do early lock cancel of OST lock
9938         # during rename (LU-4206), so cancel osc lock now.
9939         sleep 2
9940         cancel_lru_locks osc
9941         can1=$(do_facet mds1 \
9942                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9943                awk '/ldlm_cancel/ {print $2}')
9944         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9945                awk '/ldlm_bl_callback/ {print $2}')
9946         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9947         sleep 5
9948         can2=$(do_facet mds1 \
9949                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9950                awk '/ldlm_cancel/ {print $2}')
9951         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9952                awk '/ldlm_bl_callback/ {print $2}')
9953         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9954         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9955         lru_resize_enable mdc
9956         lru_resize_enable osc
9957 }
9958 run_test 120f "Early Lock Cancel: rename test"
9959
9960 test_120g() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9963                 skip_env "no early lock cancel on server"
9964         remote_mds_nodsh && skip "remote MDS with nodsh"
9965
9966         lru_resize_disable mdc
9967         lru_resize_disable osc
9968         count=10000
9969         echo create $count files
9970         test_mkdir $DIR/$tdir
9971         cancel_lru_locks mdc
9972         cancel_lru_locks osc
9973         t0=$(date +%s)
9974
9975         can0=$(do_facet $SINGLEMDS \
9976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9977                awk '/ldlm_cancel/ {print $2}')
9978         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9979                awk '/ldlm_bl_callback/ {print $2}')
9980         createmany -o $DIR/$tdir/f $count
9981         sync
9982         can1=$(do_facet $SINGLEMDS \
9983                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9984                awk '/ldlm_cancel/ {print $2}')
9985         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9986                awk '/ldlm_bl_callback/ {print $2}')
9987         t1=$(date +%s)
9988         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
9989         echo rm $count files
9990         rm -r $DIR/$tdir
9991         sync
9992         can2=$(do_facet $SINGLEMDS \
9993                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9994                awk '/ldlm_cancel/ {print $2}')
9995         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9996                awk '/ldlm_bl_callback/ {print $2}')
9997         t2=$(date +%s)
9998         echo total: $count removes in $((t2-t1))
9999         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10000         sleep 2
10001         # wait for commitment of removal
10002         lru_resize_enable mdc
10003         lru_resize_enable osc
10004 }
10005 run_test 120g "Early Lock Cancel: performance test"
10006
10007 test_121() { #bug #10589
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009
10010         rm -rf $DIR/$tfile
10011         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10012 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10013         lctl set_param fail_loc=0x310
10014         cancel_lru_locks osc > /dev/null
10015         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10016         lctl set_param fail_loc=0
10017         [[ $reads -eq $writes ]] ||
10018                 error "read $reads blocks, must be $writes blocks"
10019 }
10020 run_test 121 "read cancel race ========="
10021
10022 test_123a() { # was test 123, statahead(bug 11401)
10023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10024
10025         SLOWOK=0
10026         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10027                 log "testing UP system. Performance may be lower than expected."
10028                 SLOWOK=1
10029         fi
10030
10031         rm -rf $DIR/$tdir
10032         test_mkdir $DIR/$tdir
10033         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10034         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10035         MULT=10
10036         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10037                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10038
10039                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10040                 lctl set_param -n llite.*.statahead_max 0
10041                 lctl get_param llite.*.statahead_max
10042                 cancel_lru_locks mdc
10043                 cancel_lru_locks osc
10044                 stime=`date +%s`
10045                 time ls -l $DIR/$tdir | wc -l
10046                 etime=`date +%s`
10047                 delta=$((etime - stime))
10048                 log "ls $i files without statahead: $delta sec"
10049                 lctl set_param llite.*.statahead_max=$max
10050
10051                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10052                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10053                 cancel_lru_locks mdc
10054                 cancel_lru_locks osc
10055                 stime=`date +%s`
10056                 time ls -l $DIR/$tdir | wc -l
10057                 etime=`date +%s`
10058                 delta_sa=$((etime - stime))
10059                 log "ls $i files with statahead: $delta_sa sec"
10060                 lctl get_param -n llite.*.statahead_stats
10061                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10062
10063                 [[ $swrong -lt $ewrong ]] &&
10064                         log "statahead was stopped, maybe too many locks held!"
10065                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10066
10067                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10068                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10069                     lctl set_param -n llite.*.statahead_max 0
10070                     lctl get_param llite.*.statahead_max
10071                     cancel_lru_locks mdc
10072                     cancel_lru_locks osc
10073                     stime=`date +%s`
10074                     time ls -l $DIR/$tdir | wc -l
10075                     etime=`date +%s`
10076                     delta=$((etime - stime))
10077                     log "ls $i files again without statahead: $delta sec"
10078                     lctl set_param llite.*.statahead_max=$max
10079                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10080                         if [  $SLOWOK -eq 0 ]; then
10081                                 error "ls $i files is slower with statahead!"
10082                         else
10083                                 log "ls $i files is slower with statahead!"
10084                         fi
10085                         break
10086                     fi
10087                 fi
10088
10089                 [ $delta -gt 20 ] && break
10090                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10091                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10092         done
10093         log "ls done"
10094
10095         stime=`date +%s`
10096         rm -r $DIR/$tdir
10097         sync
10098         etime=`date +%s`
10099         delta=$((etime - stime))
10100         log "rm -r $DIR/$tdir/: $delta seconds"
10101         log "rm done"
10102         lctl get_param -n llite.*.statahead_stats
10103 }
10104 run_test 123a "verify statahead work"
10105
10106 test_123b () { # statahead(bug 15027)
10107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10108
10109         test_mkdir $DIR/$tdir
10110         createmany -o $DIR/$tdir/$tfile-%d 1000
10111
10112         cancel_lru_locks mdc
10113         cancel_lru_locks osc
10114
10115 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10116         lctl set_param fail_loc=0x80000803
10117         ls -lR $DIR/$tdir > /dev/null
10118         log "ls done"
10119         lctl set_param fail_loc=0x0
10120         lctl get_param -n llite.*.statahead_stats
10121         rm -r $DIR/$tdir
10122         sync
10123
10124 }
10125 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10126
10127 test_124a() {
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10130                 skip_env "no lru resize on server"
10131
10132         local NR=2000
10133
10134         test_mkdir $DIR/$tdir
10135
10136         log "create $NR files at $DIR/$tdir"
10137         createmany -o $DIR/$tdir/f $NR ||
10138                 error "failed to create $NR files in $DIR/$tdir"
10139
10140         cancel_lru_locks mdc
10141         ls -l $DIR/$tdir > /dev/null
10142
10143         local NSDIR=""
10144         local LRU_SIZE=0
10145         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10146                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10147                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10148                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10149                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10150                         log "NSDIR=$NSDIR"
10151                         log "NS=$(basename $NSDIR)"
10152                         break
10153                 fi
10154         done
10155
10156         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10157                 skip "Not enough cached locks created!"
10158         fi
10159         log "LRU=$LRU_SIZE"
10160
10161         local SLEEP=30
10162
10163         # We know that lru resize allows one client to hold $LIMIT locks
10164         # for 10h. After that locks begin to be killed by client.
10165         local MAX_HRS=10
10166         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10167         log "LIMIT=$LIMIT"
10168         if [ $LIMIT -lt $LRU_SIZE ]; then
10169                 skip "Limit is too small $LIMIT"
10170         fi
10171
10172         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10173         # killing locks. Some time was spent for creating locks. This means
10174         # that up to the moment of sleep finish we must have killed some of
10175         # them (10-100 locks). This depends on how fast ther were created.
10176         # Many of them were touched in almost the same moment and thus will
10177         # be killed in groups.
10178         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10179
10180         # Use $LRU_SIZE_B here to take into account real number of locks
10181         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10182         local LRU_SIZE_B=$LRU_SIZE
10183         log "LVF=$LVF"
10184         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10185         log "OLD_LVF=$OLD_LVF"
10186         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10187
10188         # Let's make sure that we really have some margin. Client checks
10189         # cached locks every 10 sec.
10190         SLEEP=$((SLEEP+20))
10191         log "Sleep ${SLEEP} sec"
10192         local SEC=0
10193         while ((SEC<$SLEEP)); do
10194                 echo -n "..."
10195                 sleep 5
10196                 SEC=$((SEC+5))
10197                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10198                 echo -n "$LRU_SIZE"
10199         done
10200         echo ""
10201         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10202         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10203
10204         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10205                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10206                 unlinkmany $DIR/$tdir/f $NR
10207                 return
10208         }
10209
10210         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10211         log "unlink $NR files at $DIR/$tdir"
10212         unlinkmany $DIR/$tdir/f $NR
10213 }
10214 run_test 124a "lru resize ======================================="
10215
10216 get_max_pool_limit()
10217 {
10218         local limit=$($LCTL get_param \
10219                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10220         local max=0
10221         for l in $limit; do
10222                 if [[ $l -gt $max ]]; then
10223                         max=$l
10224                 fi
10225         done
10226         echo $max
10227 }
10228
10229 test_124b() {
10230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10231         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10232                 skip_env "no lru resize on server"
10233
10234         LIMIT=$(get_max_pool_limit)
10235
10236         NR=$(($(default_lru_size)*20))
10237         if [[ $NR -gt $LIMIT ]]; then
10238                 log "Limit lock number by $LIMIT locks"
10239                 NR=$LIMIT
10240         fi
10241
10242         IFree=$(mdsrate_inodes_available)
10243         if [ $IFree -lt $NR ]; then
10244                 log "Limit lock number by $IFree inodes"
10245                 NR=$IFree
10246         fi
10247
10248         lru_resize_disable mdc
10249         test_mkdir -p $DIR/$tdir/disable_lru_resize
10250
10251         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10252         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10253         cancel_lru_locks mdc
10254         stime=`date +%s`
10255         PID=""
10256         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10257         PID="$PID $!"
10258         sleep 2
10259         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10260         PID="$PID $!"
10261         sleep 2
10262         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10263         PID="$PID $!"
10264         wait $PID
10265         etime=`date +%s`
10266         nolruresize_delta=$((etime-stime))
10267         log "ls -la time: $nolruresize_delta seconds"
10268         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10269         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10270
10271         lru_resize_enable mdc
10272         test_mkdir -p $DIR/$tdir/enable_lru_resize
10273
10274         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10275         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10276         cancel_lru_locks mdc
10277         stime=`date +%s`
10278         PID=""
10279         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10280         PID="$PID $!"
10281         sleep 2
10282         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10283         PID="$PID $!"
10284         sleep 2
10285         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10286         PID="$PID $!"
10287         wait $PID
10288         etime=`date +%s`
10289         lruresize_delta=$((etime-stime))
10290         log "ls -la time: $lruresize_delta seconds"
10291         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10292
10293         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10294                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10295         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10296                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10297         else
10298                 log "lru resize performs the same with no lru resize"
10299         fi
10300         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10301 }
10302 run_test 124b "lru resize (performance test) ======================="
10303
10304 test_124c() {
10305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10306         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10307                 skip_env "no lru resize on server"
10308
10309         # cache ununsed locks on client
10310         local nr=100
10311         cancel_lru_locks mdc
10312         test_mkdir $DIR/$tdir
10313         createmany -o $DIR/$tdir/f $nr ||
10314                 error "failed to create $nr files in $DIR/$tdir"
10315         ls -l $DIR/$tdir > /dev/null
10316
10317         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10318         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10319         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10320         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10321         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10322
10323         # set lru_max_age to 1 sec
10324         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10325         echo "sleep $((recalc_p * 2)) seconds..."
10326         sleep $((recalc_p * 2))
10327
10328         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10329         # restore lru_max_age
10330         $LCTL set_param -n $nsdir.lru_max_age $max_age
10331         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10332         unlinkmany $DIR/$tdir/f $nr
10333 }
10334 run_test 124c "LRUR cancel very aged locks"
10335
10336 test_125() { # 13358
10337         $LCTL get_param -n llite.*.client_type | grep -q local ||
10338                 skip "must run as local client"
10339         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10340                 skip_env "must have acl enabled"
10341         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10342
10343         test_mkdir $DIR/$tdir
10344         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10345         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10346         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10347 }
10348 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10349
10350 test_126() { # bug 12829/13455
10351         $GSS && skip_env "must run as gss disabled"
10352         $LCTL get_param -n llite.*.client_type | grep -q local ||
10353                 skip "must run as local client"
10354         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10355
10356         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10357         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10358         rm -f $DIR/$tfile
10359         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10360 }
10361 run_test 126 "check that the fsgid provided by the client is taken into account"
10362
10363 test_127a() { # bug 15521
10364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10365
10366         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10367         $LCTL set_param osc.*.stats=0
10368         FSIZE=$((2048 * 1024))
10369         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10370         cancel_lru_locks osc
10371         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10372
10373         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10374         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10375                 echo "got $COUNT $NAME"
10376                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10377                 eval $NAME=$COUNT || error "Wrong proc format"
10378
10379                 case $NAME in
10380                         read_bytes|write_bytes)
10381                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10382                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10383                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10384                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10385                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10386                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10387                                 error "sumsquare is too small: $SUMSQ"
10388                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10389                                 error "sumsquare is too big: $SUMSQ"
10390                         ;;
10391                         *) ;;
10392                 esac
10393         done < $DIR/${tfile}.tmp
10394
10395         #check that we actually got some stats
10396         [ "$read_bytes" ] || error "Missing read_bytes stats"
10397         [ "$write_bytes" ] || error "Missing write_bytes stats"
10398         [ "$read_bytes" != 0 ] || error "no read done"
10399         [ "$write_bytes" != 0 ] || error "no write done"
10400 }
10401 run_test 127a "verify the client stats are sane"
10402
10403 test_127b() { # bug LU-333
10404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10405         local name count samp unit min max sum sumsq
10406
10407         $LCTL set_param llite.*.stats=0
10408
10409         # perform 2 reads and writes so MAX is different from SUM.
10410         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10411         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10412         cancel_lru_locks osc
10413         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10414         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10415
10416         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10417         while read name count samp unit min max sum sumsq; do
10418                 echo "got $count $name"
10419                 eval $name=$count || error "Wrong proc format"
10420
10421                 case $name in
10422                 read_bytes)
10423                         [ $count -ne 2 ] && error "count is not 2: $count"
10424                         [ $min -ne $PAGE_SIZE ] &&
10425                                 error "min is not $PAGE_SIZE: $min"
10426                         [ $max -ne $PAGE_SIZE ] &&
10427                                 error "max is incorrect: $max"
10428                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10429                                 error "sum is wrong: $sum"
10430                         ;;
10431                 write_bytes)
10432                         [ $count -ne 2 ] && error "count is not 2: $count"
10433                         [ $min -ne $PAGE_SIZE ] &&
10434                                 error "min is not $PAGE_SIZE: $min"
10435                         [ $max -ne $PAGE_SIZE ] &&
10436                                 error "max is incorrect: $max"
10437                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10438                                 error "sum is wrong: $sum"
10439                         ;;
10440                 *) ;;
10441                 esac
10442         done < $TMP/$tfile.tmp
10443
10444         #check that we actually got some stats
10445         [ "$read_bytes" ] || error "Missing read_bytes stats"
10446         [ "$write_bytes" ] || error "Missing write_bytes stats"
10447         [ "$read_bytes" != 0 ] || error "no read done"
10448         [ "$write_bytes" != 0 ] || error "no write done"
10449
10450         rm -f $TMP/${tfile}.tmp
10451 }
10452 run_test 127b "verify the llite client stats are sane"
10453
10454 test_128() { # bug 15212
10455         touch $DIR/$tfile
10456         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10457                 find $DIR/$tfile
10458                 find $DIR/$tfile
10459         EOF
10460
10461         result=$(grep error $TMP/$tfile.log)
10462         rm -f $DIR/$tfile $TMP/$tfile.log
10463         [ -z "$result" ] ||
10464                 error "consecutive find's under interactive lfs failed"
10465 }
10466 run_test 128 "interactive lfs for 2 consecutive find's"
10467
10468 set_dir_limits () {
10469         local mntdev
10470         local canondev
10471         local node
10472
10473         local ldproc=/proc/fs/ldiskfs
10474         local facets=$(get_facets MDS)
10475
10476         for facet in ${facets//,/ }; do
10477                 canondev=$(ldiskfs_canon \
10478                            *.$(convert_facet2label $facet).mntdev $facet)
10479                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10480                         ldproc=/sys/fs/ldiskfs
10481                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10482                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10483         done
10484 }
10485
10486 check_mds_dmesg() {
10487         local facets=$(get_facets MDS)
10488         for facet in ${facets//,/ }; do
10489                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10490         done
10491         return 1
10492 }
10493
10494 test_129() {
10495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10496         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10497                 skip "Need MDS version with at least 2.5.56"
10498         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10499                 skip_env "ldiskfs only test"
10500         fi
10501         remote_mds_nodsh && skip "remote MDS with nodsh"
10502
10503         local ENOSPC=28
10504         local EFBIG=27
10505         local has_warning=false
10506
10507         rm -rf $DIR/$tdir
10508         mkdir -p $DIR/$tdir
10509
10510         # block size of mds1
10511         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10512         set_dir_limits $maxsize $maxsize
10513         local dirsize=$(stat -c%s "$DIR/$tdir")
10514         local nfiles=0
10515         while [[ $dirsize -le $maxsize ]]; do
10516                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10517                 rc=$?
10518                 if ! $has_warning; then
10519                         check_mds_dmesg '"is approaching"' && has_warning=true
10520                 fi
10521                 # check two errors:
10522                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10523                 # EFBIG for previous versions included in ldiskfs series
10524                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
10525                         set_dir_limits 0 0
10526                         echo "return code $rc received as expected"
10527
10528                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10529                                 error_exit "create failed w/o dir size limit"
10530
10531                         check_mds_dmesg '"has reached"' ||
10532                                 error_exit "reached message should be output"
10533
10534                         [ $has_warning = "false" ] &&
10535                                 error_exit "warning message should be output"
10536
10537                         dirsize=$(stat -c%s "$DIR/$tdir")
10538
10539                         [[ $dirsize -ge $maxsize ]] && return 0
10540                         error_exit "current dir size $dirsize, " \
10541                                    "previous limit $maxsize"
10542                 elif [ $rc -ne 0 ]; then
10543                         set_dir_limits 0 0
10544                         error_exit "return $rc received instead of expected " \
10545                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10546                 fi
10547                 nfiles=$((nfiles + 1))
10548                 dirsize=$(stat -c%s "$DIR/$tdir")
10549         done
10550
10551         set_dir_limits 0 0
10552         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10553 }
10554 run_test 129 "test directory size limit ========================"
10555
10556 OLDIFS="$IFS"
10557 cleanup_130() {
10558         trap 0
10559         IFS="$OLDIFS"
10560 }
10561
10562 test_130a() {
10563         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10564         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10565
10566         trap cleanup_130 EXIT RETURN
10567
10568         local fm_file=$DIR/$tfile
10569         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10570         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10571                 error "dd failed for $fm_file"
10572
10573         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10574         filefrag -ves $fm_file
10575         RC=$?
10576         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10577                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10578         [ $RC != 0 ] && error "filefrag $fm_file failed"
10579
10580         filefrag_op=$(filefrag -ve -k $fm_file |
10581                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10582         lun=$($LFS getstripe -i $fm_file)
10583
10584         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10585         IFS=$'\n'
10586         tot_len=0
10587         for line in $filefrag_op
10588         do
10589                 frag_lun=`echo $line | cut -d: -f5`
10590                 ext_len=`echo $line | cut -d: -f4`
10591                 if (( $frag_lun != $lun )); then
10592                         cleanup_130
10593                         error "FIEMAP on 1-stripe file($fm_file) failed"
10594                         return
10595                 fi
10596                 (( tot_len += ext_len ))
10597         done
10598
10599         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10600                 cleanup_130
10601                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10602                 return
10603         fi
10604
10605         cleanup_130
10606
10607         echo "FIEMAP on single striped file succeeded"
10608 }
10609 run_test 130a "FIEMAP (1-stripe file)"
10610
10611 test_130b() {
10612         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10613
10614         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10615         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10616
10617         trap cleanup_130 EXIT RETURN
10618
10619         local fm_file=$DIR/$tfile
10620         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10621                         error "setstripe on $fm_file"
10622         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10623                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10624
10625         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10626                 error "dd failed on $fm_file"
10627
10628         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10629         filefrag_op=$(filefrag -ve -k $fm_file |
10630                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10631
10632         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10633                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10634
10635         IFS=$'\n'
10636         tot_len=0
10637         num_luns=1
10638         for line in $filefrag_op
10639         do
10640                 frag_lun=$(echo $line | cut -d: -f5 |
10641                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10642                 ext_len=$(echo $line | cut -d: -f4)
10643                 if (( $frag_lun != $last_lun )); then
10644                         if (( tot_len != 1024 )); then
10645                                 cleanup_130
10646                                 error "FIEMAP on $fm_file failed; returned " \
10647                                 "len $tot_len for OST $last_lun instead of 1024"
10648                                 return
10649                         else
10650                                 (( num_luns += 1 ))
10651                                 tot_len=0
10652                         fi
10653                 fi
10654                 (( tot_len += ext_len ))
10655                 last_lun=$frag_lun
10656         done
10657         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10658                 cleanup_130
10659                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10660                         "luns or wrong len for OST $last_lun"
10661                 return
10662         fi
10663
10664         cleanup_130
10665
10666         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10667 }
10668 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10669
10670 test_130c() {
10671         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10672
10673         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10674         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10675
10676         trap cleanup_130 EXIT RETURN
10677
10678         local fm_file=$DIR/$tfile
10679         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10680         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10681                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10682
10683         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10684                         error "dd failed on $fm_file"
10685
10686         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10687         filefrag_op=$(filefrag -ve -k $fm_file |
10688                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10689
10690         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10691                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10692
10693         IFS=$'\n'
10694         tot_len=0
10695         num_luns=1
10696         for line in $filefrag_op
10697         do
10698                 frag_lun=$(echo $line | cut -d: -f5 |
10699                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10700                 ext_len=$(echo $line | cut -d: -f4)
10701                 if (( $frag_lun != $last_lun )); then
10702                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10703                         if (( logical != 512 )); then
10704                                 cleanup_130
10705                                 error "FIEMAP on $fm_file failed; returned " \
10706                                 "logical start for lun $logical instead of 512"
10707                                 return
10708                         fi
10709                         if (( tot_len != 512 )); then
10710                                 cleanup_130
10711                                 error "FIEMAP on $fm_file failed; returned " \
10712                                 "len $tot_len for OST $last_lun instead of 1024"
10713                                 return
10714                         else
10715                                 (( num_luns += 1 ))
10716                                 tot_len=0
10717                         fi
10718                 fi
10719                 (( tot_len += ext_len ))
10720                 last_lun=$frag_lun
10721         done
10722         if (( num_luns != 2 || tot_len != 512 )); then
10723                 cleanup_130
10724                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10725                         "luns or wrong len for OST $last_lun"
10726                 return
10727         fi
10728
10729         cleanup_130
10730
10731         echo "FIEMAP on 2-stripe file with hole succeeded"
10732 }
10733 run_test 130c "FIEMAP (2-stripe file with hole)"
10734
10735 test_130d() {
10736         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10737
10738         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10739         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10740
10741         trap cleanup_130 EXIT RETURN
10742
10743         local fm_file=$DIR/$tfile
10744         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10745                         error "setstripe on $fm_file"
10746         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10747                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10748
10749         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10750         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10751                 error "dd failed on $fm_file"
10752
10753         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10754         filefrag_op=$(filefrag -ve -k $fm_file |
10755                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10756
10757         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10758                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10759
10760         IFS=$'\n'
10761         tot_len=0
10762         num_luns=1
10763         for line in $filefrag_op
10764         do
10765                 frag_lun=$(echo $line | cut -d: -f5 |
10766                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10767                 ext_len=$(echo $line | cut -d: -f4)
10768                 if (( $frag_lun != $last_lun )); then
10769                         if (( tot_len != 1024 )); then
10770                                 cleanup_130
10771                                 error "FIEMAP on $fm_file failed; returned " \
10772                                 "len $tot_len for OST $last_lun instead of 1024"
10773                                 return
10774                         else
10775                                 (( num_luns += 1 ))
10776                                 tot_len=0
10777                         fi
10778                 fi
10779                 (( tot_len += ext_len ))
10780                 last_lun=$frag_lun
10781         done
10782         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10783                 cleanup_130
10784                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10785                         "luns or wrong len for OST $last_lun"
10786                 return
10787         fi
10788
10789         cleanup_130
10790
10791         echo "FIEMAP on N-stripe file succeeded"
10792 }
10793 run_test 130d "FIEMAP (N-stripe file)"
10794
10795 test_130e() {
10796         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10797
10798         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10799         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10800
10801         trap cleanup_130 EXIT RETURN
10802
10803         local fm_file=$DIR/$tfile
10804         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10805         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10806                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10807
10808         NUM_BLKS=512
10809         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10810         for ((i = 0; i < $NUM_BLKS; i++))
10811         do
10812                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10813         done
10814
10815         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10816         filefrag_op=$(filefrag -ve -k $fm_file |
10817                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10818
10819         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10820                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10821
10822         IFS=$'\n'
10823         tot_len=0
10824         num_luns=1
10825         for line in $filefrag_op
10826         do
10827                 frag_lun=$(echo $line | cut -d: -f5 |
10828                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10829                 ext_len=$(echo $line | cut -d: -f4)
10830                 if (( $frag_lun != $last_lun )); then
10831                         if (( tot_len != $EXPECTED_LEN )); then
10832                                 cleanup_130
10833                                 error "FIEMAP on $fm_file failed; returned " \
10834                                 "len $tot_len for OST $last_lun instead " \
10835                                 "of $EXPECTED_LEN"
10836                                 return
10837                         else
10838                                 (( num_luns += 1 ))
10839                                 tot_len=0
10840                         fi
10841                 fi
10842                 (( tot_len += ext_len ))
10843                 last_lun=$frag_lun
10844         done
10845         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10846                 cleanup_130
10847                 error "FIEMAP on $fm_file failed; returned wrong number " \
10848                         "of luns or wrong len for OST $last_lun"
10849                 return
10850         fi
10851
10852         cleanup_130
10853
10854         echo "FIEMAP with continuation calls succeeded"
10855 }
10856 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10857
10858 test_130f() {
10859         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10860         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10861
10862         local fm_file=$DIR/$tfile
10863         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10864                 error "multiop create with lov_delay_create on $fm_file"
10865
10866         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10867         filefrag_extents=$(filefrag -vek $fm_file |
10868                            awk '/extents? found/ { print $2 }')
10869         if [[ "$filefrag_extents" != "0" ]]; then
10870                 error "FIEMAP on $fm_file failed; " \
10871                       "returned $filefrag_extents expected 0"
10872         fi
10873
10874         rm -f $fm_file
10875 }
10876 run_test 130f "FIEMAP (unstriped file)"
10877
10878 # Test for writev/readv
10879 test_131a() {
10880         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10881                 error "writev test failed"
10882         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10883                 error "readv failed"
10884         rm -f $DIR/$tfile
10885 }
10886 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10887
10888 test_131b() {
10889         local fsize=$((524288 + 1048576 + 1572864))
10890         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10891                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10892                         error "append writev test failed"
10893
10894         ((fsize += 1572864 + 1048576))
10895         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10896                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10897                         error "append writev test failed"
10898         rm -f $DIR/$tfile
10899 }
10900 run_test 131b "test append writev"
10901
10902 test_131c() {
10903         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10904         error "NOT PASS"
10905 }
10906 run_test 131c "test read/write on file w/o objects"
10907
10908 test_131d() {
10909         rwv -f $DIR/$tfile -w -n 1 1572864
10910         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10911         if [ "$NOB" != 1572864 ]; then
10912                 error "Short read filed: read $NOB bytes instead of 1572864"
10913         fi
10914         rm -f $DIR/$tfile
10915 }
10916 run_test 131d "test short read"
10917
10918 test_131e() {
10919         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10920         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10921         error "read hitting hole failed"
10922         rm -f $DIR/$tfile
10923 }
10924 run_test 131e "test read hitting hole"
10925
10926 check_stats() {
10927         local facet=$1
10928         local op=$2
10929         local want=${3:-0}
10930         local res
10931
10932         case $facet in
10933         mds*) res=$(do_facet $facet \
10934                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10935                  ;;
10936         ost*) res=$(do_facet $facet \
10937                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10938                  ;;
10939         *) error "Wrong facet '$facet'" ;;
10940         esac
10941         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10942         # if the argument $3 is zero, it means any stat increment is ok.
10943         if [[ $want -gt 0 ]]; then
10944                 local count=$(echo $res | awk '{ print $2 }')
10945                 [[ $count -ne $want ]] &&
10946                         error "The $op counter on $facet is $count, not $want"
10947         fi
10948 }
10949
10950 test_133a() {
10951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10952         remote_ost_nodsh && skip "remote OST with nodsh"
10953         remote_mds_nodsh && skip "remote MDS with nodsh"
10954         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10955                 skip_env "MDS doesn't support rename stats"
10956
10957         local testdir=$DIR/${tdir}/stats_testdir
10958
10959         mkdir -p $DIR/${tdir}
10960
10961         # clear stats.
10962         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10963         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10964
10965         # verify mdt stats first.
10966         mkdir ${testdir} || error "mkdir failed"
10967         check_stats $SINGLEMDS "mkdir" 1
10968         touch ${testdir}/${tfile} || error "touch failed"
10969         check_stats $SINGLEMDS "open" 1
10970         check_stats $SINGLEMDS "close" 1
10971         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10972                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10973                 check_stats $SINGLEMDS "mknod" 2
10974         }
10975         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10976         check_stats $SINGLEMDS "unlink" 1
10977         rm -f ${testdir}/${tfile} || error "file remove failed"
10978         check_stats $SINGLEMDS "unlink" 2
10979
10980         # remove working dir and check mdt stats again.
10981         rmdir ${testdir} || error "rmdir failed"
10982         check_stats $SINGLEMDS "rmdir" 1
10983
10984         local testdir1=$DIR/${tdir}/stats_testdir1
10985         mkdir -p ${testdir}
10986         mkdir -p ${testdir1}
10987         touch ${testdir1}/test1
10988         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
10989         check_stats $SINGLEMDS "crossdir_rename" 1
10990
10991         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
10992         check_stats $SINGLEMDS "samedir_rename" 1
10993
10994         rm -rf $DIR/${tdir}
10995 }
10996 run_test 133a "Verifying MDT stats ========================================"
10997
10998 test_133b() {
10999         local res
11000
11001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11002         remote_ost_nodsh && skip "remote OST with nodsh"
11003         remote_mds_nodsh && skip "remote MDS with nodsh"
11004
11005         local testdir=$DIR/${tdir}/stats_testdir
11006
11007         mkdir -p ${testdir} || error "mkdir failed"
11008         touch ${testdir}/${tfile} || error "touch failed"
11009         cancel_lru_locks mdc
11010
11011         # clear stats.
11012         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11013         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11014
11015         # extra mdt stats verification.
11016         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11017         check_stats $SINGLEMDS "setattr" 1
11018         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11019         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11020         then            # LU-1740
11021                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11022                 check_stats $SINGLEMDS "getattr" 1
11023         fi
11024         rm -rf $DIR/${tdir}
11025
11026         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11027         # so the check below is not reliable
11028         [ $MDSCOUNT -eq 1 ] || return 0
11029
11030         # Sleep to avoid a cached response.
11031         #define OBD_STATFS_CACHE_SECONDS 1
11032         sleep 2
11033         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11034         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11035         $LFS df || error "lfs failed"
11036         check_stats $SINGLEMDS "statfs" 1
11037
11038         # check aggregated statfs (LU-10018)
11039         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11040                 return 0
11041         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11042                 return 0
11043         sleep 2
11044         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11045         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11046         df $DIR
11047         check_stats $SINGLEMDS "statfs" 1
11048
11049         # We want to check that the client didn't send OST_STATFS to
11050         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11051         # extra care is needed here.
11052         if remote_mds; then
11053                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11054                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11055
11056                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11057                 [ "$res" ] && error "OST got STATFS"
11058         fi
11059
11060         return 0
11061 }
11062 run_test 133b "Verifying extra MDT stats =================================="
11063
11064 test_133c() {
11065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11066         remote_ost_nodsh && skip "remote OST with nodsh"
11067         remote_mds_nodsh && skip "remote MDS with nodsh"
11068
11069         local testdir=$DIR/$tdir/stats_testdir
11070
11071         test_mkdir -p $testdir
11072
11073         # verify obdfilter stats.
11074         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11075         sync
11076         cancel_lru_locks osc
11077         wait_delete_completed
11078
11079         # clear stats.
11080         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11081         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11082
11083         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11084                 error "dd failed"
11085         sync
11086         cancel_lru_locks osc
11087         check_stats ost1 "write" 1
11088
11089         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11090         check_stats ost1 "read" 1
11091
11092         > $testdir/$tfile || error "truncate failed"
11093         check_stats ost1 "punch" 1
11094
11095         rm -f $testdir/$tfile || error "file remove failed"
11096         wait_delete_completed
11097         check_stats ost1 "destroy" 1
11098
11099         rm -rf $DIR/$tdir
11100 }
11101 run_test 133c "Verifying OST stats ========================================"
11102
11103 order_2() {
11104         local value=$1
11105         local orig=$value
11106         local order=1
11107
11108         while [ $value -ge 2 ]; do
11109                 order=$((order*2))
11110                 value=$((value/2))
11111         done
11112
11113         if [ $orig -gt $order ]; then
11114                 order=$((order*2))
11115         fi
11116         echo $order
11117 }
11118
11119 size_in_KMGT() {
11120     local value=$1
11121     local size=('K' 'M' 'G' 'T');
11122     local i=0
11123     local size_string=$value
11124
11125     while [ $value -ge 1024 ]; do
11126         if [ $i -gt 3 ]; then
11127             #T is the biggest unit we get here, if that is bigger,
11128             #just return XXXT
11129             size_string=${value}T
11130             break
11131         fi
11132         value=$((value >> 10))
11133         if [ $value -lt 1024 ]; then
11134             size_string=${value}${size[$i]}
11135             break
11136         fi
11137         i=$((i + 1))
11138     done
11139
11140     echo $size_string
11141 }
11142
11143 get_rename_size() {
11144         local size=$1
11145         local context=${2:-.}
11146         local sample=$(do_facet $SINGLEMDS $LCTL \
11147                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11148                 grep -A1 $context |
11149                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11150         echo $sample
11151 }
11152
11153 test_133d() {
11154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11155         remote_ost_nodsh && skip "remote OST with nodsh"
11156         remote_mds_nodsh && skip "remote MDS with nodsh"
11157         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11158                 skip_env "MDS doesn't support rename stats"
11159
11160         local testdir1=$DIR/${tdir}/stats_testdir1
11161         local testdir2=$DIR/${tdir}/stats_testdir2
11162         mkdir -p $DIR/${tdir}
11163
11164         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11165
11166         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11167         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11168
11169         createmany -o $testdir1/test 512 || error "createmany failed"
11170
11171         # check samedir rename size
11172         mv ${testdir1}/test0 ${testdir1}/test_0
11173
11174         local testdir1_size=$(ls -l $DIR/${tdir} |
11175                 awk '/stats_testdir1/ {print $5}')
11176         local testdir2_size=$(ls -l $DIR/${tdir} |
11177                 awk '/stats_testdir2/ {print $5}')
11178
11179         testdir1_size=$(order_2 $testdir1_size)
11180         testdir2_size=$(order_2 $testdir2_size)
11181
11182         testdir1_size=$(size_in_KMGT $testdir1_size)
11183         testdir2_size=$(size_in_KMGT $testdir2_size)
11184
11185         echo "source rename dir size: ${testdir1_size}"
11186         echo "target rename dir size: ${testdir2_size}"
11187
11188         local cmd="do_facet $SINGLEMDS $LCTL "
11189         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11190
11191         eval $cmd || error "$cmd failed"
11192         local samedir=$($cmd | grep 'same_dir')
11193         local same_sample=$(get_rename_size $testdir1_size)
11194         [ -z "$samedir" ] && error "samedir_rename_size count error"
11195         [[ $same_sample -eq 1 ]] ||
11196                 error "samedir_rename_size error $same_sample"
11197         echo "Check same dir rename stats success"
11198
11199         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11200
11201         # check crossdir rename size
11202         mv ${testdir1}/test_0 ${testdir2}/test_0
11203
11204         testdir1_size=$(ls -l $DIR/${tdir} |
11205                 awk '/stats_testdir1/ {print $5}')
11206         testdir2_size=$(ls -l $DIR/${tdir} |
11207                 awk '/stats_testdir2/ {print $5}')
11208
11209         testdir1_size=$(order_2 $testdir1_size)
11210         testdir2_size=$(order_2 $testdir2_size)
11211
11212         testdir1_size=$(size_in_KMGT $testdir1_size)
11213         testdir2_size=$(size_in_KMGT $testdir2_size)
11214
11215         echo "source rename dir size: ${testdir1_size}"
11216         echo "target rename dir size: ${testdir2_size}"
11217
11218         eval $cmd || error "$cmd failed"
11219         local crossdir=$($cmd | grep 'crossdir')
11220         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11221         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11222         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11223         [[ $src_sample -eq 1 ]] ||
11224                 error "crossdir_rename_size error $src_sample"
11225         [[ $tgt_sample -eq 1 ]] ||
11226                 error "crossdir_rename_size error $tgt_sample"
11227         echo "Check cross dir rename stats success"
11228         rm -rf $DIR/${tdir}
11229 }
11230 run_test 133d "Verifying rename_stats ========================================"
11231
11232 test_133e() {
11233         remote_mds_nodsh && skip "remote MDS with nodsh"
11234         remote_ost_nodsh && skip "remote OST with nodsh"
11235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11236
11237         local testdir=$DIR/${tdir}/stats_testdir
11238         local ctr f0 f1 bs=32768 count=42 sum
11239
11240         mkdir -p ${testdir} || error "mkdir failed"
11241
11242         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11243
11244         for ctr in {write,read}_bytes; do
11245                 sync
11246                 cancel_lru_locks osc
11247
11248                 do_facet ost1 $LCTL set_param -n \
11249                         "obdfilter.*.exports.clear=clear"
11250
11251                 if [ $ctr = write_bytes ]; then
11252                         f0=/dev/zero
11253                         f1=${testdir}/${tfile}
11254                 else
11255                         f0=${testdir}/${tfile}
11256                         f1=/dev/null
11257                 fi
11258
11259                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11260                         error "dd failed"
11261                 sync
11262                 cancel_lru_locks osc
11263
11264                 sum=$(do_facet ost1 $LCTL get_param \
11265                         "obdfilter.*.exports.*.stats" |
11266                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11267                                 $1 == ctr { sum += $7 }
11268                                 END { printf("%0.0f", sum) }')
11269
11270                 if ((sum != bs * count)); then
11271                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11272                 fi
11273         done
11274
11275         rm -rf $DIR/${tdir}
11276 }
11277 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11278
11279 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11280
11281 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11282 # not honor the -ignore_readdir_race option correctly. So we call
11283 # error_ignore() rather than error() in these cases. See LU-11152.
11284 error_133() {
11285         if (find --version; do_facet mds1 find --version) |
11286                 grep -q '\b4\.5\.1[1-4]\b'; then
11287                 error_ignore LU-11152 "$@"
11288         else
11289                 error "$@"
11290         fi
11291 }
11292
11293 test_133f() {
11294         # First without trusting modes.
11295         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11296         echo "proc_dirs='$proc_dirs'"
11297         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11298         find $proc_dirs -exec cat '{}' \; &> /dev/null
11299
11300         # Second verifying readability.
11301         $LCTL get_param -R '*' &> /dev/null
11302
11303         # Verifing writability with badarea_io.
11304         find $proc_dirs \
11305                 -ignore_readdir_race \
11306                 -type f \
11307                 -not -name force_lbug \
11308                 -not -name changelog_mask \
11309                 -exec badarea_io '{}' \; ||
11310                         error_133 "find $proc_dirs failed"
11311 }
11312 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11313
11314 test_133g() {
11315         remote_mds_nodsh && skip "remote MDS with nodsh"
11316         remote_ost_nodsh && skip "remote OST with nodsh"
11317
11318         # eventually, this can also be replaced with "lctl get_param -R",
11319         # but not until that option is always available on the server
11320         local facet
11321         for facet in mds1 ost1; do
11322                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11323                         skip_noexit "Too old lustre on $facet"
11324                 local facet_proc_dirs=$(do_facet $facet \
11325                                         \\\ls -d $proc_regexp 2>/dev/null)
11326                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11327                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11328                 do_facet $facet find $facet_proc_dirs \
11329                         ! -name req_history \
11330                         -exec cat '{}' \\\; &> /dev/null
11331
11332                 do_facet $facet find $facet_proc_dirs \
11333                         ! -name req_history \
11334                         -type f \
11335                         -exec cat '{}' \\\; &> /dev/null ||
11336                                 error "proc file read failed"
11337
11338                 do_facet $facet find $facet_proc_dirs \
11339                         -ignore_readdir_race \
11340                         -type f \
11341                         -not -name force_lbug \
11342                         -not -name changelog_mask \
11343                         -exec badarea_io '{}' \\\; ||
11344                                 error_133 "$facet find $facet_proc_dirs failed"
11345         done
11346
11347         # remount the FS in case writes/reads /proc break the FS
11348         cleanup || error "failed to unmount"
11349         setup || error "failed to setup"
11350         true
11351 }
11352 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11353
11354 test_133h() {
11355         remote_mds_nodsh && skip "remote MDS with nodsh"
11356         remote_ost_nodsh && skip "remote OST with nodsh"
11357         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11358                 skip "Need MDS version at least 2.9.54"
11359
11360         local facet
11361
11362         for facet in client mds1 ost1; do
11363                 local facet_proc_dirs=$(do_facet $facet \
11364                                         \\\ls -d $proc_regexp 2> /dev/null)
11365                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11366                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11367                 # Get the list of files that are missing the terminating newline
11368                 local missing=($(do_facet $facet \
11369                         find ${facet_proc_dirs} -type f \|              \
11370                                 while read F\; do                       \
11371                                         awk -v FS='\v' -v RS='\v\v'     \
11372                                         "'END { if(NR>0 &&              \
11373                                         \\\$NF !~ /.*\\\n\$/)           \
11374                                                 print FILENAME}'"       \
11375                                         '\$F'\;                         \
11376                                 done 2>/dev/null))
11377                 [ ${#missing[*]} -eq 0 ] ||
11378                         error "files do not end with newline: ${missing[*]}"
11379         done
11380 }
11381 run_test 133h "Proc files should end with newlines"
11382
11383 test_134a() {
11384         remote_mds_nodsh && skip "remote MDS with nodsh"
11385         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11386                 skip "Need MDS version at least 2.7.54"
11387
11388         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11389         cancel_lru_locks mdc
11390
11391         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11392         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11393         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11394
11395         local nr=1000
11396         createmany -o $DIR/$tdir/f $nr ||
11397                 error "failed to create $nr files in $DIR/$tdir"
11398         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11399
11400         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11401         do_facet mds1 $LCTL set_param fail_loc=0x327
11402         do_facet mds1 $LCTL set_param fail_val=500
11403         touch $DIR/$tdir/m
11404
11405         echo "sleep 10 seconds ..."
11406         sleep 10
11407         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11408
11409         do_facet mds1 $LCTL set_param fail_loc=0
11410         do_facet mds1 $LCTL set_param fail_val=0
11411         [ $lck_cnt -lt $unused ] ||
11412                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11413
11414         rm $DIR/$tdir/m
11415         unlinkmany $DIR/$tdir/f $nr
11416 }
11417 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11418
11419 test_134b() {
11420         remote_mds_nodsh && skip "remote MDS with nodsh"
11421         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11422                 skip "Need MDS version at least 2.7.54"
11423
11424         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11425         cancel_lru_locks mdc
11426
11427         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11428                         ldlm.lock_reclaim_threshold_mb)
11429         # disable reclaim temporarily
11430         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11431
11432         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11433         do_facet mds1 $LCTL set_param fail_loc=0x328
11434         do_facet mds1 $LCTL set_param fail_val=500
11435
11436         $LCTL set_param debug=+trace
11437
11438         local nr=600
11439         createmany -o $DIR/$tdir/f $nr &
11440         local create_pid=$!
11441
11442         echo "Sleep $TIMEOUT seconds ..."
11443         sleep $TIMEOUT
11444         if ! ps -p $create_pid  > /dev/null 2>&1; then
11445                 do_facet mds1 $LCTL set_param fail_loc=0
11446                 do_facet mds1 $LCTL set_param fail_val=0
11447                 do_facet mds1 $LCTL set_param \
11448                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11449                 error "createmany finished incorrectly!"
11450         fi
11451         do_facet mds1 $LCTL set_param fail_loc=0
11452         do_facet mds1 $LCTL set_param fail_val=0
11453         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11454         wait $create_pid || return 1
11455
11456         unlinkmany $DIR/$tdir/f $nr
11457 }
11458 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11459
11460 test_140() { #bug-17379
11461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11462
11463         test_mkdir $DIR/$tdir
11464         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11465         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11466
11467         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11468         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11469         local i=0
11470         while i=$((i + 1)); do
11471                 test_mkdir $i
11472                 cd $i || error "Changing to $i"
11473                 ln -s ../stat stat || error "Creating stat symlink"
11474                 # Read the symlink until ELOOP present,
11475                 # not LBUGing the system is considered success,
11476                 # we didn't overrun the stack.
11477                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11478                 if [ $ret -ne 0 ]; then
11479                         if [ $ret -eq 40 ]; then
11480                                 break  # -ELOOP
11481                         else
11482                                 error "Open stat symlink"
11483                                         return
11484                         fi
11485                 fi
11486         done
11487         i=$((i - 1))
11488         echo "The symlink depth = $i"
11489         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
11490                                         error "Invalid symlink depth"
11491
11492         # Test recursive symlink
11493         ln -s symlink_self symlink_self
11494         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11495         echo "open symlink_self returns $ret"
11496         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11497 }
11498 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11499
11500 test_150() {
11501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11502
11503         local TF="$TMP/$tfile"
11504
11505         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11506         cp $TF $DIR/$tfile
11507         cancel_lru_locks $OSC
11508         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11509         remount_client $MOUNT
11510         df -P $MOUNT
11511         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11512
11513         $TRUNCATE $TF 6000
11514         $TRUNCATE $DIR/$tfile 6000
11515         cancel_lru_locks $OSC
11516         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11517
11518         echo "12345" >>$TF
11519         echo "12345" >>$DIR/$tfile
11520         cancel_lru_locks $OSC
11521         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11522
11523         echo "12345" >>$TF
11524         echo "12345" >>$DIR/$tfile
11525         cancel_lru_locks $OSC
11526         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11527
11528         rm -f $TF
11529         true
11530 }
11531 run_test 150 "truncate/append tests"
11532
11533 #LU-2902 roc_hit was not able to read all values from lproc
11534 function roc_hit_init() {
11535         local list=$(comma_list $(osts_nodes))
11536         local dir=$DIR/$tdir-check
11537         local file=$dir/$tfile
11538         local BEFORE
11539         local AFTER
11540         local idx
11541
11542         test_mkdir $dir
11543         #use setstripe to do a write to every ost
11544         for i in $(seq 0 $((OSTCOUNT-1))); do
11545                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11546                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11547                 idx=$(printf %04x $i)
11548                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11549                         awk '$1 == "cache_access" {sum += $7}
11550                                 END { printf("%0.0f", sum) }')
11551
11552                 cancel_lru_locks osc
11553                 cat $file >/dev/null
11554
11555                 AFTER=$(get_osd_param $list *OST*$idx stats |
11556                         awk '$1 == "cache_access" {sum += $7}
11557                                 END { printf("%0.0f", sum) }')
11558
11559                 echo BEFORE:$BEFORE AFTER:$AFTER
11560                 if ! let "AFTER - BEFORE == 4"; then
11561                         rm -rf $dir
11562                         error "roc_hit is not safe to use"
11563                 fi
11564                 rm $file
11565         done
11566
11567         rm -rf $dir
11568 }
11569
11570 function roc_hit() {
11571         local list=$(comma_list $(osts_nodes))
11572         echo $(get_osd_param $list '' stats |
11573                 awk '$1 == "cache_hit" {sum += $7}
11574                         END { printf("%0.0f", sum) }')
11575 }
11576
11577 function set_cache() {
11578         local on=1
11579
11580         if [ "$2" == "off" ]; then
11581                 on=0;
11582         fi
11583         local list=$(comma_list $(osts_nodes))
11584         set_osd_param $list '' $1_cache_enable $on
11585
11586         cancel_lru_locks osc
11587 }
11588
11589 test_151() {
11590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11591         remote_ost_nodsh && skip "remote OST with nodsh"
11592
11593         local CPAGES=3
11594         local list=$(comma_list $(osts_nodes))
11595
11596         # check whether obdfilter is cache capable at all
11597         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11598                 skip "not cache-capable obdfilter"
11599         fi
11600
11601         # check cache is enabled on all obdfilters
11602         if get_osd_param $list '' read_cache_enable | grep 0; then
11603                 skip "oss cache is disabled"
11604         fi
11605
11606         set_osd_param $list '' writethrough_cache_enable 1
11607
11608         # check write cache is enabled on all obdfilters
11609         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11610                 skip "oss write cache is NOT enabled"
11611         fi
11612
11613         roc_hit_init
11614
11615         #define OBD_FAIL_OBD_NO_LRU  0x609
11616         do_nodes $list $LCTL set_param fail_loc=0x609
11617
11618         # pages should be in the case right after write
11619         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11620                 error "dd failed"
11621
11622         local BEFORE=$(roc_hit)
11623         cancel_lru_locks osc
11624         cat $DIR/$tfile >/dev/null
11625         local AFTER=$(roc_hit)
11626
11627         do_nodes $list $LCTL set_param fail_loc=0
11628
11629         if ! let "AFTER - BEFORE == CPAGES"; then
11630                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11631         fi
11632
11633         # the following read invalidates the cache
11634         cancel_lru_locks osc
11635         set_osd_param $list '' read_cache_enable 0
11636         cat $DIR/$tfile >/dev/null
11637
11638         # now data shouldn't be found in the cache
11639         BEFORE=$(roc_hit)
11640         cancel_lru_locks osc
11641         cat $DIR/$tfile >/dev/null
11642         AFTER=$(roc_hit)
11643         if let "AFTER - BEFORE != 0"; then
11644                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11645         fi
11646
11647         set_osd_param $list '' read_cache_enable 1
11648         rm -f $DIR/$tfile
11649 }
11650 run_test 151 "test cache on oss and controls ==============================="
11651
11652 test_152() {
11653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11654
11655         local TF="$TMP/$tfile"
11656
11657         # simulate ENOMEM during write
11658 #define OBD_FAIL_OST_NOMEM      0x226
11659         lctl set_param fail_loc=0x80000226
11660         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11661         cp $TF $DIR/$tfile
11662         sync || error "sync failed"
11663         lctl set_param fail_loc=0
11664
11665         # discard client's cache
11666         cancel_lru_locks osc
11667
11668         # simulate ENOMEM during read
11669         lctl set_param fail_loc=0x80000226
11670         cmp $TF $DIR/$tfile || error "cmp failed"
11671         lctl set_param fail_loc=0
11672
11673         rm -f $TF
11674 }
11675 run_test 152 "test read/write with enomem ============================"
11676
11677 test_153() {
11678         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11679 }
11680 run_test 153 "test if fdatasync does not crash ======================="
11681
11682 dot_lustre_fid_permission_check() {
11683         local fid=$1
11684         local ffid=$MOUNT/.lustre/fid/$fid
11685         local test_dir=$2
11686
11687         echo "stat fid $fid"
11688         stat $ffid > /dev/null || error "stat $ffid failed."
11689         echo "touch fid $fid"
11690         touch $ffid || error "touch $ffid failed."
11691         echo "write to fid $fid"
11692         cat /etc/hosts > $ffid || error "write $ffid failed."
11693         echo "read fid $fid"
11694         diff /etc/hosts $ffid || error "read $ffid failed."
11695         echo "append write to fid $fid"
11696         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11697         echo "rename fid $fid"
11698         mv $ffid $test_dir/$tfile.1 &&
11699                 error "rename $ffid to $tfile.1 should fail."
11700         touch $test_dir/$tfile.1
11701         mv $test_dir/$tfile.1 $ffid &&
11702                 error "rename $tfile.1 to $ffid should fail."
11703         rm -f $test_dir/$tfile.1
11704         echo "truncate fid $fid"
11705         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11706         echo "link fid $fid"
11707         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11708         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11709                 echo "setfacl fid $fid"
11710                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11711                 echo "getfacl fid $fid"
11712                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11713         fi
11714         echo "unlink fid $fid"
11715         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11716         echo "mknod fid $fid"
11717         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11718
11719         fid=[0xf00000400:0x1:0x0]
11720         ffid=$MOUNT/.lustre/fid/$fid
11721
11722         echo "stat non-exist fid $fid"
11723         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11724         echo "write to non-exist fid $fid"
11725         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11726         echo "link new fid $fid"
11727         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11728
11729         mkdir -p $test_dir/$tdir
11730         touch $test_dir/$tdir/$tfile
11731         fid=$($LFS path2fid $test_dir/$tdir)
11732         rc=$?
11733         [ $rc -ne 0 ] &&
11734                 error "error: could not get fid for $test_dir/$dir/$tfile."
11735
11736         ffid=$MOUNT/.lustre/fid/$fid
11737
11738         echo "ls $fid"
11739         ls $ffid > /dev/null || error "ls $ffid failed."
11740         echo "touch $fid/$tfile.1"
11741         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11742
11743         echo "touch $MOUNT/.lustre/fid/$tfile"
11744         touch $MOUNT/.lustre/fid/$tfile && \
11745                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11746
11747         echo "setxattr to $MOUNT/.lustre/fid"
11748         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11749
11750         echo "listxattr for $MOUNT/.lustre/fid"
11751         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11752
11753         echo "delxattr from $MOUNT/.lustre/fid"
11754         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11755
11756         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11757         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11758                 error "touch invalid fid should fail."
11759
11760         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11761         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11762                 error "touch non-normal fid should fail."
11763
11764         echo "rename $tdir to $MOUNT/.lustre/fid"
11765         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11766                 error "rename to $MOUNT/.lustre/fid should fail."
11767
11768         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11769         then            # LU-3547
11770                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11771                 local new_obf_mode=777
11772
11773                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11774                 chmod $new_obf_mode $DIR/.lustre/fid ||
11775                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11776
11777                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11778                 [ $obf_mode -eq $new_obf_mode ] ||
11779                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11780
11781                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11782                 chmod $old_obf_mode $DIR/.lustre/fid ||
11783                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11784         fi
11785
11786         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11787         fid=$($LFS path2fid $test_dir/$tfile-2)
11788
11789         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11790         then # LU-5424
11791                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11792                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11793                         error "create lov data thru .lustre failed"
11794         fi
11795         echo "cp /etc/passwd $test_dir/$tfile-2"
11796         cp /etc/passwd $test_dir/$tfile-2 ||
11797                 error "copy to $test_dir/$tfile-2 failed."
11798         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11799         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11800                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11801
11802         rm -rf $test_dir/tfile.lnk
11803         rm -rf $test_dir/$tfile-2
11804 }
11805
11806 test_154A() {
11807         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11808                 skip "Need MDS version at least 2.4.1"
11809
11810         local tf=$DIR/$tfile
11811         touch $tf
11812
11813         local fid=$($LFS path2fid $tf)
11814         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11815
11816         # check that we get the same pathname back
11817         local found=$($LFS fid2path $MOUNT "$fid")
11818         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11819         [ "$found" == "$tf" ] ||
11820                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11821 }
11822 run_test 154A "lfs path2fid and fid2path basic checks"
11823
11824 test_154B() {
11825         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11826                 skip "Need MDS version at least 2.4.1"
11827
11828         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11829         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11830         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11831         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11832
11833         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11834         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11835
11836         # check that we get the same pathname
11837         echo "PFID: $PFID, name: $name"
11838         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11839         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11840         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11841                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11842
11843         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11844 }
11845 run_test 154B "verify the ll_decode_linkea tool"
11846
11847 test_154a() {
11848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11849         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11850         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11851                 skip "Need MDS version at least 2.2.51"
11852         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11853
11854         cp /etc/hosts $DIR/$tfile
11855
11856         fid=$($LFS path2fid $DIR/$tfile)
11857         rc=$?
11858         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11859
11860         dot_lustre_fid_permission_check "$fid" $DIR ||
11861                 error "dot lustre permission check $fid failed"
11862
11863         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11864
11865         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11866
11867         touch $MOUNT/.lustre/file &&
11868                 error "creation is not allowed under .lustre"
11869
11870         mkdir $MOUNT/.lustre/dir &&
11871                 error "mkdir is not allowed under .lustre"
11872
11873         rm -rf $DIR/$tfile
11874 }
11875 run_test 154a "Open-by-FID"
11876
11877 test_154b() {
11878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11879         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11880         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11881         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11882                 skip "Need MDS version at least 2.2.51"
11883
11884         local remote_dir=$DIR/$tdir/remote_dir
11885         local MDTIDX=1
11886         local rc=0
11887
11888         mkdir -p $DIR/$tdir
11889         $LFS mkdir -i $MDTIDX $remote_dir ||
11890                 error "create remote directory failed"
11891
11892         cp /etc/hosts $remote_dir/$tfile
11893
11894         fid=$($LFS path2fid $remote_dir/$tfile)
11895         rc=$?
11896         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11897
11898         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11899                 error "dot lustre permission check $fid failed"
11900         rm -rf $DIR/$tdir
11901 }
11902 run_test 154b "Open-by-FID for remote directory"
11903
11904 test_154c() {
11905         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11906                 skip "Need MDS version at least 2.4.1"
11907
11908         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11909         local FID1=$($LFS path2fid $DIR/$tfile.1)
11910         local FID2=$($LFS path2fid $DIR/$tfile.2)
11911         local FID3=$($LFS path2fid $DIR/$tfile.3)
11912
11913         local N=1
11914         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11915                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11916                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11917                 local want=FID$N
11918                 [ "$FID" = "${!want}" ] ||
11919                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11920                 N=$((N + 1))
11921         done
11922
11923         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11924         do
11925                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11926                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11927                 N=$((N + 1))
11928         done
11929 }
11930 run_test 154c "lfs path2fid and fid2path multiple arguments"
11931
11932 test_154d() {
11933         remote_mds_nodsh && skip "remote MDS with nodsh"
11934         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11935                 skip "Need MDS version at least 2.5.53"
11936
11937         if remote_mds; then
11938                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11939         else
11940                 nid="0@lo"
11941         fi
11942         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11943         local fd
11944         local cmd
11945
11946         rm -f $DIR/$tfile
11947         touch $DIR/$tfile
11948
11949         local fid=$($LFS path2fid $DIR/$tfile)
11950         # Open the file
11951         fd=$(free_fd)
11952         cmd="exec $fd<$DIR/$tfile"
11953         eval $cmd
11954         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11955         echo "$fid_list" | grep "$fid"
11956         rc=$?
11957
11958         cmd="exec $fd>/dev/null"
11959         eval $cmd
11960         if [ $rc -ne 0 ]; then
11961                 error "FID $fid not found in open files list $fid_list"
11962         fi
11963 }
11964 run_test 154d "Verify open file fid"
11965
11966 test_154e()
11967 {
11968         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11969                 skip "Need MDS version at least 2.6.50"
11970
11971         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11972                 error ".lustre returned by readdir"
11973         fi
11974 }
11975 run_test 154e ".lustre is not returned by readdir"
11976
11977 test_154f() {
11978         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11979
11980         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11981         test_mkdir -p -c1 $DIR/$tdir/d
11982         # test dirs inherit from its stripe
11983         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11984         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11985         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11986         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
11987         touch $DIR/f
11988
11989         # get fid of parents
11990         local FID0=$($LFS path2fid $DIR/$tdir/d)
11991         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
11992         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
11993         local FID3=$($LFS path2fid $DIR)
11994
11995         # check that path2fid --parents returns expected <parent_fid>/name
11996         # 1) test for a directory (single parent)
11997         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
11998         [ "$parent" == "$FID0/foo1" ] ||
11999                 error "expected parent: $FID0/foo1, got: $parent"
12000
12001         # 2) test for a file with nlink > 1 (multiple parents)
12002         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12003         echo "$parent" | grep -F "$FID1/$tfile" ||
12004                 error "$FID1/$tfile not returned in parent list"
12005         echo "$parent" | grep -F "$FID2/link" ||
12006                 error "$FID2/link not returned in parent list"
12007
12008         # 3) get parent by fid
12009         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12010         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12011         echo "$parent" | grep -F "$FID1/$tfile" ||
12012                 error "$FID1/$tfile not returned in parent list (by fid)"
12013         echo "$parent" | grep -F "$FID2/link" ||
12014                 error "$FID2/link not returned in parent list (by fid)"
12015
12016         # 4) test for entry in root directory
12017         parent=$($LFS path2fid --parents $DIR/f)
12018         echo "$parent" | grep -F "$FID3/f" ||
12019                 error "$FID3/f not returned in parent list"
12020
12021         # 5) test it on root directory
12022         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12023                 error "$MOUNT should not have parents"
12024
12025         # enable xattr caching and check that linkea is correctly updated
12026         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12027         save_lustre_params client "llite.*.xattr_cache" > $save
12028         lctl set_param llite.*.xattr_cache 1
12029
12030         # 6.1) linkea update on rename
12031         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12032
12033         # get parents by fid
12034         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12035         # foo1 should no longer be returned in parent list
12036         echo "$parent" | grep -F "$FID1" &&
12037                 error "$FID1 should no longer be in parent list"
12038         # the new path should appear
12039         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12040                 error "$FID2/$tfile.moved is not in parent list"
12041
12042         # 6.2) linkea update on unlink
12043         rm -f $DIR/$tdir/d/foo2/link
12044         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12045         # foo2/link should no longer be returned in parent list
12046         echo "$parent" | grep -F "$FID2/link" &&
12047                 error "$FID2/link should no longer be in parent list"
12048         true
12049
12050         rm -f $DIR/f
12051         restore_lustre_params < $save
12052         rm -f $save
12053 }
12054 run_test 154f "get parent fids by reading link ea"
12055
12056 test_154g()
12057 {
12058         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12059         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12060            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12061                 skip "Need MDS version at least 2.6.92"
12062
12063         mkdir -p $DIR/$tdir
12064         llapi_fid_test -d $DIR/$tdir
12065 }
12066 run_test 154g "various llapi FID tests"
12067
12068 test_155_small_load() {
12069     local temp=$TMP/$tfile
12070     local file=$DIR/$tfile
12071
12072     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12073         error "dd of=$temp bs=6096 count=1 failed"
12074     cp $temp $file
12075     cancel_lru_locks $OSC
12076     cmp $temp $file || error "$temp $file differ"
12077
12078     $TRUNCATE $temp 6000
12079     $TRUNCATE $file 6000
12080     cmp $temp $file || error "$temp $file differ (truncate1)"
12081
12082     echo "12345" >>$temp
12083     echo "12345" >>$file
12084     cmp $temp $file || error "$temp $file differ (append1)"
12085
12086     echo "12345" >>$temp
12087     echo "12345" >>$file
12088     cmp $temp $file || error "$temp $file differ (append2)"
12089
12090     rm -f $temp $file
12091     true
12092 }
12093
12094 test_155_big_load() {
12095         remote_ost_nodsh && skip "remote OST with nodsh"
12096
12097         local temp=$TMP/$tfile
12098         local file=$DIR/$tfile
12099
12100         free_min_max
12101         local cache_size=$(do_facet ost$((MAXI+1)) \
12102                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12103         local large_file_size=$((cache_size * 2))
12104
12105         echo "OSS cache size: $cache_size KB"
12106         echo "Large file size: $large_file_size KB"
12107
12108         [ $MAXV -le $large_file_size ] &&
12109                 skip_env "max available OST size needs > $large_file_size KB"
12110
12111         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12112
12113         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12114                 error "dd of=$temp bs=$large_file_size count=1k failed"
12115         cp $temp $file
12116         ls -lh $temp $file
12117         cancel_lru_locks osc
12118         cmp $temp $file || error "$temp $file differ"
12119
12120         rm -f $temp $file
12121         true
12122 }
12123
12124 save_writethrough() {
12125         local facets=$(get_facets OST)
12126
12127         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12128 }
12129
12130 test_155a() {
12131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12132
12133         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12134
12135         save_writethrough $p
12136
12137         set_cache read on
12138         set_cache writethrough on
12139         test_155_small_load
12140         restore_lustre_params < $p
12141         rm -f $p
12142 }
12143 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12144
12145 test_155b() {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147
12148         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12149
12150         save_writethrough $p
12151
12152         set_cache read on
12153         set_cache writethrough off
12154         test_155_small_load
12155         restore_lustre_params < $p
12156         rm -f $p
12157 }
12158 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12159
12160 test_155c() {
12161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12162
12163         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12164
12165         save_writethrough $p
12166
12167         set_cache read off
12168         set_cache writethrough on
12169         test_155_small_load
12170         restore_lustre_params < $p
12171         rm -f $p
12172 }
12173 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12174
12175 test_155d() {
12176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12177
12178         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12179
12180         save_writethrough $p
12181
12182         set_cache read off
12183         set_cache writethrough off
12184         test_155_small_load
12185         restore_lustre_params < $p
12186         rm -f $p
12187 }
12188 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12189
12190 test_155e() {
12191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12192
12193         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12194
12195         save_writethrough $p
12196
12197         set_cache read on
12198         set_cache writethrough on
12199         test_155_big_load
12200         restore_lustre_params < $p
12201         rm -f $p
12202 }
12203 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12204
12205 test_155f() {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207
12208         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12209
12210         save_writethrough $p
12211
12212         set_cache read on
12213         set_cache writethrough off
12214         test_155_big_load
12215         restore_lustre_params < $p
12216         rm -f $p
12217 }
12218 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12219
12220 test_155g() {
12221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12222
12223         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12224
12225         save_writethrough $p
12226
12227         set_cache read off
12228         set_cache writethrough on
12229         test_155_big_load
12230         restore_lustre_params < $p
12231         rm -f $p
12232 }
12233 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12234
12235 test_155h() {
12236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12237
12238         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12239
12240         save_writethrough $p
12241
12242         set_cache read off
12243         set_cache writethrough off
12244         test_155_big_load
12245         restore_lustre_params < $p
12246         rm -f $p
12247 }
12248 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12249
12250 test_156() {
12251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12252         remote_ost_nodsh && skip "remote OST with nodsh"
12253         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12254                 skip "stats not implemented on old servers"
12255         [ "$ost1_FSTYPE" = "zfs" ] &&
12256                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12257
12258         local CPAGES=3
12259         local BEFORE
12260         local AFTER
12261         local file="$DIR/$tfile"
12262         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12263
12264         save_writethrough $p
12265         roc_hit_init
12266
12267         log "Turn on read and write cache"
12268         set_cache read on
12269         set_cache writethrough on
12270
12271         log "Write data and read it back."
12272         log "Read should be satisfied from the cache."
12273         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12274         BEFORE=$(roc_hit)
12275         cancel_lru_locks osc
12276         cat $file >/dev/null
12277         AFTER=$(roc_hit)
12278         if ! let "AFTER - BEFORE == CPAGES"; then
12279                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12280         else
12281                 log "cache hits:: before: $BEFORE, after: $AFTER"
12282         fi
12283
12284         log "Read again; it should be satisfied from the cache."
12285         BEFORE=$AFTER
12286         cancel_lru_locks osc
12287         cat $file >/dev/null
12288         AFTER=$(roc_hit)
12289         if ! let "AFTER - BEFORE == CPAGES"; then
12290                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12291         else
12292                 log "cache hits:: before: $BEFORE, after: $AFTER"
12293         fi
12294
12295         log "Turn off the read cache and turn on the write cache"
12296         set_cache read off
12297         set_cache writethrough on
12298
12299         log "Read again; it should be satisfied from the cache."
12300         BEFORE=$(roc_hit)
12301         cancel_lru_locks osc
12302         cat $file >/dev/null
12303         AFTER=$(roc_hit)
12304         if ! let "AFTER - BEFORE == CPAGES"; then
12305                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12306         else
12307                 log "cache hits:: before: $BEFORE, after: $AFTER"
12308         fi
12309
12310         log "Read again; it should not be satisfied from the cache."
12311         BEFORE=$AFTER
12312         cancel_lru_locks osc
12313         cat $file >/dev/null
12314         AFTER=$(roc_hit)
12315         if ! let "AFTER - BEFORE == 0"; then
12316                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12317         else
12318                 log "cache hits:: before: $BEFORE, after: $AFTER"
12319         fi
12320
12321         log "Write data and read it back."
12322         log "Read should be satisfied from the cache."
12323         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12324         BEFORE=$(roc_hit)
12325         cancel_lru_locks osc
12326         cat $file >/dev/null
12327         AFTER=$(roc_hit)
12328         if ! let "AFTER - BEFORE == CPAGES"; then
12329                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12330         else
12331                 log "cache hits:: before: $BEFORE, after: $AFTER"
12332         fi
12333
12334         log "Read again; it should not be satisfied from the cache."
12335         BEFORE=$AFTER
12336         cancel_lru_locks osc
12337         cat $file >/dev/null
12338         AFTER=$(roc_hit)
12339         if ! let "AFTER - BEFORE == 0"; then
12340                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12341         else
12342                 log "cache hits:: before: $BEFORE, after: $AFTER"
12343         fi
12344
12345         log "Turn off read and write cache"
12346         set_cache read off
12347         set_cache writethrough off
12348
12349         log "Write data and read it back"
12350         log "It should not be satisfied from the cache."
12351         rm -f $file
12352         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12353         cancel_lru_locks osc
12354         BEFORE=$(roc_hit)
12355         cat $file >/dev/null
12356         AFTER=$(roc_hit)
12357         if ! let "AFTER - BEFORE == 0"; then
12358                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12359         else
12360                 log "cache hits:: before: $BEFORE, after: $AFTER"
12361         fi
12362
12363         log "Turn on the read cache and turn off the write cache"
12364         set_cache read on
12365         set_cache writethrough off
12366
12367         log "Write data and read it back"
12368         log "It should not be satisfied from the cache."
12369         rm -f $file
12370         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12371         BEFORE=$(roc_hit)
12372         cancel_lru_locks osc
12373         cat $file >/dev/null
12374         AFTER=$(roc_hit)
12375         if ! let "AFTER - BEFORE == 0"; then
12376                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12377         else
12378                 log "cache hits:: before: $BEFORE, after: $AFTER"
12379         fi
12380
12381         log "Read again; it should be satisfied from the cache."
12382         BEFORE=$(roc_hit)
12383         cancel_lru_locks osc
12384         cat $file >/dev/null
12385         AFTER=$(roc_hit)
12386         if ! let "AFTER - BEFORE == CPAGES"; then
12387                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12388         else
12389                 log "cache hits:: before: $BEFORE, after: $AFTER"
12390         fi
12391
12392         restore_lustre_params < $p
12393         rm -f $p $file
12394 }
12395 run_test 156 "Verification of tunables"
12396
12397 test_160a() {
12398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12399         remote_mds_nodsh && skip "remote MDS with nodsh"
12400         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12401                 skip "Need MDS version at least 2.2.0"
12402
12403         changelog_register || error "changelog_register failed"
12404         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12405         changelog_users $SINGLEMDS | grep -q $cl_user ||
12406                 error "User $cl_user not found in changelog_users"
12407
12408         # change something
12409         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12410         changelog_clear 0 || error "changelog_clear failed"
12411         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12412         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12413         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12414         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12415         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12416         rm $DIR/$tdir/pics/desktop.jpg
12417
12418         changelog_dump | tail -10
12419
12420         echo "verifying changelog mask"
12421         changelog_chmask "-MKDIR"
12422         changelog_chmask "-CLOSE"
12423
12424         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12425         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12426
12427         changelog_chmask "+MKDIR"
12428         changelog_chmask "+CLOSE"
12429
12430         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12431         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12432
12433         changelog_dump | tail -10
12434         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12435         CLOSES=$(changelog_dump | grep -c "CLOSE")
12436         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12437         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12438
12439         # verify contents
12440         echo "verifying target fid"
12441         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12442         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12443         [ "$fidc" == "$fidf" ] ||
12444                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12445         echo "verifying parent fid"
12446         # The FID returned from the Changelog may be the directory shard on
12447         # a different MDT, and not the FID returned by path2fid on the parent.
12448         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12449         # since this is what will matter when recreating this file in the tree.
12450         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12451         local pathp=$($LFS fid2path $MOUNT "$fidp")
12452         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12453                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12454
12455         echo "getting records for $cl_user"
12456         changelog_users $SINGLEMDS
12457         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12458         local nclr=3
12459         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12460                 error "changelog_clear failed"
12461         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12462         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12463         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12464                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12465
12466         local min0_rec=$(changelog_users $SINGLEMDS |
12467                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12468         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12469                           awk '{ print $1; exit; }')
12470
12471         changelog_dump | tail -n 5
12472         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12473         [ $first_rec == $((min0_rec + 1)) ] ||
12474                 error "first index should be $min0_rec + 1 not $first_rec"
12475
12476         # LU-3446 changelog index reset on MDT restart
12477         local cur_rec1=$(changelog_users $SINGLEMDS |
12478                          awk '/^current.index:/ { print $NF }')
12479         changelog_clear 0 ||
12480                 error "clear all changelog records for $cl_user failed"
12481         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12482         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12483                 error "Fail to start $SINGLEMDS"
12484         local cur_rec2=$(changelog_users $SINGLEMDS |
12485                          awk '/^current.index:/ { print $NF }')
12486         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12487         [ $cur_rec1 == $cur_rec2 ] ||
12488                 error "current index should be $cur_rec1 not $cur_rec2"
12489
12490         echo "verifying users from this test are deregistered"
12491         changelog_deregister || error "changelog_deregister failed"
12492         changelog_users $SINGLEMDS | grep -q $cl_user &&
12493                 error "User '$cl_user' still in changelog_users"
12494
12495         # lctl get_param -n mdd.*.changelog_users
12496         # current index: 144
12497         # ID    index (idle seconds)
12498         # cl3   144 (2)
12499         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12500                 # this is the normal case where all users were deregistered
12501                 # make sure no new records are added when no users are present
12502                 local last_rec1=$(changelog_users $SINGLEMDS |
12503                                   awk '/^current.index:/ { print $NF }')
12504                 touch $DIR/$tdir/chloe
12505                 local last_rec2=$(changelog_users $SINGLEMDS |
12506                                   awk '/^current.index:/ { print $NF }')
12507                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12508                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12509         else
12510                 # any changelog users must be leftovers from a previous test
12511                 changelog_users $SINGLEMDS
12512                 echo "other changelog users; can't verify off"
12513         fi
12514 }
12515 run_test 160a "changelog sanity"
12516
12517 test_160b() { # LU-3587
12518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12519         remote_mds_nodsh && skip "remote MDS with nodsh"
12520         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12521                 skip "Need MDS version at least 2.2.0"
12522
12523         changelog_register || error "changelog_register failed"
12524         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12525         changelog_users $SINGLEMDS | grep -q $cl_user ||
12526                 error "User '$cl_user' not found in changelog_users"
12527
12528         local longname1=$(str_repeat a 255)
12529         local longname2=$(str_repeat b 255)
12530
12531         cd $DIR
12532         echo "creating very long named file"
12533         touch $longname1 || error "create of '$longname1' failed"
12534         echo "renaming very long named file"
12535         mv $longname1 $longname2
12536
12537         changelog_dump | grep RENME | tail -n 5
12538         rm -f $longname2
12539 }
12540 run_test 160b "Verify that very long rename doesn't crash in changelog"
12541
12542 test_160c() {
12543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12544         remote_mds_nodsh && skip "remote MDS with nodsh"
12545
12546         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12547                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12548                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12549                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12550
12551         local rc=0
12552
12553         # Registration step
12554         changelog_register || error "changelog_register failed"
12555
12556         rm -rf $DIR/$tdir
12557         mkdir -p $DIR/$tdir
12558         $MCREATE $DIR/$tdir/foo_160c
12559         changelog_chmask "-TRUNC"
12560         $TRUNCATE $DIR/$tdir/foo_160c 200
12561         changelog_chmask "+TRUNC"
12562         $TRUNCATE $DIR/$tdir/foo_160c 199
12563         changelog_dump | tail -n 5
12564         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12565         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12566 }
12567 run_test 160c "verify that changelog log catch the truncate event"
12568
12569 test_160d() {
12570         remote_mds_nodsh && skip "remote MDS with nodsh"
12571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12573         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12574                 skip "Need MDS version at least 2.7.60"
12575
12576         # Registration step
12577         changelog_register || error "changelog_register failed"
12578
12579         mkdir -p $DIR/$tdir/migrate_dir
12580         changelog_clear 0 || error "changelog_clear failed"
12581
12582         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12583         changelog_dump | tail -n 5
12584         local migrates=$(changelog_dump | grep -c "MIGRT")
12585         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12586 }
12587 run_test 160d "verify that changelog log catch the migrate event"
12588
12589 test_160e() {
12590         remote_mds_nodsh && skip "remote MDS with nodsh"
12591
12592         # Create a user
12593         changelog_register || error "changelog_register failed"
12594
12595         # Delete a future user (expect fail)
12596         local MDT0=$(facet_svc $SINGLEMDS)
12597         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12598         local rc=$?
12599
12600         if [ $rc -eq 0 ]; then
12601                 error "Deleted non-existant user cl77"
12602         elif [ $rc -ne 2 ]; then
12603                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12604         fi
12605
12606         # Clear to a bad index (1 billion should be safe)
12607         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12608         rc=$?
12609
12610         if [ $rc -eq 0 ]; then
12611                 error "Successfully cleared to invalid CL index"
12612         elif [ $rc -ne 22 ]; then
12613                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12614         fi
12615 }
12616 run_test 160e "changelog negative testing (should return errors)"
12617
12618 test_160f() {
12619         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12620         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12621                 skip "Need MDS version at least 2.10.56"
12622
12623         local mdts=$(comma_list $(mdts_nodes))
12624
12625         # Create a user
12626         changelog_register || error "first changelog_register failed"
12627         changelog_register || error "second changelog_register failed"
12628         local cl_users
12629         declare -A cl_user1
12630         declare -A cl_user2
12631         local user_rec1
12632         local user_rec2
12633         local i
12634
12635         # generate some changelog records to accumulate on each MDT
12636         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12637         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12638                 error "create $DIR/$tdir/$tfile failed"
12639
12640         # check changelogs have been generated
12641         local nbcl=$(changelog_dump | wc -l)
12642         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12643
12644         for param in "changelog_max_idle_time=10" \
12645                      "changelog_gc=1" \
12646                      "changelog_min_gc_interval=2" \
12647                      "changelog_min_free_cat_entries=3"; do
12648                 local MDT0=$(facet_svc $SINGLEMDS)
12649                 local var="${param%=*}"
12650                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12651
12652                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12653                 do_nodes $mdts $LCTL set_param mdd.*.$param
12654         done
12655
12656         # force cl_user2 to be idle (1st part)
12657         sleep 9
12658
12659         # simulate changelog catalog almost full
12660         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12661         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12662
12663         for i in $(seq $MDSCOUNT); do
12664                 cl_users=(${CL_USERS[mds$i]})
12665                 cl_user1[mds$i]="${cl_users[0]}"
12666                 cl_user2[mds$i]="${cl_users[1]}"
12667
12668                 [ -n "${cl_user1[mds$i]}" ] ||
12669                         error "mds$i: no user registered"
12670                 [ -n "${cl_user2[mds$i]}" ] ||
12671                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12672
12673                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12674                 [ -n "$user_rec1" ] ||
12675                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12676                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12677                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12678                 [ -n "$user_rec2" ] ||
12679                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12680                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12681                      "$user_rec1 + 2 == $user_rec2"
12682                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12683                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12684                               "$user_rec1 + 2, but is $user_rec2"
12685                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12686                 [ -n "$user_rec2" ] ||
12687                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12688                 [ $user_rec1 == $user_rec2 ] ||
12689                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12690                               "$user_rec1, but is $user_rec2"
12691         done
12692
12693         # force cl_user2 to be idle (2nd part) and to reach
12694         # changelog_max_idle_time
12695         sleep 2
12696
12697         # generate one more changelog to trigger fail_loc
12698         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12699                 error "create $DIR/$tdir/${tfile}bis failed"
12700
12701         # ensure gc thread is done
12702         for i in $(mdts_nodes); do
12703                 wait_update $i \
12704                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12705                         error "$i: GC-thread not done"
12706         done
12707
12708         local first_rec
12709         for i in $(seq $MDSCOUNT); do
12710                 # check cl_user1 still registered
12711                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12712                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12713                 # check cl_user2 unregistered
12714                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12715                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12716
12717                 # check changelogs are present and starting at $user_rec1 + 1
12718                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12719                 [ -n "$user_rec1" ] ||
12720                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12721                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12722                             awk '{ print $1; exit; }')
12723
12724                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12725                 [ $((user_rec1 + 1)) == $first_rec ] ||
12726                         error "mds$i: first index should be $user_rec1 + 1, " \
12727                               "but is $first_rec"
12728         done
12729 }
12730 run_test 160f "changelog garbage collect (timestamped users)"
12731
12732 test_160g() {
12733         remote_mds_nodsh && skip "remote MDS with nodsh"
12734         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12735                 skip "Need MDS version at least 2.10.56"
12736
12737         local mdts=$(comma_list $(mdts_nodes))
12738
12739         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12740         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12741
12742         # Create a user
12743         changelog_register || error "first changelog_register failed"
12744         changelog_register || error "second changelog_register failed"
12745         local cl_users
12746         declare -A cl_user1
12747         declare -A cl_user2
12748         local user_rec1
12749         local user_rec2
12750         local i
12751
12752         # generate some changelog records to accumulate on each MDT
12753         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12754         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12755                 error "create $DIR/$tdir/$tfile failed"
12756
12757         # check changelogs have been generated
12758         local nbcl=$(changelog_dump | wc -l)
12759         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12760
12761         # reduce the max_idle_indexes value to make sure we exceed it
12762         max_ndx=$((nbcl / 2 - 1))
12763
12764         for param in "changelog_max_idle_indexes=$max_ndx" \
12765                      "changelog_gc=1" \
12766                      "changelog_min_gc_interval=2" \
12767                      "changelog_min_free_cat_entries=3"; do
12768                 local MDT0=$(facet_svc $SINGLEMDS)
12769                 local var="${param%=*}"
12770                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12771
12772                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12773                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12774                         error "unable to set mdd.*.$param"
12775         done
12776
12777         # simulate changelog catalog almost full
12778         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12779         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12780
12781         for i in $(seq $MDSCOUNT); do
12782                 cl_users=(${CL_USERS[mds$i]})
12783                 cl_user1[mds$i]="${cl_users[0]}"
12784                 cl_user2[mds$i]="${cl_users[1]}"
12785
12786                 [ -n "${cl_user1[mds$i]}" ] ||
12787                         error "mds$i: no user registered"
12788                 [ -n "${cl_user2[mds$i]}" ] ||
12789                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12790
12791                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12792                 [ -n "$user_rec1" ] ||
12793                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12794                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12795                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12796                 [ -n "$user_rec2" ] ||
12797                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12798                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12799                      "$user_rec1 + 2 == $user_rec2"
12800                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12801                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12802                               "$user_rec1 + 2, but is $user_rec2"
12803                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12804                 [ -n "$user_rec2" ] ||
12805                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12806                 [ $user_rec1 == $user_rec2 ] ||
12807                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12808                               "$user_rec1, but is $user_rec2"
12809         done
12810
12811         # ensure we are past the previous changelog_min_gc_interval set above
12812         sleep 2
12813
12814         # generate one more changelog to trigger fail_loc
12815         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12816                 error "create $DIR/$tdir/${tfile}bis failed"
12817
12818         # ensure gc thread is done
12819         for i in $(mdts_nodes); do
12820                 wait_update $i \
12821                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12822                         error "$i: GC-thread not done"
12823         done
12824
12825         local first_rec
12826         for i in $(seq $MDSCOUNT); do
12827                 # check cl_user1 still registered
12828                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12829                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12830                 # check cl_user2 unregistered
12831                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12832                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12833
12834                 # check changelogs are present and starting at $user_rec1 + 1
12835                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12836                 [ -n "$user_rec1" ] ||
12837                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12838                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12839                             awk '{ print $1; exit; }')
12840
12841                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12842                 [ $((user_rec1 + 1)) == $first_rec ] ||
12843                         error "mds$i: first index should be $user_rec1 + 1, " \
12844                               "but is $first_rec"
12845         done
12846 }
12847 run_test 160g "changelog garbage collect (old users)"
12848
12849 test_160h() {
12850         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12851         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12852                 skip "Need MDS version at least 2.10.56"
12853
12854         local mdts=$(comma_list $(mdts_nodes))
12855
12856         # Create a user
12857         changelog_register || error "first changelog_register failed"
12858         changelog_register || error "second changelog_register failed"
12859         local cl_users
12860         declare -A cl_user1
12861         declare -A cl_user2
12862         local user_rec1
12863         local user_rec2
12864         local i
12865
12866         # generate some changelog records to accumulate on each MDT
12867         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12868         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12869                 error "create $DIR/$tdir/$tfile failed"
12870
12871         # check changelogs have been generated
12872         local nbcl=$(changelog_dump | wc -l)
12873         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12874
12875         for param in "changelog_max_idle_time=10" \
12876                      "changelog_gc=1" \
12877                      "changelog_min_gc_interval=2"; do
12878                 local MDT0=$(facet_svc $SINGLEMDS)
12879                 local var="${param%=*}"
12880                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12881
12882                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12883                 do_nodes $mdts $LCTL set_param mdd.*.$param
12884         done
12885
12886         # force cl_user2 to be idle (1st part)
12887         sleep 9
12888
12889         for i in $(seq $MDSCOUNT); do
12890                 cl_users=(${CL_USERS[mds$i]})
12891                 cl_user1[mds$i]="${cl_users[0]}"
12892                 cl_user2[mds$i]="${cl_users[1]}"
12893
12894                 [ -n "${cl_user1[mds$i]}" ] ||
12895                         error "mds$i: no user registered"
12896                 [ -n "${cl_user2[mds$i]}" ] ||
12897                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12898
12899                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12900                 [ -n "$user_rec1" ] ||
12901                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12902                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12903                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12904                 [ -n "$user_rec2" ] ||
12905                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12906                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12907                      "$user_rec1 + 2 == $user_rec2"
12908                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12909                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12910                               "$user_rec1 + 2, but is $user_rec2"
12911                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12912                 [ -n "$user_rec2" ] ||
12913                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12914                 [ $user_rec1 == $user_rec2 ] ||
12915                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12916                               "$user_rec1, but is $user_rec2"
12917         done
12918
12919         # force cl_user2 to be idle (2nd part) and to reach
12920         # changelog_max_idle_time
12921         sleep 2
12922
12923         # force each GC-thread start and block then
12924         # one per MDT/MDD, set fail_val accordingly
12925         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12926         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12927
12928         # generate more changelogs to trigger fail_loc
12929         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12930                 error "create $DIR/$tdir/${tfile}bis failed"
12931
12932         # stop MDT to stop GC-thread, should be done in back-ground as it will
12933         # block waiting for the thread to be released and exit
12934         declare -A stop_pids
12935         for i in $(seq $MDSCOUNT); do
12936                 stop mds$i &
12937                 stop_pids[mds$i]=$!
12938         done
12939
12940         for i in $(mdts_nodes); do
12941                 local facet
12942                 local nb=0
12943                 local facets=$(facets_up_on_host $i)
12944
12945                 for facet in ${facets//,/ }; do
12946                         if [[ $facet == mds* ]]; then
12947                                 nb=$((nb + 1))
12948                         fi
12949                 done
12950                 # ensure each MDS's gc threads are still present and all in "R"
12951                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12952                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12953                         error "$i: expected $nb GC-thread"
12954                 wait_update $i \
12955                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12956                         "R" 20 ||
12957                         error "$i: GC-thread not found in R-state"
12958                 # check umounts of each MDT on MDS have reached kthread_stop()
12959                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12960                         error "$i: expected $nb umount"
12961                 wait_update $i \
12962                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12963                         error "$i: umount not found in D-state"
12964         done
12965
12966         # release all GC-threads
12967         do_nodes $mdts $LCTL set_param fail_loc=0
12968
12969         # wait for MDT stop to complete
12970         for i in $(seq $MDSCOUNT); do
12971                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12972         done
12973
12974         # XXX
12975         # may try to check if any orphan changelog records are present
12976         # via ldiskfs/zfs and llog_reader...
12977
12978         # re-start/mount MDTs
12979         for i in $(seq $MDSCOUNT); do
12980                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12981                         error "Fail to start mds$i"
12982         done
12983
12984         local first_rec
12985         for i in $(seq $MDSCOUNT); do
12986                 # check cl_user1 still registered
12987                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12988                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12989                 # check cl_user2 unregistered
12990                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12991                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12992
12993                 # check changelogs are present and starting at $user_rec1 + 1
12994                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12995                 [ -n "$user_rec1" ] ||
12996                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12997                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12998                             awk '{ print $1; exit; }')
12999
13000                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13001                 [ $((user_rec1 + 1)) == $first_rec ] ||
13002                         error "mds$i: first index should be $user_rec1 + 1, " \
13003                               "but is $first_rec"
13004         done
13005 }
13006 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13007               "during mount"
13008
13009 test_160i() {
13010
13011         local mdts=$(comma_list $(mdts_nodes))
13012
13013         changelog_register || error "first changelog_register failed"
13014
13015         # generate some changelog records to accumulate on each MDT
13016         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13017         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13018                 error "create $DIR/$tdir/$tfile failed"
13019
13020         # check changelogs have been generated
13021         local nbcl=$(changelog_dump | wc -l)
13022         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13023
13024         # simulate race between register and unregister
13025         # XXX as fail_loc is set per-MDS, with DNE configs the race
13026         # simulation will only occur for one MDT per MDS and for the
13027         # others the normal race scenario will take place
13028         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13029         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13030         do_nodes $mdts $LCTL set_param fail_val=1
13031
13032         # unregister 1st user
13033         changelog_deregister &
13034         local pid1=$!
13035         # wait some time for deregister work to reach race rdv
13036         sleep 2
13037         # register 2nd user
13038         changelog_register || error "2nd user register failed"
13039
13040         wait $pid1 || error "1st user deregister failed"
13041
13042         local i
13043         local last_rec
13044         declare -A LAST_REC
13045         for i in $(seq $MDSCOUNT); do
13046                 if changelog_users mds$i | grep "^cl"; then
13047                         # make sure new records are added with one user present
13048                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13049                                           awk '/^current.index:/ { print $NF }')
13050                 else
13051                         error "mds$i has no user registered"
13052                 fi
13053         done
13054
13055         # generate more changelog records to accumulate on each MDT
13056         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13057                 error "create $DIR/$tdir/${tfile}bis failed"
13058
13059         for i in $(seq $MDSCOUNT); do
13060                 last_rec=$(changelog_users $SINGLEMDS |
13061                            awk '/^current.index:/ { print $NF }')
13062                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13063                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13064                         error "changelogs are off on mds$i"
13065         done
13066 }
13067 run_test 160i "changelog user register/unregister race"
13068
13069 test_161a() {
13070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13071
13072         test_mkdir -c1 $DIR/$tdir
13073         cp /etc/hosts $DIR/$tdir/$tfile
13074         test_mkdir -c1 $DIR/$tdir/foo1
13075         test_mkdir -c1 $DIR/$tdir/foo2
13076         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13077         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13078         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13079         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13080         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13081         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13082                 $LFS fid2path $DIR $FID
13083                 error "bad link ea"
13084         fi
13085         # middle
13086         rm $DIR/$tdir/foo2/zachary
13087         # last
13088         rm $DIR/$tdir/foo2/thor
13089         # first
13090         rm $DIR/$tdir/$tfile
13091         # rename
13092         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13093         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13094                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13095         rm $DIR/$tdir/foo2/maggie
13096
13097         # overflow the EA
13098         local longname=$tfile.avg_len_is_thirty_two_
13099         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13100                 error_noexit 'failed to unlink many hardlinks'" EXIT
13101         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13102                 error "failed to hardlink many files"
13103         links=$($LFS fid2path $DIR $FID | wc -l)
13104         echo -n "${links}/1000 links in link EA"
13105         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13106 }
13107 run_test 161a "link ea sanity"
13108
13109 test_161b() {
13110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13111         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13112
13113         local MDTIDX=1
13114         local remote_dir=$DIR/$tdir/remote_dir
13115
13116         mkdir -p $DIR/$tdir
13117         $LFS mkdir -i $MDTIDX $remote_dir ||
13118                 error "create remote directory failed"
13119
13120         cp /etc/hosts $remote_dir/$tfile
13121         mkdir -p $remote_dir/foo1
13122         mkdir -p $remote_dir/foo2
13123         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13124         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13125         ln $remote_dir/$tfile $remote_dir/foo1/luna
13126         ln $remote_dir/$tfile $remote_dir/foo2/thor
13127
13128         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13129                      tr -d ']')
13130         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13131                 $LFS fid2path $DIR $FID
13132                 error "bad link ea"
13133         fi
13134         # middle
13135         rm $remote_dir/foo2/zachary
13136         # last
13137         rm $remote_dir/foo2/thor
13138         # first
13139         rm $remote_dir/$tfile
13140         # rename
13141         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13142         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13143         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13144                 $LFS fid2path $DIR $FID
13145                 error "bad link rename"
13146         fi
13147         rm $remote_dir/foo2/maggie
13148
13149         # overflow the EA
13150         local longname=filename_avg_len_is_thirty_two_
13151         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13152                 error "failed to hardlink many files"
13153         links=$($LFS fid2path $DIR $FID | wc -l)
13154         echo -n "${links}/1000 links in link EA"
13155         [[ ${links} -gt 60 ]] ||
13156                 error "expected at least 60 links in link EA"
13157         unlinkmany $remote_dir/foo2/$longname 1000 ||
13158         error "failed to unlink many hardlinks"
13159 }
13160 run_test 161b "link ea sanity under remote directory"
13161
13162 test_161c() {
13163         remote_mds_nodsh && skip "remote MDS with nodsh"
13164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13165         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13166                 skip "Need MDS version at least 2.1.5"
13167
13168         # define CLF_RENAME_LAST 0x0001
13169         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13170         changelog_register || error "changelog_register failed"
13171
13172         rm -rf $DIR/$tdir
13173         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13174         touch $DIR/$tdir/foo_161c
13175         touch $DIR/$tdir/bar_161c
13176         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13177         changelog_dump | grep RENME | tail -n 5
13178         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13179         changelog_clear 0 || error "changelog_clear failed"
13180         if [ x$flags != "x0x1" ]; then
13181                 error "flag $flags is not 0x1"
13182         fi
13183
13184         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13185         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13186         touch $DIR/$tdir/foo_161c
13187         touch $DIR/$tdir/bar_161c
13188         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13189         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13190         changelog_dump | grep RENME | tail -n 5
13191         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13192         changelog_clear 0 || error "changelog_clear failed"
13193         if [ x$flags != "x0x0" ]; then
13194                 error "flag $flags is not 0x0"
13195         fi
13196         echo "rename overwrite a target having nlink > 1," \
13197                 "changelog record has flags of $flags"
13198
13199         # rename doesn't overwrite a target (changelog flag 0x0)
13200         touch $DIR/$tdir/foo_161c
13201         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13202         changelog_dump | grep RENME | tail -n 5
13203         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13204         changelog_clear 0 || error "changelog_clear failed"
13205         if [ x$flags != "x0x0" ]; then
13206                 error "flag $flags is not 0x0"
13207         fi
13208         echo "rename doesn't overwrite a target," \
13209                 "changelog record has flags of $flags"
13210
13211         # define CLF_UNLINK_LAST 0x0001
13212         # unlink a file having nlink = 1 (changelog flag 0x1)
13213         rm -f $DIR/$tdir/foo2_161c
13214         changelog_dump | grep UNLNK | tail -n 5
13215         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13216         changelog_clear 0 || error "changelog_clear failed"
13217         if [ x$flags != "x0x1" ]; then
13218                 error "flag $flags is not 0x1"
13219         fi
13220         echo "unlink a file having nlink = 1," \
13221                 "changelog record has flags of $flags"
13222
13223         # unlink a file having nlink > 1 (changelog flag 0x0)
13224         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13225         rm -f $DIR/$tdir/foobar_161c
13226         changelog_dump | grep UNLNK | tail -n 5
13227         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13228         changelog_clear 0 || error "changelog_clear failed"
13229         if [ x$flags != "x0x0" ]; then
13230                 error "flag $flags is not 0x0"
13231         fi
13232         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13233 }
13234 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13235
13236 test_161d() {
13237         remote_mds_nodsh && skip "remote MDS with nodsh"
13238         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13239
13240         local pid
13241         local fid
13242
13243         changelog_register || error "changelog_register failed"
13244
13245         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13246         # interfer with $MOUNT/.lustre/fid/ access
13247         mkdir $DIR/$tdir
13248         [[ $? -eq 0 ]] || error "mkdir failed"
13249
13250         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13251         $LCTL set_param fail_loc=0x8000140c
13252         # 5s pause
13253         $LCTL set_param fail_val=5
13254
13255         # create file
13256         echo foofoo > $DIR/$tdir/$tfile &
13257         pid=$!
13258
13259         # wait for create to be delayed
13260         sleep 2
13261
13262         ps -p $pid
13263         [[ $? -eq 0 ]] || error "create should be blocked"
13264
13265         local tempfile=$(mktemp)
13266         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13267         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13268         # some delay may occur during ChangeLog publishing and file read just
13269         # above, that could allow file write to happen finally
13270         [[ -s $tempfile ]] && echo "file should be empty"
13271
13272         $LCTL set_param fail_loc=0
13273
13274         wait $pid
13275         [[ $? -eq 0 ]] || error "create failed"
13276 }
13277 run_test 161d "create with concurrent .lustre/fid access"
13278
13279 check_path() {
13280         local expected="$1"
13281         shift
13282         local fid="$2"
13283
13284         local path
13285         path=$($LFS fid2path "$@")
13286         local rc=$?
13287
13288         if [ $rc -ne 0 ]; then
13289                 error "path looked up of '$expected' failed: rc=$rc"
13290         elif [ "$path" != "$expected" ]; then
13291                 error "path looked up '$path' instead of '$expected'"
13292         else
13293                 echo "FID '$fid' resolves to path '$path' as expected"
13294         fi
13295 }
13296
13297 test_162a() { # was test_162
13298         test_mkdir -p -c1 $DIR/$tdir/d2
13299         touch $DIR/$tdir/d2/$tfile
13300         touch $DIR/$tdir/d2/x1
13301         touch $DIR/$tdir/d2/x2
13302         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13303         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13304         # regular file
13305         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13306         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13307
13308         # softlink
13309         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13310         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13311         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13312
13313         # softlink to wrong file
13314         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13315         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13316         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13317
13318         # hardlink
13319         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13320         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13321         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13322         # fid2path dir/fsname should both work
13323         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13324         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13325
13326         # hardlink count: check that there are 2 links
13327         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13328         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13329
13330         # hardlink indexing: remove the first link
13331         rm $DIR/$tdir/d2/p/q/r/hlink
13332         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13333 }
13334 run_test 162a "path lookup sanity"
13335
13336 test_162b() {
13337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13339
13340         mkdir $DIR/$tdir
13341         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13342                                 error "create striped dir failed"
13343
13344         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13345                                         tail -n 1 | awk '{print $2}')
13346         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13347
13348         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13349         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13350
13351         # regular file
13352         for ((i=0;i<5;i++)); do
13353                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13354                         error "get fid for f$i failed"
13355                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13356
13357                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13358                         error "get fid for d$i failed"
13359                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13360         done
13361
13362         return 0
13363 }
13364 run_test 162b "striped directory path lookup sanity"
13365
13366 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13367 test_162c() {
13368         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13369                 skip "Need MDS version at least 2.7.51"
13370
13371         local lpath=$tdir.local
13372         local rpath=$tdir.remote
13373
13374         test_mkdir $DIR/$lpath
13375         test_mkdir $DIR/$rpath
13376
13377         for ((i = 0; i <= 101; i++)); do
13378                 lpath="$lpath/$i"
13379                 mkdir $DIR/$lpath
13380                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13381                         error "get fid for local directory $DIR/$lpath failed"
13382                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13383
13384                 rpath="$rpath/$i"
13385                 test_mkdir $DIR/$rpath
13386                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13387                         error "get fid for remote directory $DIR/$rpath failed"
13388                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13389         done
13390
13391         return 0
13392 }
13393 run_test 162c "fid2path works with paths 100 or more directories deep"
13394
13395 test_169() {
13396         # do directio so as not to populate the page cache
13397         log "creating a 10 Mb file"
13398         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13399         log "starting reads"
13400         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13401         log "truncating the file"
13402         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13403         log "killing dd"
13404         kill %+ || true # reads might have finished
13405         echo "wait until dd is finished"
13406         wait
13407         log "removing the temporary file"
13408         rm -rf $DIR/$tfile || error "tmp file removal failed"
13409 }
13410 run_test 169 "parallel read and truncate should not deadlock"
13411
13412 test_170() {
13413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13414
13415         $LCTL clear     # bug 18514
13416         $LCTL debug_daemon start $TMP/${tfile}_log_good
13417         touch $DIR/$tfile
13418         $LCTL debug_daemon stop
13419         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13420                 error "sed failed to read log_good"
13421
13422         $LCTL debug_daemon start $TMP/${tfile}_log_good
13423         rm -rf $DIR/$tfile
13424         $LCTL debug_daemon stop
13425
13426         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13427                error "lctl df log_bad failed"
13428
13429         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13430         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13431
13432         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13433         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13434
13435         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13436                 error "bad_line good_line1 good_line2 are empty"
13437
13438         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13439         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13440         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13441
13442         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13443         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13444         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13445
13446         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13447                 error "bad_line_new good_line_new are empty"
13448
13449         local expected_good=$((good_line1 + good_line2*2))
13450
13451         rm -f $TMP/${tfile}*
13452         # LU-231, short malformed line may not be counted into bad lines
13453         if [ $bad_line -ne $bad_line_new ] &&
13454                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13455                 error "expected $bad_line bad lines, but got $bad_line_new"
13456                 return 1
13457         fi
13458
13459         if [ $expected_good -ne $good_line_new ]; then
13460                 error "expected $expected_good good lines, but got $good_line_new"
13461                 return 2
13462         fi
13463         true
13464 }
13465 run_test 170 "test lctl df to handle corrupted log ====================="
13466
13467 test_171() { # bug20592
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13471         $LCTL set_param fail_loc=0x50e
13472         $LCTL set_param fail_val=3000
13473         multiop_bg_pause $DIR/$tfile O_s || true
13474         local MULTIPID=$!
13475         kill -USR1 $MULTIPID
13476         # cause log dump
13477         sleep 3
13478         wait $MULTIPID
13479         if dmesg | grep "recursive fault"; then
13480                 error "caught a recursive fault"
13481         fi
13482         $LCTL set_param fail_loc=0
13483         true
13484 }
13485 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13486
13487 # it would be good to share it with obdfilter-survey/iokit-libecho code
13488 setup_obdecho_osc () {
13489         local rc=0
13490         local ost_nid=$1
13491         local obdfilter_name=$2
13492         echo "Creating new osc for $obdfilter_name on $ost_nid"
13493         # make sure we can find loopback nid
13494         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13495
13496         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13497                            ${obdfilter_name}_osc_UUID || rc=2; }
13498         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13499                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13500         return $rc
13501 }
13502
13503 cleanup_obdecho_osc () {
13504         local obdfilter_name=$1
13505         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13506         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13507         return 0
13508 }
13509
13510 obdecho_test() {
13511         local OBD=$1
13512         local node=$2
13513         local pages=${3:-64}
13514         local rc=0
13515         local id
13516
13517         local count=10
13518         local obd_size=$(get_obd_size $node $OBD)
13519         local page_size=$(get_page_size $node)
13520         if [[ -n "$obd_size" ]]; then
13521                 local new_count=$((obd_size / (pages * page_size / 1024)))
13522                 [[ $new_count -ge $count ]] || count=$new_count
13523         fi
13524
13525         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13526         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13527                            rc=2; }
13528         if [ $rc -eq 0 ]; then
13529             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13530             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13531         fi
13532         echo "New object id is $id"
13533         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13534                            rc=4; }
13535         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13536                            "test_brw $count w v $pages $id" || rc=4; }
13537         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13538                            rc=4; }
13539         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
13540                                         "cleanup" || rc=5; }
13541         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
13542                                         "detach" || rc=6; }
13543         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13544         return $rc
13545 }
13546
13547 test_180a() {
13548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13549
13550         if ! module_loaded obdecho; then
13551                 load_module obdecho/obdecho &&
13552                         stack_trap "rmmod obdecho" EXIT ||
13553                         error "unable to load obdecho on client"
13554         fi
13555
13556         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13557         local host=$($LCTL get_param -n osc.$osc.import |
13558                      awk '/current_connection:/ { print $2 }' )
13559         local target=$($LCTL get_param -n osc.$osc.import |
13560                        awk '/target:/ { print $2 }' )
13561         target=${target%_UUID}
13562
13563         if [ -n "$target" ]; then
13564                 setup_obdecho_osc $host $target &&
13565                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13566                         { error "obdecho setup failed with $?"; return; }
13567
13568                 obdecho_test ${target}_osc client ||
13569                         error "obdecho_test failed on ${target}_osc"
13570         else
13571                 $LCTL get_param osc.$osc.import
13572                 error "there is no osc.$osc.import target"
13573         fi
13574 }
13575 run_test 180a "test obdecho on osc"
13576
13577 test_180b() {
13578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13579         remote_ost_nodsh && skip "remote OST with nodsh"
13580
13581         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13582                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13583                 error "failed to load module obdecho"
13584
13585         local target=$(do_facet ost1 $LCTL dl |
13586                        awk '/obdfilter/ { print $4; exit; }')
13587
13588         if [ -n "$target" ]; then
13589                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13590         else
13591                 do_facet ost1 $LCTL dl
13592                 error "there is no obdfilter target on ost1"
13593         fi
13594 }
13595 run_test 180b "test obdecho directly on obdfilter"
13596
13597 test_180c() { # LU-2598
13598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13599         remote_ost_nodsh && skip "remote OST with nodsh"
13600         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13601                 skip "Need MDS version at least 2.4.0"
13602
13603         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13604                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13605                 error "failed to load module obdecho"
13606
13607         local target=$(do_facet ost1 $LCTL dl |
13608                        awk '/obdfilter/ { print $4; exit; }')
13609
13610         if [ -n "$target" ]; then
13611                 local pages=16384 # 64MB bulk I/O RPC size
13612
13613                 obdecho_test "$target" ost1 "$pages" ||
13614                         error "obdecho_test with pages=$pages failed with $?"
13615         else
13616                 do_facet ost1 $LCTL dl
13617                 error "there is no obdfilter target on ost1"
13618         fi
13619 }
13620 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13621
13622 test_181() { # bug 22177
13623         test_mkdir $DIR/$tdir
13624         # create enough files to index the directory
13625         createmany -o $DIR/$tdir/foobar 4000
13626         # print attributes for debug purpose
13627         lsattr -d .
13628         # open dir
13629         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13630         MULTIPID=$!
13631         # remove the files & current working dir
13632         unlinkmany $DIR/$tdir/foobar 4000
13633         rmdir $DIR/$tdir
13634         kill -USR1 $MULTIPID
13635         wait $MULTIPID
13636         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13637         return 0
13638 }
13639 run_test 181 "Test open-unlinked dir ========================"
13640
13641 test_182() {
13642         local fcount=1000
13643         local tcount=10
13644
13645         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13646
13647         $LCTL set_param mdc.*.rpc_stats=clear
13648
13649         for (( i = 0; i < $tcount; i++ )) ; do
13650                 mkdir $DIR/$tdir/$i
13651         done
13652
13653         for (( i = 0; i < $tcount; i++ )) ; do
13654                 createmany -o $DIR/$tdir/$i/f- $fcount &
13655         done
13656         wait
13657
13658         for (( i = 0; i < $tcount; i++ )) ; do
13659                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13660         done
13661         wait
13662
13663         $LCTL get_param mdc.*.rpc_stats
13664
13665         rm -rf $DIR/$tdir
13666 }
13667 run_test 182 "Test parallel modify metadata operations ================"
13668
13669 test_183() { # LU-2275
13670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13671         remote_mds_nodsh && skip "remote MDS with nodsh"
13672         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13673                 skip "Need MDS version at least 2.3.56"
13674
13675         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13676         echo aaa > $DIR/$tdir/$tfile
13677
13678 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13680
13681         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13682         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13683
13684         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13685
13686         # Flush negative dentry cache
13687         touch $DIR/$tdir/$tfile
13688
13689         # We are not checking for any leaked references here, they'll
13690         # become evident next time we do cleanup with module unload.
13691         rm -rf $DIR/$tdir
13692 }
13693 run_test 183 "No crash or request leak in case of strange dispositions ========"
13694
13695 # test suite 184 is for LU-2016, LU-2017
13696 test_184a() {
13697         check_swap_layouts_support
13698
13699         dir0=$DIR/$tdir/$testnum
13700         test_mkdir -p -c1 $dir0
13701         ref1=/etc/passwd
13702         ref2=/etc/group
13703         file1=$dir0/f1
13704         file2=$dir0/f2
13705         $LFS setstripe -c1 $file1
13706         cp $ref1 $file1
13707         $LFS setstripe -c2 $file2
13708         cp $ref2 $file2
13709         gen1=$($LFS getstripe -g $file1)
13710         gen2=$($LFS getstripe -g $file2)
13711
13712         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13713         gen=$($LFS getstripe -g $file1)
13714         [[ $gen1 != $gen ]] ||
13715                 "Layout generation on $file1 does not change"
13716         gen=$($LFS getstripe -g $file2)
13717         [[ $gen2 != $gen ]] ||
13718                 "Layout generation on $file2 does not change"
13719
13720         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13721         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13722
13723         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13724 }
13725 run_test 184a "Basic layout swap"
13726
13727 test_184b() {
13728         check_swap_layouts_support
13729
13730         dir0=$DIR/$tdir/$testnum
13731         mkdir -p $dir0 || error "creating dir $dir0"
13732         file1=$dir0/f1
13733         file2=$dir0/f2
13734         file3=$dir0/f3
13735         dir1=$dir0/d1
13736         dir2=$dir0/d2
13737         mkdir $dir1 $dir2
13738         $LFS setstripe -c1 $file1
13739         $LFS setstripe -c2 $file2
13740         $LFS setstripe -c1 $file3
13741         chown $RUNAS_ID $file3
13742         gen1=$($LFS getstripe -g $file1)
13743         gen2=$($LFS getstripe -g $file2)
13744
13745         $LFS swap_layouts $dir1 $dir2 &&
13746                 error "swap of directories layouts should fail"
13747         $LFS swap_layouts $dir1 $file1 &&
13748                 error "swap of directory and file layouts should fail"
13749         $RUNAS $LFS swap_layouts $file1 $file2 &&
13750                 error "swap of file we cannot write should fail"
13751         $LFS swap_layouts $file1 $file3 &&
13752                 error "swap of file with different owner should fail"
13753         /bin/true # to clear error code
13754 }
13755 run_test 184b "Forbidden layout swap (will generate errors)"
13756
13757 test_184c() {
13758         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13759         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13760         check_swap_layouts_support
13761
13762         local dir0=$DIR/$tdir/$testnum
13763         mkdir -p $dir0 || error "creating dir $dir0"
13764
13765         local ref1=$dir0/ref1
13766         local ref2=$dir0/ref2
13767         local file1=$dir0/file1
13768         local file2=$dir0/file2
13769         # create a file large enough for the concurrent test
13770         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13771         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13772         echo "ref file size: ref1($(stat -c %s $ref1))," \
13773              "ref2($(stat -c %s $ref2))"
13774
13775         cp $ref2 $file2
13776         dd if=$ref1 of=$file1 bs=16k &
13777         local DD_PID=$!
13778
13779         # Make sure dd starts to copy file
13780         while [ ! -f $file1 ]; do sleep 0.1; done
13781
13782         $LFS swap_layouts $file1 $file2
13783         local rc=$?
13784         wait $DD_PID
13785         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13786         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13787
13788         # how many bytes copied before swapping layout
13789         local copied=$(stat -c %s $file2)
13790         local remaining=$(stat -c %s $ref1)
13791         remaining=$((remaining - copied))
13792         echo "Copied $copied bytes before swapping layout..."
13793
13794         cmp -n $copied $file1 $ref2 | grep differ &&
13795                 error "Content mismatch [0, $copied) of ref2 and file1"
13796         cmp -n $copied $file2 $ref1 ||
13797                 error "Content mismatch [0, $copied) of ref1 and file2"
13798         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13799                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13800
13801         # clean up
13802         rm -f $ref1 $ref2 $file1 $file2
13803 }
13804 run_test 184c "Concurrent write and layout swap"
13805
13806 test_184d() {
13807         check_swap_layouts_support
13808         [ -z "$(which getfattr 2>/dev/null)" ] &&
13809                 skip_env "no getfattr command"
13810
13811         local file1=$DIR/$tdir/$tfile-1
13812         local file2=$DIR/$tdir/$tfile-2
13813         local file3=$DIR/$tdir/$tfile-3
13814         local lovea1
13815         local lovea2
13816
13817         mkdir -p $DIR/$tdir
13818         touch $file1 || error "create $file1 failed"
13819         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13820                 error "create $file2 failed"
13821         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13822                 error "create $file3 failed"
13823         lovea1=$(get_layout_param $file1)
13824
13825         $LFS swap_layouts $file2 $file3 ||
13826                 error "swap $file2 $file3 layouts failed"
13827         $LFS swap_layouts $file1 $file2 ||
13828                 error "swap $file1 $file2 layouts failed"
13829
13830         lovea2=$(get_layout_param $file2)
13831         echo "$lovea1"
13832         echo "$lovea2"
13833         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13834
13835         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13836         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13837 }
13838 run_test 184d "allow stripeless layouts swap"
13839
13840 test_184e() {
13841         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13842                 skip "Need MDS version at least 2.6.94"
13843         check_swap_layouts_support
13844         [ -z "$(which getfattr 2>/dev/null)" ] &&
13845                 skip_env "no getfattr command"
13846
13847         local file1=$DIR/$tdir/$tfile-1
13848         local file2=$DIR/$tdir/$tfile-2
13849         local file3=$DIR/$tdir/$tfile-3
13850         local lovea
13851
13852         mkdir -p $DIR/$tdir
13853         touch $file1 || error "create $file1 failed"
13854         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13855                 error "create $file2 failed"
13856         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13857                 error "create $file3 failed"
13858
13859         $LFS swap_layouts $file1 $file2 ||
13860                 error "swap $file1 $file2 layouts failed"
13861
13862         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13863         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13864
13865         echo 123 > $file1 || error "Should be able to write into $file1"
13866
13867         $LFS swap_layouts $file1 $file3 ||
13868                 error "swap $file1 $file3 layouts failed"
13869
13870         echo 123 > $file1 || error "Should be able to write into $file1"
13871
13872         rm -rf $file1 $file2 $file3
13873 }
13874 run_test 184e "Recreate layout after stripeless layout swaps"
13875
13876 test_184f() {
13877         # Create a file with name longer than sizeof(struct stat) ==
13878         # 144 to see if we can get chars from the file name to appear
13879         # in the returned striping. Note that 'f' == 0x66.
13880         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13881
13882         mkdir -p $DIR/$tdir
13883         mcreate $DIR/$tdir/$file
13884         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13885                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13886         fi
13887 }
13888 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13889
13890 test_185() { # LU-2441
13891         # LU-3553 - no volatile file support in old servers
13892         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13893                 skip "Need MDS version at least 2.3.60"
13894
13895         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13896         touch $DIR/$tdir/spoo
13897         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13898         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13899                 error "cannot create/write a volatile file"
13900         [ "$FILESET" == "" ] &&
13901         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13902                 error "FID is still valid after close"
13903
13904         multiop_bg_pause $DIR/$tdir vVw4096_c
13905         local multi_pid=$!
13906
13907         local OLD_IFS=$IFS
13908         IFS=":"
13909         local fidv=($fid)
13910         IFS=$OLD_IFS
13911         # assume that the next FID for this client is sequential, since stdout
13912         # is unfortunately eaten by multiop_bg_pause
13913         local n=$((${fidv[1]} + 1))
13914         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13915         if [ "$FILESET" == "" ]; then
13916                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13917                         error "FID is missing before close"
13918         fi
13919         kill -USR1 $multi_pid
13920         # 1 second delay, so if mtime change we will see it
13921         sleep 1
13922         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13923         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13924 }
13925 run_test 185 "Volatile file support"
13926
13927 test_187a() {
13928         remote_mds_nodsh && skip "remote MDS with nodsh"
13929         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13930                 skip "Need MDS version at least 2.3.0"
13931
13932         local dir0=$DIR/$tdir/$testnum
13933         mkdir -p $dir0 || error "creating dir $dir0"
13934
13935         local file=$dir0/file1
13936         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13937         local dv1=$($LFS data_version $file)
13938         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13939         local dv2=$($LFS data_version $file)
13940         [[ $dv1 != $dv2 ]] ||
13941                 error "data version did not change on write $dv1 == $dv2"
13942
13943         # clean up
13944         rm -f $file1
13945 }
13946 run_test 187a "Test data version change"
13947
13948 test_187b() {
13949         remote_mds_nodsh && skip "remote MDS with nodsh"
13950         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13951                 skip "Need MDS version at least 2.3.0"
13952
13953         local dir0=$DIR/$tdir/$testnum
13954         mkdir -p $dir0 || error "creating dir $dir0"
13955
13956         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13957         [[ ${DV[0]} != ${DV[1]} ]] ||
13958                 error "data version did not change on write"\
13959                       " ${DV[0]} == ${DV[1]}"
13960
13961         # clean up
13962         rm -f $file1
13963 }
13964 run_test 187b "Test data version change on volatile file"
13965
13966 test_200() {
13967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13968         remote_mgs_nodsh && skip "remote MGS with nodsh"
13969         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13970
13971         local POOL=${POOL:-cea1}
13972         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13973         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13974         # Pool OST targets
13975         local first_ost=0
13976         local last_ost=$(($OSTCOUNT - 1))
13977         local ost_step=2
13978         local ost_list=$(seq $first_ost $ost_step $last_ost)
13979         local ost_range="$first_ost $last_ost $ost_step"
13980         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13981         local file_dir=$POOL_ROOT/file_tst
13982         local subdir=$test_path/subdir
13983         local rc=0
13984
13985         if ! combined_mgs_mds ; then
13986                 mount_mgs_client
13987         fi
13988
13989         while : ; do
13990                 # former test_200a test_200b
13991                 pool_add $POOL                          || { rc=$? ; break; }
13992                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
13993                 # former test_200c test_200d
13994                 mkdir -p $test_path
13995                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
13996                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
13997                 mkdir -p $subdir
13998                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
13999                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14000                                                         || { rc=$? ; break; }
14001                 # former test_200e test_200f
14002                 local files=$((OSTCOUNT*3))
14003                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14004                                                         || { rc=$? ; break; }
14005                 pool_create_files $POOL $file_dir $files "$ost_list" \
14006                                                         || { rc=$? ; break; }
14007                 # former test_200g test_200h
14008                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14009                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14010
14011                 # former test_201a test_201b test_201c
14012                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14013
14014                 local f=$test_path/$tfile
14015                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14016                 pool_remove $POOL $f                    || { rc=$? ; break; }
14017                 break
14018         done
14019
14020         destroy_test_pools
14021
14022         if ! combined_mgs_mds ; then
14023                 umount_mgs_client
14024         fi
14025         return $rc
14026 }
14027 run_test 200 "OST pools"
14028
14029 # usage: default_attr <count | size | offset>
14030 default_attr() {
14031         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14032 }
14033
14034 # usage: check_default_stripe_attr
14035 check_default_stripe_attr() {
14036         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14037         case $1 in
14038         --stripe-count|-c)
14039                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14040         --stripe-size|-S)
14041                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14042         --stripe-index|-i)
14043                 EXPECTED=-1;;
14044         *)
14045                 error "unknown getstripe attr '$1'"
14046         esac
14047
14048         [ $ACTUAL == $EXPECTED ] ||
14049                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14050 }
14051
14052 test_204a() {
14053         test_mkdir $DIR/$tdir
14054         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14055
14056         check_default_stripe_attr --stripe-count
14057         check_default_stripe_attr --stripe-size
14058         check_default_stripe_attr --stripe-index
14059 }
14060 run_test 204a "Print default stripe attributes"
14061
14062 test_204b() {
14063         test_mkdir $DIR/$tdir
14064         $LFS setstripe --stripe-count 1 $DIR/$tdir
14065
14066         check_default_stripe_attr --stripe-size
14067         check_default_stripe_attr --stripe-index
14068 }
14069 run_test 204b "Print default stripe size and offset"
14070
14071 test_204c() {
14072         test_mkdir $DIR/$tdir
14073         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14074
14075         check_default_stripe_attr --stripe-count
14076         check_default_stripe_attr --stripe-index
14077 }
14078 run_test 204c "Print default stripe count and offset"
14079
14080 test_204d() {
14081         test_mkdir $DIR/$tdir
14082         $LFS setstripe --stripe-index 0 $DIR/$tdir
14083
14084         check_default_stripe_attr --stripe-count
14085         check_default_stripe_attr --stripe-size
14086 }
14087 run_test 204d "Print default stripe count and size"
14088
14089 test_204e() {
14090         test_mkdir $DIR/$tdir
14091         $LFS setstripe -d $DIR/$tdir
14092
14093         check_default_stripe_attr --stripe-count --raw
14094         check_default_stripe_attr --stripe-size --raw
14095         check_default_stripe_attr --stripe-index --raw
14096 }
14097 run_test 204e "Print raw stripe attributes"
14098
14099 test_204f() {
14100         test_mkdir $DIR/$tdir
14101         $LFS setstripe --stripe-count 1 $DIR/$tdir
14102
14103         check_default_stripe_attr --stripe-size --raw
14104         check_default_stripe_attr --stripe-index --raw
14105 }
14106 run_test 204f "Print raw stripe size and offset"
14107
14108 test_204g() {
14109         test_mkdir $DIR/$tdir
14110         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14111
14112         check_default_stripe_attr --stripe-count --raw
14113         check_default_stripe_attr --stripe-index --raw
14114 }
14115 run_test 204g "Print raw stripe count and offset"
14116
14117 test_204h() {
14118         test_mkdir $DIR/$tdir
14119         $LFS setstripe --stripe-index 0 $DIR/$tdir
14120
14121         check_default_stripe_attr --stripe-count --raw
14122         check_default_stripe_attr --stripe-size --raw
14123 }
14124 run_test 204h "Print raw stripe count and size"
14125
14126 # Figure out which job scheduler is being used, if any,
14127 # or use a fake one
14128 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14129         JOBENV=SLURM_JOB_ID
14130 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14131         JOBENV=LSB_JOBID
14132 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14133         JOBENV=PBS_JOBID
14134 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14135         JOBENV=LOADL_STEP_ID
14136 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14137         JOBENV=JOB_ID
14138 else
14139         $LCTL list_param jobid_name > /dev/null 2>&1
14140         if [ $? -eq 0 ]; then
14141                 JOBENV=nodelocal
14142         else
14143                 JOBENV=FAKE_JOBID
14144         fi
14145 fi
14146 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14147
14148 verify_jobstats() {
14149         local cmd=($1)
14150         shift
14151         local facets="$@"
14152
14153 # we don't really need to clear the stats for this test to work, since each
14154 # command has a unique jobid, but it makes debugging easier if needed.
14155 #       for facet in $facets; do
14156 #               local dev=$(convert_facet2label $facet)
14157 #               # clear old jobstats
14158 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14159 #       done
14160
14161         # use a new JobID for each test, or we might see an old one
14162         [ "$JOBENV" = "FAKE_JOBID" ] &&
14163                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14164
14165         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14166
14167         [ "$JOBENV" = "nodelocal" ] && {
14168                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14169                 $LCTL set_param jobid_name=$FAKE_JOBID
14170                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14171         }
14172
14173         log "Test: ${cmd[*]}"
14174         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14175
14176         if [ $JOBENV = "FAKE_JOBID" ]; then
14177                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14178         else
14179                 ${cmd[*]}
14180         fi
14181
14182         # all files are created on OST0000
14183         for facet in $facets; do
14184                 local stats="*.$(convert_facet2label $facet).job_stats"
14185
14186                 # strip out libtool wrappers for in-tree executables
14187                 if [ $(do_facet $facet lctl get_param $stats |
14188                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14189                         do_facet $facet lctl get_param $stats
14190                         error "No jobstats for $JOBVAL found on $facet::$stats"
14191                 fi
14192         done
14193 }
14194
14195 jobstats_set() {
14196         local new_jobenv=$1
14197
14198         set_persistent_param_and_check client "jobid_var" \
14199                 "$FSNAME.sys.jobid_var" $new_jobenv
14200 }
14201
14202 test_205() { # Job stats
14203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14204         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14205                 skip "Need MDS version with at least 2.7.1"
14206         remote_mgs_nodsh && skip "remote MGS with nodsh"
14207         remote_mds_nodsh && skip "remote MDS with nodsh"
14208         remote_ost_nodsh && skip "remote OST with nodsh"
14209         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14210                 skip "Server doesn't support jobstats"
14211         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14212
14213         local old_jobenv=$($LCTL get_param -n jobid_var)
14214         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14215
14216         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14217                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14218         else
14219                 stack_trap "do_facet mgs $PERM_CMD \
14220                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14221         fi
14222         changelog_register
14223
14224         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14225                                 mdt.*.job_cleanup_interval | head -n 1)
14226         local new_interval=5
14227         do_facet $SINGLEMDS \
14228                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14229         stack_trap "do_facet $SINGLEMDS \
14230                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14231         local start=$SECONDS
14232
14233         local cmd
14234         # mkdir
14235         cmd="mkdir $DIR/$tdir"
14236         verify_jobstats "$cmd" "$SINGLEMDS"
14237         # rmdir
14238         cmd="rmdir $DIR/$tdir"
14239         verify_jobstats "$cmd" "$SINGLEMDS"
14240         # mkdir on secondary MDT
14241         if [ $MDSCOUNT -gt 1 ]; then
14242                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14243                 verify_jobstats "$cmd" "mds2"
14244         fi
14245         # mknod
14246         cmd="mknod $DIR/$tfile c 1 3"
14247         verify_jobstats "$cmd" "$SINGLEMDS"
14248         # unlink
14249         cmd="rm -f $DIR/$tfile"
14250         verify_jobstats "$cmd" "$SINGLEMDS"
14251         # create all files on OST0000 so verify_jobstats can find OST stats
14252         # open & close
14253         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14254         verify_jobstats "$cmd" "$SINGLEMDS"
14255         # setattr
14256         cmd="touch $DIR/$tfile"
14257         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14258         # write
14259         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14260         verify_jobstats "$cmd" "ost1"
14261         # read
14262         cancel_lru_locks osc
14263         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14264         verify_jobstats "$cmd" "ost1"
14265         # truncate
14266         cmd="$TRUNCATE $DIR/$tfile 0"
14267         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14268         # rename
14269         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14270         verify_jobstats "$cmd" "$SINGLEMDS"
14271         # jobstats expiry - sleep until old stats should be expired
14272         local left=$((new_interval + 5 - (SECONDS - start)))
14273         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14274                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14275                         "0" $left
14276         cmd="mkdir $DIR/$tdir.expire"
14277         verify_jobstats "$cmd" "$SINGLEMDS"
14278         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14279             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14280
14281         # Ensure that jobid are present in changelog (if supported by MDS)
14282         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14283                 changelog_dump | tail -10
14284                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14285                 [ $jobids -eq 9 ] ||
14286                         error "Wrong changelog jobid count $jobids != 9"
14287
14288                 # LU-5862
14289                 JOBENV="disable"
14290                 jobstats_set $JOBENV
14291                 touch $DIR/$tfile
14292                 changelog_dump | grep $tfile
14293                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14294                 [ $jobids -eq 0 ] ||
14295                         error "Unexpected jobids when jobid_var=$JOBENV"
14296         fi
14297
14298         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14299         JOBENV="JOBCOMPLEX"
14300         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14301
14302         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14303 }
14304 run_test 205 "Verify job stats"
14305
14306 # LU-1480, LU-1773 and LU-1657
14307 test_206() {
14308         mkdir -p $DIR/$tdir
14309         $LFS setstripe -c -1 $DIR/$tdir
14310 #define OBD_FAIL_LOV_INIT 0x1403
14311         $LCTL set_param fail_loc=0xa0001403
14312         $LCTL set_param fail_val=1
14313         touch $DIR/$tdir/$tfile || true
14314 }
14315 run_test 206 "fail lov_init_raid0() doesn't lbug"
14316
14317 test_207a() {
14318         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14319         local fsz=`stat -c %s $DIR/$tfile`
14320         cancel_lru_locks mdc
14321
14322         # do not return layout in getattr intent
14323 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14324         $LCTL set_param fail_loc=0x170
14325         local sz=`stat -c %s $DIR/$tfile`
14326
14327         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14328
14329         rm -rf $DIR/$tfile
14330 }
14331 run_test 207a "can refresh layout at glimpse"
14332
14333 test_207b() {
14334         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14335         local cksum=`md5sum $DIR/$tfile`
14336         local fsz=`stat -c %s $DIR/$tfile`
14337         cancel_lru_locks mdc
14338         cancel_lru_locks osc
14339
14340         # do not return layout in getattr intent
14341 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14342         $LCTL set_param fail_loc=0x171
14343
14344         # it will refresh layout after the file is opened but before read issues
14345         echo checksum is "$cksum"
14346         echo "$cksum" |md5sum -c --quiet || error "file differs"
14347
14348         rm -rf $DIR/$tfile
14349 }
14350 run_test 207b "can refresh layout at open"
14351
14352 test_208() {
14353         # FIXME: in this test suite, only RD lease is used. This is okay
14354         # for now as only exclusive open is supported. After generic lease
14355         # is done, this test suite should be revised. - Jinshan
14356
14357         remote_mds_nodsh && skip "remote MDS with nodsh"
14358         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14359                 skip "Need MDS version at least 2.4.52"
14360
14361         echo "==== test 1: verify get lease work"
14362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14363
14364         echo "==== test 2: verify lease can be broken by upcoming open"
14365         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14366         local PID=$!
14367         sleep 1
14368
14369         $MULTIOP $DIR/$tfile oO_RDONLY:c
14370         kill -USR1 $PID && wait $PID || error "break lease error"
14371
14372         echo "==== test 3: verify lease can't be granted if an open already exists"
14373         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14374         local PID=$!
14375         sleep 1
14376
14377         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14378         kill -USR1 $PID && wait $PID || error "open file error"
14379
14380         echo "==== test 4: lease can sustain over recovery"
14381         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14382         PID=$!
14383         sleep 1
14384
14385         fail mds1
14386
14387         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14388
14389         echo "==== test 5: lease broken can't be regained by replay"
14390         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14391         PID=$!
14392         sleep 1
14393
14394         # open file to break lease and then recovery
14395         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14396         fail mds1
14397
14398         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14399
14400         rm -f $DIR/$tfile
14401 }
14402 run_test 208 "Exclusive open"
14403
14404 test_209() {
14405         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14406                 skip_env "must have disp_stripe"
14407
14408         touch $DIR/$tfile
14409         sync; sleep 5; sync;
14410
14411         echo 3 > /proc/sys/vm/drop_caches
14412         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14413
14414         # open/close 500 times
14415         for i in $(seq 500); do
14416                 cat $DIR/$tfile
14417         done
14418
14419         echo 3 > /proc/sys/vm/drop_caches
14420         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14421
14422         echo "before: $req_before, after: $req_after"
14423         [ $((req_after - req_before)) -ge 300 ] &&
14424                 error "open/close requests are not freed"
14425         return 0
14426 }
14427 run_test 209 "read-only open/close requests should be freed promptly"
14428
14429 test_212() {
14430         size=`date +%s`
14431         size=$((size % 8192 + 1))
14432         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14433         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14434         rm -f $DIR/f212 $DIR/f212.xyz
14435 }
14436 run_test 212 "Sendfile test ============================================"
14437
14438 test_213() {
14439         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14440         cancel_lru_locks osc
14441         lctl set_param fail_loc=0x8000040f
14442         # generate a read lock
14443         cat $DIR/$tfile > /dev/null
14444         # write to the file, it will try to cancel the above read lock.
14445         cat /etc/hosts >> $DIR/$tfile
14446 }
14447 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14448
14449 test_214() { # for bug 20133
14450         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14451         for (( i=0; i < 340; i++ )) ; do
14452                 touch $DIR/$tdir/d214c/a$i
14453         done
14454
14455         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14456         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14457         ls $DIR/d214c || error "ls $DIR/d214c failed"
14458         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14459         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14460 }
14461 run_test 214 "hash-indexed directory test - bug 20133"
14462
14463 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14464 create_lnet_proc_files() {
14465         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14466 }
14467
14468 # counterpart of create_lnet_proc_files
14469 remove_lnet_proc_files() {
14470         rm -f $TMP/lnet_$1.sys
14471 }
14472
14473 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14474 # 3rd arg as regexp for body
14475 check_lnet_proc_stats() {
14476         local l=$(cat "$TMP/lnet_$1" |wc -l)
14477         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14478
14479         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14480 }
14481
14482 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14483 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14484 # optional and can be regexp for 2nd line (lnet.routes case)
14485 check_lnet_proc_entry() {
14486         local blp=2          # blp stands for 'position of 1st line of body'
14487         [ -z "$5" ] || blp=3 # lnet.routes case
14488
14489         local l=$(cat "$TMP/lnet_$1" |wc -l)
14490         # subtracting one from $blp because the body can be empty
14491         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14492
14493         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14494                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14495
14496         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14497                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14498
14499         # bail out if any unexpected line happened
14500         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14501         [ "$?" != 0 ] || error "$2 misformatted"
14502 }
14503
14504 test_215() { # for bugs 18102, 21079, 21517
14505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14506
14507         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14508         local P='[1-9][0-9]*'           # positive numeric
14509         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14510         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14511         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14512         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14513
14514         local L1 # regexp for 1st line
14515         local L2 # regexp for 2nd line (optional)
14516         local BR # regexp for the rest (body)
14517
14518         # lnet.stats should look as 11 space-separated non-negative numerics
14519         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14520         create_lnet_proc_files "stats"
14521         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14522         remove_lnet_proc_files "stats"
14523
14524         # lnet.routes should look like this:
14525         # Routing disabled/enabled
14526         # net hops priority state router
14527         # where net is a string like tcp0, hops > 0, priority >= 0,
14528         # state is up/down,
14529         # router is a string like 192.168.1.1@tcp2
14530         L1="^Routing (disabled|enabled)$"
14531         L2="^net +hops +priority +state +router$"
14532         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14533         create_lnet_proc_files "routes"
14534         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14535         remove_lnet_proc_files "routes"
14536
14537         # lnet.routers should look like this:
14538         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14539         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14540         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14541         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14542         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14543         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14544         create_lnet_proc_files "routers"
14545         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14546         remove_lnet_proc_files "routers"
14547
14548         # lnet.peers should look like this:
14549         # nid refs state last max rtr min tx min queue
14550         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14551         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14552         # numeric (0 or >0 or <0), queue >= 0.
14553         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14554         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14555         create_lnet_proc_files "peers"
14556         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14557         remove_lnet_proc_files "peers"
14558
14559         # lnet.buffers  should look like this:
14560         # pages count credits min
14561         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14562         L1="^pages +count +credits +min$"
14563         BR="^ +$N +$N +$I +$I$"
14564         create_lnet_proc_files "buffers"
14565         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14566         remove_lnet_proc_files "buffers"
14567
14568         # lnet.nis should look like this:
14569         # nid status alive refs peer rtr max tx min
14570         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14571         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14572         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14573         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14574         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14575         create_lnet_proc_files "nis"
14576         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14577         remove_lnet_proc_files "nis"
14578
14579         # can we successfully write to lnet.stats?
14580         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14581 }
14582 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14583
14584 test_216() { # bug 20317
14585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14586         remote_ost_nodsh && skip "remote OST with nodsh"
14587
14588         local node
14589         local facets=$(get_facets OST)
14590         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14591
14592         save_lustre_params client "osc.*.contention_seconds" > $p
14593         save_lustre_params $facets \
14594                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14595         save_lustre_params $facets \
14596                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14597         save_lustre_params $facets \
14598                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14599         clear_stats osc.*.osc_stats
14600
14601         # agressive lockless i/o settings
14602         do_nodes $(comma_list $(osts_nodes)) \
14603                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14604                         ldlm.namespaces.filter-*.contended_locks=0 \
14605                         ldlm.namespaces.filter-*.contention_seconds=60"
14606         lctl set_param -n osc.*.contention_seconds=60
14607
14608         $DIRECTIO write $DIR/$tfile 0 10 4096
14609         $CHECKSTAT -s 40960 $DIR/$tfile
14610
14611         # disable lockless i/o
14612         do_nodes $(comma_list $(osts_nodes)) \
14613                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14614                         ldlm.namespaces.filter-*.contended_locks=32 \
14615                         ldlm.namespaces.filter-*.contention_seconds=0"
14616         lctl set_param -n osc.*.contention_seconds=0
14617         clear_stats osc.*.osc_stats
14618
14619         dd if=/dev/zero of=$DIR/$tfile count=0
14620         $CHECKSTAT -s 0 $DIR/$tfile
14621
14622         restore_lustre_params <$p
14623         rm -f $p
14624         rm $DIR/$tfile
14625 }
14626 run_test 216 "check lockless direct write updates file size and kms correctly"
14627
14628 test_217() { # bug 22430
14629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14630
14631         local node
14632         local nid
14633
14634         for node in $(nodes_list); do
14635                 nid=$(host_nids_address $node $NETTYPE)
14636                 if [[ $nid = *-* ]] ; then
14637                         echo "lctl ping $(h2nettype $nid)"
14638                         lctl ping $(h2nettype $nid)
14639                 else
14640                         echo "skipping $node (no hyphen detected)"
14641                 fi
14642         done
14643 }
14644 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14645
14646 test_218() {
14647        # do directio so as not to populate the page cache
14648        log "creating a 10 Mb file"
14649        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14650        log "starting reads"
14651        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14652        log "truncating the file"
14653        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14654        log "killing dd"
14655        kill %+ || true # reads might have finished
14656        echo "wait until dd is finished"
14657        wait
14658        log "removing the temporary file"
14659        rm -rf $DIR/$tfile || error "tmp file removal failed"
14660 }
14661 run_test 218 "parallel read and truncate should not deadlock"
14662
14663 test_219() {
14664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14665
14666         # write one partial page
14667         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14668         # set no grant so vvp_io_commit_write will do sync write
14669         $LCTL set_param fail_loc=0x411
14670         # write a full page at the end of file
14671         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14672
14673         $LCTL set_param fail_loc=0
14674         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14675         $LCTL set_param fail_loc=0x411
14676         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14677
14678         # LU-4201
14679         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14680         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14681 }
14682 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14683
14684 test_220() { #LU-325
14685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14686         remote_ost_nodsh && skip "remote OST with nodsh"
14687         remote_mds_nodsh && skip "remote MDS with nodsh"
14688         remote_mgs_nodsh && skip "remote MGS with nodsh"
14689
14690         local OSTIDX=0
14691
14692         # create on MDT0000 so the last_id and next_id are correct
14693         mkdir $DIR/$tdir
14694         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14695         OST=${OST%_UUID}
14696
14697         # on the mdt's osc
14698         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14699         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14700                         osc.$mdtosc_proc1.prealloc_last_id)
14701         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14702                         osc.$mdtosc_proc1.prealloc_next_id)
14703
14704         $LFS df -i
14705
14706         if ! combined_mgs_mds ; then
14707                 mount_mgs_client
14708         fi
14709
14710         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14711         #define OBD_FAIL_OST_ENOINO              0x229
14712         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14713         create_pool $FSNAME.$TESTNAME || return 1
14714         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14715
14716         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14717
14718         MDSOBJS=$((last_id - next_id))
14719         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14720
14721         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14722         echo "OST still has $count kbytes free"
14723
14724         echo "create $MDSOBJS files @next_id..."
14725         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14726
14727         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14728                         osc.$mdtosc_proc1.prealloc_last_id)
14729         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14730                         osc.$mdtosc_proc1.prealloc_next_id)
14731
14732         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14733         $LFS df -i
14734
14735         echo "cleanup..."
14736
14737         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14738         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14739
14740         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14741                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14742         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14743                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14744         echo "unlink $MDSOBJS files @$next_id..."
14745         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14746
14747         if ! combined_mgs_mds ; then
14748                 umount_mgs_client
14749         fi
14750 }
14751 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14752
14753 test_221() {
14754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14755
14756         dd if=`which date` of=$MOUNT/date oflag=sync
14757         chmod +x $MOUNT/date
14758
14759         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14760         $LCTL set_param fail_loc=0x80001401
14761
14762         $MOUNT/date > /dev/null
14763         rm -f $MOUNT/date
14764 }
14765 run_test 221 "make sure fault and truncate race to not cause OOM"
14766
14767 test_222a () {
14768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14769
14770         rm -rf $DIR/$tdir
14771         test_mkdir $DIR/$tdir
14772         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14773         createmany -o $DIR/$tdir/$tfile 10
14774         cancel_lru_locks mdc
14775         cancel_lru_locks osc
14776         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14777         $LCTL set_param fail_loc=0x31a
14778         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14779         $LCTL set_param fail_loc=0
14780         rm -r $DIR/$tdir
14781 }
14782 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14783
14784 test_222b () {
14785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14786
14787         rm -rf $DIR/$tdir
14788         test_mkdir $DIR/$tdir
14789         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14790         createmany -o $DIR/$tdir/$tfile 10
14791         cancel_lru_locks mdc
14792         cancel_lru_locks osc
14793         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14794         $LCTL set_param fail_loc=0x31a
14795         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14796         $LCTL set_param fail_loc=0
14797 }
14798 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14799
14800 test_223 () {
14801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14802
14803         rm -rf $DIR/$tdir
14804         test_mkdir $DIR/$tdir
14805         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14806         createmany -o $DIR/$tdir/$tfile 10
14807         cancel_lru_locks mdc
14808         cancel_lru_locks osc
14809         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14810         $LCTL set_param fail_loc=0x31b
14811         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14812         $LCTL set_param fail_loc=0
14813         rm -r $DIR/$tdir
14814 }
14815 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14816
14817 test_224a() { # LU-1039, MRP-303
14818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14819
14820         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14821         $LCTL set_param fail_loc=0x508
14822         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14823         $LCTL set_param fail_loc=0
14824         df $DIR
14825 }
14826 run_test 224a "Don't panic on bulk IO failure"
14827
14828 test_224b() { # LU-1039, MRP-303
14829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14830
14831         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14832         cancel_lru_locks osc
14833         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14834         $LCTL set_param fail_loc=0x515
14835         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14836         $LCTL set_param fail_loc=0
14837         df $DIR
14838 }
14839 run_test 224b "Don't panic on bulk IO failure"
14840
14841 test_224c() { # LU-6441
14842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14843         remote_mds_nodsh && skip "remote MDS with nodsh"
14844
14845         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14846         save_writethrough $p
14847         set_cache writethrough on
14848
14849         local pages_per_rpc=$($LCTL get_param \
14850                                 osc.*.max_pages_per_rpc)
14851         local at_max=$($LCTL get_param -n at_max)
14852         local timeout=$($LCTL get_param -n timeout)
14853         local test_at="at_max"
14854         local param_at="$FSNAME.sys.at_max"
14855         local test_timeout="timeout"
14856         local param_timeout="$FSNAME.sys.timeout"
14857
14858         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14859
14860         set_persistent_param_and_check client "$test_at" "$param_at" 0
14861         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14862
14863         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14864         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14865         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14866         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14867         sync
14868         do_facet ost1 "$LCTL set_param fail_loc=0"
14869
14870         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14871         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14872                 $timeout
14873
14874         $LCTL set_param -n $pages_per_rpc
14875         restore_lustre_params < $p
14876         rm -f $p
14877 }
14878 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14879
14880 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14881 test_225a () {
14882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14883         if [ -z ${MDSSURVEY} ]; then
14884                 skip_env "mds-survey not found"
14885         fi
14886         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14887                 skip "Need MDS version at least 2.2.51"
14888
14889         local mds=$(facet_host $SINGLEMDS)
14890         local target=$(do_nodes $mds 'lctl dl' |
14891                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14892
14893         local cmd1="file_count=1000 thrhi=4"
14894         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14895         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14896         local cmd="$cmd1 $cmd2 $cmd3"
14897
14898         rm -f ${TMP}/mds_survey*
14899         echo + $cmd
14900         eval $cmd || error "mds-survey with zero-stripe failed"
14901         cat ${TMP}/mds_survey*
14902         rm -f ${TMP}/mds_survey*
14903 }
14904 run_test 225a "Metadata survey sanity with zero-stripe"
14905
14906 test_225b () {
14907         if [ -z ${MDSSURVEY} ]; then
14908                 skip_env "mds-survey not found"
14909         fi
14910         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14911                 skip "Need MDS version at least 2.2.51"
14912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14913         remote_mds_nodsh && skip "remote MDS with nodsh"
14914         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14915                 skip_env "Need to mount OST to test"
14916         fi
14917
14918         local mds=$(facet_host $SINGLEMDS)
14919         local target=$(do_nodes $mds 'lctl dl' |
14920                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14921
14922         local cmd1="file_count=1000 thrhi=4"
14923         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14924         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14925         local cmd="$cmd1 $cmd2 $cmd3"
14926
14927         rm -f ${TMP}/mds_survey*
14928         echo + $cmd
14929         eval $cmd || error "mds-survey with stripe_count failed"
14930         cat ${TMP}/mds_survey*
14931         rm -f ${TMP}/mds_survey*
14932 }
14933 run_test 225b "Metadata survey sanity with stripe_count = 1"
14934
14935 mcreate_path2fid () {
14936         local mode=$1
14937         local major=$2
14938         local minor=$3
14939         local name=$4
14940         local desc=$5
14941         local path=$DIR/$tdir/$name
14942         local fid
14943         local rc
14944         local fid_path
14945
14946         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14947                 error "cannot create $desc"
14948
14949         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14950         rc=$?
14951         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14952
14953         fid_path=$($LFS fid2path $MOUNT $fid)
14954         rc=$?
14955         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14956
14957         [ "$path" == "$fid_path" ] ||
14958                 error "fid2path returned $fid_path, expected $path"
14959
14960         echo "pass with $path and $fid"
14961 }
14962
14963 test_226a () {
14964         rm -rf $DIR/$tdir
14965         mkdir -p $DIR/$tdir
14966
14967         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14968         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14969         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14970         mcreate_path2fid 0040666 0 0 dir "directory"
14971         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14972         mcreate_path2fid 0100666 0 0 file "regular file"
14973         mcreate_path2fid 0120666 0 0 link "symbolic link"
14974         mcreate_path2fid 0140666 0 0 sock "socket"
14975 }
14976 run_test 226a "call path2fid and fid2path on files of all type"
14977
14978 test_226b () {
14979         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14980
14981         local MDTIDX=1
14982
14983         rm -rf $DIR/$tdir
14984         mkdir -p $DIR/$tdir
14985         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
14986                 error "create remote directory failed"
14987         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
14988         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
14989                                 "character special file (null)"
14990         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
14991                                 "character special file (no device)"
14992         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
14993         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
14994                                 "block special file (loop)"
14995         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
14996         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
14997         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
14998 }
14999 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15000
15001 # LU-1299 Executing or running ldd on a truncated executable does not
15002 # cause an out-of-memory condition.
15003 test_227() {
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15006
15007         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15008         chmod +x $MOUNT/date
15009
15010         $MOUNT/date > /dev/null
15011         ldd $MOUNT/date > /dev/null
15012         rm -f $MOUNT/date
15013 }
15014 run_test 227 "running truncated executable does not cause OOM"
15015
15016 # LU-1512 try to reuse idle OI blocks
15017 test_228a() {
15018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15019         remote_mds_nodsh && skip "remote MDS with nodsh"
15020         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15021
15022         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15023         local myDIR=$DIR/$tdir
15024
15025         mkdir -p $myDIR
15026         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15027         $LCTL set_param fail_loc=0x80001002
15028         createmany -o $myDIR/t- 10000
15029         $LCTL set_param fail_loc=0
15030         # The guard is current the largest FID holder
15031         touch $myDIR/guard
15032         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15033                     tr -d '[')
15034         local IDX=$(($SEQ % 64))
15035
15036         do_facet $SINGLEMDS sync
15037         # Make sure journal flushed.
15038         sleep 6
15039         local blk1=$(do_facet $SINGLEMDS \
15040                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15041                      grep Blockcount | awk '{print $4}')
15042
15043         # Remove old files, some OI blocks will become idle.
15044         unlinkmany $myDIR/t- 10000
15045         # Create new files, idle OI blocks should be reused.
15046         createmany -o $myDIR/t- 2000
15047         do_facet $SINGLEMDS sync
15048         # Make sure journal flushed.
15049         sleep 6
15050         local blk2=$(do_facet $SINGLEMDS \
15051                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15052                      grep Blockcount | awk '{print $4}')
15053
15054         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15055 }
15056 run_test 228a "try to reuse idle OI blocks"
15057
15058 test_228b() {
15059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15060         remote_mds_nodsh && skip "remote MDS with nodsh"
15061         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15062
15063         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15064         local myDIR=$DIR/$tdir
15065
15066         mkdir -p $myDIR
15067         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15068         $LCTL set_param fail_loc=0x80001002
15069         createmany -o $myDIR/t- 10000
15070         $LCTL set_param fail_loc=0
15071         # The guard is current the largest FID holder
15072         touch $myDIR/guard
15073         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15074                     tr -d '[')
15075         local IDX=$(($SEQ % 64))
15076
15077         do_facet $SINGLEMDS sync
15078         # Make sure journal flushed.
15079         sleep 6
15080         local blk1=$(do_facet $SINGLEMDS \
15081                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15082                      grep Blockcount | awk '{print $4}')
15083
15084         # Remove old files, some OI blocks will become idle.
15085         unlinkmany $myDIR/t- 10000
15086
15087         # stop the MDT
15088         stop $SINGLEMDS || error "Fail to stop MDT."
15089         # remount the MDT
15090         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15091
15092         df $MOUNT || error "Fail to df."
15093         # Create new files, idle OI blocks should be reused.
15094         createmany -o $myDIR/t- 2000
15095         do_facet $SINGLEMDS sync
15096         # Make sure journal flushed.
15097         sleep 6
15098         local blk2=$(do_facet $SINGLEMDS \
15099                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15100                      grep Blockcount | awk '{print $4}')
15101
15102         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15103 }
15104 run_test 228b "idle OI blocks can be reused after MDT restart"
15105
15106 #LU-1881
15107 test_228c() {
15108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15109         remote_mds_nodsh && skip "remote MDS with nodsh"
15110         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15111
15112         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15113         local myDIR=$DIR/$tdir
15114
15115         mkdir -p $myDIR
15116         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15117         $LCTL set_param fail_loc=0x80001002
15118         # 20000 files can guarantee there are index nodes in the OI file
15119         createmany -o $myDIR/t- 20000
15120         $LCTL set_param fail_loc=0
15121         # The guard is current the largest FID holder
15122         touch $myDIR/guard
15123         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15124                     tr -d '[')
15125         local IDX=$(($SEQ % 64))
15126
15127         do_facet $SINGLEMDS sync
15128         # Make sure journal flushed.
15129         sleep 6
15130         local blk1=$(do_facet $SINGLEMDS \
15131                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15132                      grep Blockcount | awk '{print $4}')
15133
15134         # Remove old files, some OI blocks will become idle.
15135         unlinkmany $myDIR/t- 20000
15136         rm -f $myDIR/guard
15137         # The OI file should become empty now
15138
15139         # Create new files, idle OI blocks should be reused.
15140         createmany -o $myDIR/t- 2000
15141         do_facet $SINGLEMDS sync
15142         # Make sure journal flushed.
15143         sleep 6
15144         local blk2=$(do_facet $SINGLEMDS \
15145                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15146                      grep Blockcount | awk '{print $4}')
15147
15148         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15149 }
15150 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15151
15152 test_229() { # LU-2482, LU-3448
15153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15154         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15155         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15156                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15157
15158         rm -f $DIR/$tfile
15159
15160         # Create a file with a released layout and stripe count 2.
15161         $MULTIOP $DIR/$tfile H2c ||
15162                 error "failed to create file with released layout"
15163
15164         $LFS getstripe -v $DIR/$tfile
15165
15166         local pattern=$($LFS getstripe -L $DIR/$tfile)
15167         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15168
15169         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15170                 error "getstripe"
15171         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15172         stat $DIR/$tfile || error "failed to stat released file"
15173
15174         chown $RUNAS_ID $DIR/$tfile ||
15175                 error "chown $RUNAS_ID $DIR/$tfile failed"
15176
15177         chgrp $RUNAS_ID $DIR/$tfile ||
15178                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15179
15180         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15181         rm $DIR/$tfile || error "failed to remove released file"
15182 }
15183 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15184
15185 test_230a() {
15186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15187         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15188         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15189                 skip "Need MDS version at least 2.11.52"
15190
15191         local MDTIDX=1
15192
15193         test_mkdir $DIR/$tdir
15194         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15195         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15196         [ $mdt_idx -ne 0 ] &&
15197                 error "create local directory on wrong MDT $mdt_idx"
15198
15199         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15200                         error "create remote directory failed"
15201         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15202         [ $mdt_idx -ne $MDTIDX ] &&
15203                 error "create remote directory on wrong MDT $mdt_idx"
15204
15205         createmany -o $DIR/$tdir/test_230/t- 10 ||
15206                 error "create files on remote directory failed"
15207         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15208         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15209         rm -r $DIR/$tdir || error "unlink remote directory failed"
15210 }
15211 run_test 230a "Create remote directory and files under the remote directory"
15212
15213 test_230b() {
15214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15216         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15217                 skip "Need MDS version at least 2.11.52"
15218
15219         local MDTIDX=1
15220         local mdt_index
15221         local i
15222         local file
15223         local pid
15224         local stripe_count
15225         local migrate_dir=$DIR/$tdir/migrate_dir
15226         local other_dir=$DIR/$tdir/other_dir
15227
15228         test_mkdir $DIR/$tdir
15229         test_mkdir -i0 -c1 $migrate_dir
15230         test_mkdir -i0 -c1 $other_dir
15231         for ((i=0; i<10; i++)); do
15232                 mkdir -p $migrate_dir/dir_${i}
15233                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15234                         error "create files under remote dir failed $i"
15235         done
15236
15237         cp /etc/passwd $migrate_dir/$tfile
15238         cp /etc/passwd $other_dir/$tfile
15239         chattr +SAD $migrate_dir
15240         chattr +SAD $migrate_dir/$tfile
15241
15242         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15243         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15244         local old_dir_mode=$(stat -c%f $migrate_dir)
15245         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15246
15247         mkdir -p $migrate_dir/dir_default_stripe2
15248         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15249         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15250
15251         mkdir -p $other_dir
15252         ln $migrate_dir/$tfile $other_dir/luna
15253         ln $migrate_dir/$tfile $migrate_dir/sofia
15254         ln $other_dir/$tfile $migrate_dir/david
15255         ln -s $migrate_dir/$tfile $other_dir/zachary
15256         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15257         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15258
15259         $LFS migrate -m $MDTIDX $migrate_dir ||
15260                 error "fails on migrating remote dir to MDT1"
15261
15262         echo "migratate to MDT1, then checking.."
15263         for ((i = 0; i < 10; i++)); do
15264                 for file in $(find $migrate_dir/dir_${i}); do
15265                         mdt_index=$($LFS getstripe -m $file)
15266                         [ $mdt_index == $MDTIDX ] ||
15267                                 error "$file is not on MDT${MDTIDX}"
15268                 done
15269         done
15270
15271         # the multiple link file should still in MDT0
15272         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15273         [ $mdt_index == 0 ] ||
15274                 error "$file is not on MDT${MDTIDX}"
15275
15276         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15277         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15278                 error " expect $old_dir_flag get $new_dir_flag"
15279
15280         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15281         [ "$old_file_flag" = "$new_file_flag" ] ||
15282                 error " expect $old_file_flag get $new_file_flag"
15283
15284         local new_dir_mode=$(stat -c%f $migrate_dir)
15285         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15286                 error "expect mode $old_dir_mode get $new_dir_mode"
15287
15288         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15289         [ "$old_file_mode" = "$new_file_mode" ] ||
15290                 error "expect mode $old_file_mode get $new_file_mode"
15291
15292         diff /etc/passwd $migrate_dir/$tfile ||
15293                 error "$tfile different after migration"
15294
15295         diff /etc/passwd $other_dir/luna ||
15296                 error "luna different after migration"
15297
15298         diff /etc/passwd $migrate_dir/sofia ||
15299                 error "sofia different after migration"
15300
15301         diff /etc/passwd $migrate_dir/david ||
15302                 error "david different after migration"
15303
15304         diff /etc/passwd $other_dir/zachary ||
15305                 error "zachary different after migration"
15306
15307         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15308                 error "${tfile}_ln different after migration"
15309
15310         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15311                 error "${tfile}_ln_other different after migration"
15312
15313         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15314         [ $stripe_count = 2 ] ||
15315                 error "dir strpe_count $d != 2 after migration."
15316
15317         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15318         [ $stripe_count = 2 ] ||
15319                 error "file strpe_count $d != 2 after migration."
15320
15321         #migrate back to MDT0
15322         MDTIDX=0
15323
15324         $LFS migrate -m $MDTIDX $migrate_dir ||
15325                 error "fails on migrating remote dir to MDT0"
15326
15327         echo "migrate back to MDT0, checking.."
15328         for file in $(find $migrate_dir); do
15329                 mdt_index=$($LFS getstripe -m $file)
15330                 [ $mdt_index == $MDTIDX ] ||
15331                         error "$file is not on MDT${MDTIDX}"
15332         done
15333
15334         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15335         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15336                 error " expect $old_dir_flag get $new_dir_flag"
15337
15338         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15339         [ "$old_file_flag" = "$new_file_flag" ] ||
15340                 error " expect $old_file_flag get $new_file_flag"
15341
15342         local new_dir_mode=$(stat -c%f $migrate_dir)
15343         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15344                 error "expect mode $old_dir_mode get $new_dir_mode"
15345
15346         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15347         [ "$old_file_mode" = "$new_file_mode" ] ||
15348                 error "expect mode $old_file_mode get $new_file_mode"
15349
15350         diff /etc/passwd ${migrate_dir}/$tfile ||
15351                 error "$tfile different after migration"
15352
15353         diff /etc/passwd ${other_dir}/luna ||
15354                 error "luna different after migration"
15355
15356         diff /etc/passwd ${migrate_dir}/sofia ||
15357                 error "sofia different after migration"
15358
15359         diff /etc/passwd ${other_dir}/zachary ||
15360                 error "zachary different after migration"
15361
15362         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15363                 error "${tfile}_ln different after migration"
15364
15365         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15366                 error "${tfile}_ln_other different after migration"
15367
15368         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15369         [ $stripe_count = 2 ] ||
15370                 error "dir strpe_count $d != 2 after migration."
15371
15372         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15373         [ $stripe_count = 2 ] ||
15374                 error "file strpe_count $d != 2 after migration."
15375
15376         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15377 }
15378 run_test 230b "migrate directory"
15379
15380 test_230c() {
15381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15383         remote_mds_nodsh && skip "remote MDS with nodsh"
15384         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15385                 skip "Need MDS version at least 2.11.52"
15386
15387         local MDTIDX=1
15388         local total=3
15389         local mdt_index
15390         local file
15391         local migrate_dir=$DIR/$tdir/migrate_dir
15392
15393         #If migrating directory fails in the middle, all entries of
15394         #the directory is still accessiable.
15395         test_mkdir $DIR/$tdir
15396         test_mkdir -i0 -c1 $migrate_dir
15397         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15398         stat $migrate_dir
15399         createmany -o $migrate_dir/f $total ||
15400                 error "create files under ${migrate_dir} failed"
15401
15402         # fail after migrating top dir, and this will fail only once, so the
15403         # first sub file migration will fail (currently f3), others succeed.
15404         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15405         do_facet mds1 lctl set_param fail_loc=0x1801
15406         local t=$(ls $migrate_dir | wc -l)
15407         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15408                 error "migrate should fail"
15409         local u=$(ls $migrate_dir | wc -l)
15410         [ "$u" == "$t" ] || error "$u != $t during migration"
15411
15412         # add new dir/file should succeed
15413         mkdir $migrate_dir/dir ||
15414                 error "mkdir failed under migrating directory"
15415         touch $migrate_dir/file ||
15416                 error "create file failed under migrating directory"
15417
15418         # add file with existing name should fail
15419         for file in $migrate_dir/f*; do
15420                 stat $file > /dev/null || error "stat $file failed"
15421                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15422                         error "open(O_CREAT|O_EXCL) $file should fail"
15423                 $MULTIOP $file m && error "create $file should fail"
15424                 touch $DIR/$tdir/remote_dir/$tfile ||
15425                         error "touch $tfile failed"
15426                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15427                         error "link $file should fail"
15428                 mdt_index=$($LFS getstripe -m $file)
15429                 if [ $mdt_index == 0 ]; then
15430                         # file failed to migrate is not allowed to rename to
15431                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15432                                 error "rename to $file should fail"
15433                 else
15434                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15435                                 error "rename to $file failed"
15436                 fi
15437                 echo hello >> $file || error "write $file failed"
15438         done
15439
15440         # resume migration with different options should fail
15441         $LFS migrate -m 0 $migrate_dir &&
15442                 error "migrate -m 0 $migrate_dir should fail"
15443
15444         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15445                 error "migrate -c 2 $migrate_dir should fail"
15446
15447         # resume migration should succeed
15448         $LFS migrate -m $MDTIDX $migrate_dir ||
15449                 error "migrate $migrate_dir failed"
15450
15451         echo "Finish migration, then checking.."
15452         for file in $(find $migrate_dir); do
15453                 mdt_index=$($LFS getstripe -m $file)
15454                 [ $mdt_index == $MDTIDX ] ||
15455                         error "$file is not on MDT${MDTIDX}"
15456         done
15457
15458         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15459 }
15460 run_test 230c "check directory accessiblity if migration failed"
15461
15462 test_230d() {
15463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15465         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15466                 skip "Need MDS version at least 2.11.52"
15467         # LU-11235
15468         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15469
15470         local migrate_dir=$DIR/$tdir/migrate_dir
15471         local old_index
15472         local new_index
15473         local old_count
15474         local new_count
15475         local new_hash
15476         local mdt_index
15477         local i
15478         local j
15479
15480         old_index=$((RANDOM % MDSCOUNT))
15481         old_count=$((MDSCOUNT - old_index))
15482         new_index=$((RANDOM % MDSCOUNT))
15483         new_count=$((MDSCOUNT - new_index))
15484         new_hash="all_char"
15485
15486         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15487         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15488
15489         test_mkdir $DIR/$tdir
15490         test_mkdir -i $old_index -c $old_count $migrate_dir
15491
15492         for ((i=0; i<100; i++)); do
15493                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15494                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15495                         error "create files under remote dir failed $i"
15496         done
15497
15498         echo -n "Migrate from MDT$old_index "
15499         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15500         echo -n "to MDT$new_index"
15501         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15502         echo
15503
15504         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15505         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15506                 error "migrate remote dir error"
15507
15508         echo "Finish migration, then checking.."
15509         for file in $(find $migrate_dir); do
15510                 mdt_index=$($LFS getstripe -m $file)
15511                 if [ $mdt_index -lt $new_index ] ||
15512                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15513                         error "$file is on MDT$mdt_index"
15514                 fi
15515         done
15516
15517         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15518 }
15519 run_test 230d "check migrate big directory"
15520
15521 test_230e() {
15522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15524         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15525                 skip "Need MDS version at least 2.11.52"
15526
15527         local i
15528         local j
15529         local a_fid
15530         local b_fid
15531
15532         mkdir -p $DIR/$tdir
15533         mkdir $DIR/$tdir/migrate_dir
15534         mkdir $DIR/$tdir/other_dir
15535         touch $DIR/$tdir/migrate_dir/a
15536         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15537         ls $DIR/$tdir/other_dir
15538
15539         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15540                 error "migrate dir fails"
15541
15542         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15543         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15544
15545         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15546         [ $mdt_index == 0 ] || error "a is not on MDT0"
15547
15548         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15549                 error "migrate dir fails"
15550
15551         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15552         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15553
15554         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15555         [ $mdt_index == 1 ] || error "a is not on MDT1"
15556
15557         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15558         [ $mdt_index == 1 ] || error "b is not on MDT1"
15559
15560         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15561         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15562
15563         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15564
15565         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15566 }
15567 run_test 230e "migrate mulitple local link files"
15568
15569 test_230f() {
15570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15572         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15573                 skip "Need MDS version at least 2.11.52"
15574
15575         local a_fid
15576         local ln_fid
15577
15578         mkdir -p $DIR/$tdir
15579         mkdir $DIR/$tdir/migrate_dir
15580         $LFS mkdir -i1 $DIR/$tdir/other_dir
15581         touch $DIR/$tdir/migrate_dir/a
15582         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15583         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15584         ls $DIR/$tdir/other_dir
15585
15586         # a should be migrated to MDT1, since no other links on MDT0
15587         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15588                 error "#1 migrate dir fails"
15589         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15590         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15591         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15592         [ $mdt_index == 1 ] || error "a is not on MDT1"
15593
15594         # a should stay on MDT1, because it is a mulitple link file
15595         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15596                 error "#2 migrate dir fails"
15597         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15598         [ $mdt_index == 1 ] || error "a is not on MDT1"
15599
15600         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15601                 error "#3 migrate dir fails"
15602
15603         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15604         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15605         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15606
15607         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15608         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15609
15610         # a should be migrated to MDT0, since no other links on MDT1
15611         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15612                 error "#4 migrate dir fails"
15613         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15614         [ $mdt_index == 0 ] || error "a is not on MDT0"
15615
15616         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15617 }
15618 run_test 230f "migrate mulitple remote link files"
15619
15620 test_230g() {
15621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15623         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15624                 skip "Need MDS version at least 2.11.52"
15625
15626         mkdir -p $DIR/$tdir/migrate_dir
15627
15628         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15629                 error "migrating dir to non-exist MDT succeeds"
15630         true
15631 }
15632 run_test 230g "migrate dir to non-exist MDT"
15633
15634 test_230h() {
15635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15636         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15637         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15638                 skip "Need MDS version at least 2.11.52"
15639
15640         local mdt_index
15641
15642         mkdir -p $DIR/$tdir/migrate_dir
15643
15644         $LFS migrate -m1 $DIR &&
15645                 error "migrating mountpoint1 should fail"
15646
15647         $LFS migrate -m1 $DIR/$tdir/.. &&
15648                 error "migrating mountpoint2 should fail"
15649
15650         # same as mv
15651         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15652                 error "migrating $tdir/migrate_dir/.. should fail"
15653
15654         true
15655 }
15656 run_test 230h "migrate .. and root"
15657
15658 test_230i() {
15659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15662                 skip "Need MDS version at least 2.11.52"
15663
15664         mkdir -p $DIR/$tdir/migrate_dir
15665
15666         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15667                 error "migration fails with a tailing slash"
15668
15669         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15670                 error "migration fails with two tailing slashes"
15671 }
15672 run_test 230i "lfs migrate -m tolerates trailing slashes"
15673
15674 test_230j() {
15675         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15676         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15677                 skip "Need MDS version at least 2.11.52"
15678
15679         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15680         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15681                 error "create $tfile failed"
15682         cat /etc/passwd > $DIR/$tdir/$tfile
15683
15684         $LFS migrate -m 1 $DIR/$tdir
15685
15686         cmp /etc/passwd $DIR/$tdir/$tfile ||
15687                 error "DoM file mismatch after migration"
15688 }
15689 run_test 230j "DoM file data not changed after dir migration"
15690
15691 test_230k() {
15692         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15693         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15694                 skip "Need MDS version at least 2.11.56"
15695
15696         local total=20
15697         local files_on_starting_mdt=0
15698
15699         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15700         $LFS getdirstripe $DIR/$tdir
15701         for i in $(seq $total); do
15702                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15703                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15704                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15705         done
15706
15707         echo "$files_on_starting_mdt files on MDT0"
15708
15709         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15710         $LFS getdirstripe $DIR/$tdir
15711
15712         files_on_starting_mdt=0
15713         for i in $(seq $total); do
15714                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15715                         error "file $tfile.$i mismatch after migration"
15716                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15717                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15718         done
15719
15720         echo "$files_on_starting_mdt files on MDT1 after migration"
15721         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15722
15723         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15724         $LFS getdirstripe $DIR/$tdir
15725
15726         files_on_starting_mdt=0
15727         for i in $(seq $total); do
15728                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15729                         error "file $tfile.$i mismatch after 2nd migration"
15730                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15731                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15732         done
15733
15734         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15735         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15736
15737         true
15738 }
15739 run_test 230k "file data not changed after dir migration"
15740
15741 test_230l() {
15742         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15743         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15744                 skip "Need MDS version at least 2.11.56"
15745
15746         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15747         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15748                 error "create files under remote dir failed $i"
15749         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15750 }
15751 run_test 230l "readdir between MDTs won't crash"
15752
15753 test_231a()
15754 {
15755         # For simplicity this test assumes that max_pages_per_rpc
15756         # is the same across all OSCs
15757         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15758         local bulk_size=$((max_pages * PAGE_SIZE))
15759         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15760                                        head -n 1)
15761
15762         mkdir -p $DIR/$tdir
15763         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15764                 error "failed to set stripe with -S ${brw_size}M option"
15765
15766         # clear the OSC stats
15767         $LCTL set_param osc.*.stats=0 &>/dev/null
15768         stop_writeback
15769
15770         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15772                 oflag=direct &>/dev/null || error "dd failed"
15773
15774         sync; sleep 1; sync # just to be safe
15775         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15776         if [ x$nrpcs != "x1" ]; then
15777                 $LCTL get_param osc.*.stats
15778                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15779         fi
15780
15781         start_writeback
15782         # Drop the OSC cache, otherwise we will read from it
15783         cancel_lru_locks osc
15784
15785         # clear the OSC stats
15786         $LCTL set_param osc.*.stats=0 &>/dev/null
15787
15788         # Client reads $bulk_size.
15789         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15790                 iflag=direct &>/dev/null || error "dd failed"
15791
15792         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15793         if [ x$nrpcs != "x1" ]; then
15794                 $LCTL get_param osc.*.stats
15795                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15796         fi
15797 }
15798 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15799
15800 test_231b() {
15801         mkdir -p $DIR/$tdir
15802         local i
15803         for i in {0..1023}; do
15804                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15805                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15806                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15807         done
15808         sync
15809 }
15810 run_test 231b "must not assert on fully utilized OST request buffer"
15811
15812 test_232a() {
15813         mkdir -p $DIR/$tdir
15814         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15815
15816         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15817         do_facet ost1 $LCTL set_param fail_loc=0x31c
15818
15819         # ignore dd failure
15820         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15821
15822         do_facet ost1 $LCTL set_param fail_loc=0
15823         umount_client $MOUNT || error "umount failed"
15824         mount_client $MOUNT || error "mount failed"
15825         stop ost1 || error "cannot stop ost1"
15826         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15827 }
15828 run_test 232a "failed lock should not block umount"
15829
15830 test_232b() {
15831         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15832                 skip "Need MDS version at least 2.10.58"
15833
15834         mkdir -p $DIR/$tdir
15835         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15836         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15837         sync
15838         cancel_lru_locks osc
15839
15840         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15841         do_facet ost1 $LCTL set_param fail_loc=0x31c
15842
15843         # ignore failure
15844         $LFS data_version $DIR/$tdir/$tfile || true
15845
15846         do_facet ost1 $LCTL set_param fail_loc=0
15847         umount_client $MOUNT || error "umount failed"
15848         mount_client $MOUNT || error "mount failed"
15849         stop ost1 || error "cannot stop ost1"
15850         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15851 }
15852 run_test 232b "failed data version lock should not block umount"
15853
15854 test_233a() {
15855         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15856                 skip "Need MDS version at least 2.3.64"
15857         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15858
15859         local fid=$($LFS path2fid $MOUNT)
15860
15861         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15862                 error "cannot access $MOUNT using its FID '$fid'"
15863 }
15864 run_test 233a "checking that OBF of the FS root succeeds"
15865
15866 test_233b() {
15867         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15868                 skip "Need MDS version at least 2.5.90"
15869         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15870
15871         local fid=$($LFS path2fid $MOUNT/.lustre)
15872
15873         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15874                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15875
15876         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15877         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15878                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15879 }
15880 run_test 233b "checking that OBF of the FS .lustre succeeds"
15881
15882 test_234() {
15883         local p="$TMP/sanityN-$TESTNAME.parameters"
15884         save_lustre_params client "llite.*.xattr_cache" > $p
15885         lctl set_param llite.*.xattr_cache 1 ||
15886                 skip_env "xattr cache is not supported"
15887
15888         mkdir -p $DIR/$tdir || error "mkdir failed"
15889         touch $DIR/$tdir/$tfile || error "touch failed"
15890         # OBD_FAIL_LLITE_XATTR_ENOMEM
15891         $LCTL set_param fail_loc=0x1405
15892         getfattr -n user.attr $DIR/$tdir/$tfile &&
15893                 error "getfattr should have failed with ENOMEM"
15894         $LCTL set_param fail_loc=0x0
15895         rm -rf $DIR/$tdir
15896
15897         restore_lustre_params < $p
15898         rm -f $p
15899 }
15900 run_test 234 "xattr cache should not crash on ENOMEM"
15901
15902 test_235() {
15903         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15904                 skip "Need MDS version at least 2.4.52"
15905
15906         flock_deadlock $DIR/$tfile
15907         local RC=$?
15908         case $RC in
15909                 0)
15910                 ;;
15911                 124) error "process hangs on a deadlock"
15912                 ;;
15913                 *) error "error executing flock_deadlock $DIR/$tfile"
15914                 ;;
15915         esac
15916 }
15917 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15918
15919 #LU-2935
15920 test_236() {
15921         check_swap_layouts_support
15922
15923         local ref1=/etc/passwd
15924         local ref2=/etc/group
15925         local file1=$DIR/$tdir/f1
15926         local file2=$DIR/$tdir/f2
15927
15928         test_mkdir -c1 $DIR/$tdir
15929         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15930         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15931         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15932         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15933         local fd=$(free_fd)
15934         local cmd="exec $fd<>$file2"
15935         eval $cmd
15936         rm $file2
15937         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15938                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15939         cmd="exec $fd>&-"
15940         eval $cmd
15941         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15942
15943         #cleanup
15944         rm -rf $DIR/$tdir
15945 }
15946 run_test 236 "Layout swap on open unlinked file"
15947
15948 # LU-4659 linkea consistency
15949 test_238() {
15950         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15951                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15952                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15953                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15954
15955         touch $DIR/$tfile
15956         ln $DIR/$tfile $DIR/$tfile.lnk
15957         touch $DIR/$tfile.new
15958         mv $DIR/$tfile.new $DIR/$tfile
15959         local fid1=$($LFS path2fid $DIR/$tfile)
15960         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15961         local path1=$($LFS fid2path $FSNAME "$fid1")
15962         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15963         local path2=$($LFS fid2path $FSNAME "$fid2")
15964         [ $tfile.lnk == $path2 ] ||
15965                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15966         rm -f $DIR/$tfile*
15967 }
15968 run_test 238 "Verify linkea consistency"
15969
15970 test_239A() { # was test_239
15971         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15972                 skip "Need MDS version at least 2.5.60"
15973
15974         local list=$(comma_list $(mdts_nodes))
15975
15976         mkdir -p $DIR/$tdir
15977         createmany -o $DIR/$tdir/f- 5000
15978         unlinkmany $DIR/$tdir/f- 5000
15979         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15980                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15981         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
15982                         osp.*MDT*.sync_in_flight" | calc_sum)
15983         [ "$changes" -eq 0 ] || error "$changes not synced"
15984 }
15985 run_test 239A "osp_sync test"
15986
15987 test_239a() { #LU-5297
15988         remote_mds_nodsh && skip "remote MDS with nodsh"
15989
15990         touch $DIR/$tfile
15991         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
15992         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
15993         chgrp $RUNAS_GID $DIR/$tfile
15994         wait_delete_completed
15995 }
15996 run_test 239a "process invalid osp sync record correctly"
15997
15998 test_239b() { #LU-5297
15999         remote_mds_nodsh && skip "remote MDS with nodsh"
16000
16001         touch $DIR/$tfile1
16002         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16003         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16004         chgrp $RUNAS_GID $DIR/$tfile1
16005         wait_delete_completed
16006         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16007         touch $DIR/$tfile2
16008         chgrp $RUNAS_GID $DIR/$tfile2
16009         wait_delete_completed
16010 }
16011 run_test 239b "process osp sync record with ENOMEM error correctly"
16012
16013 test_240() {
16014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16015         remote_mds_nodsh && skip "remote MDS with nodsh"
16016
16017         mkdir -p $DIR/$tdir
16018
16019         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16020                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16021         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16022                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16023
16024         umount_client $MOUNT || error "umount failed"
16025         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16026         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16027         mount_client $MOUNT || error "failed to mount client"
16028
16029         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16030         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16031 }
16032 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16033
16034 test_241_bio() {
16035         local count=$1
16036         local bsize=$2
16037
16038         for LOOP in $(seq $count); do
16039                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16040                 cancel_lru_locks $OSC || true
16041         done
16042 }
16043
16044 test_241_dio() {
16045         local count=$1
16046         local bsize=$2
16047
16048         for LOOP in $(seq $1); do
16049                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16050                         2>/dev/null
16051         done
16052 }
16053
16054 test_241a() { # was test_241
16055         local bsize=$PAGE_SIZE
16056
16057         (( bsize < 40960 )) && bsize=40960
16058         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16059         ls -la $DIR/$tfile
16060         cancel_lru_locks $OSC
16061         test_241_bio 1000 $bsize &
16062         PID=$!
16063         test_241_dio 1000 $bsize
16064         wait $PID
16065 }
16066 run_test 241a "bio vs dio"
16067
16068 test_241b() {
16069         local bsize=$PAGE_SIZE
16070
16071         (( bsize < 40960 )) && bsize=40960
16072         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16073         ls -la $DIR/$tfile
16074         test_241_dio 1000 $bsize &
16075         PID=$!
16076         test_241_dio 1000 $bsize
16077         wait $PID
16078 }
16079 run_test 241b "dio vs dio"
16080
16081 test_242() {
16082         remote_mds_nodsh && skip "remote MDS with nodsh"
16083
16084         mkdir -p $DIR/$tdir
16085         touch $DIR/$tdir/$tfile
16086
16087         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16088         do_facet mds1 lctl set_param fail_loc=0x105
16089         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16090
16091         do_facet mds1 lctl set_param fail_loc=0
16092         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16093 }
16094 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16095
16096 test_243()
16097 {
16098         test_mkdir $DIR/$tdir
16099         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16100 }
16101 run_test 243 "various group lock tests"
16102
16103 test_244()
16104 {
16105         test_mkdir $DIR/$tdir
16106         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16107         sendfile_grouplock $DIR/$tdir/$tfile || \
16108                 error "sendfile+grouplock failed"
16109         rm -rf $DIR/$tdir
16110 }
16111 run_test 244 "sendfile with group lock tests"
16112
16113 test_245() {
16114         local flagname="multi_mod_rpcs"
16115         local connect_data_name="max_mod_rpcs"
16116         local out
16117
16118         # check if multiple modify RPCs flag is set
16119         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16120                 grep "connect_flags:")
16121         echo "$out"
16122
16123         echo "$out" | grep -qw $flagname
16124         if [ $? -ne 0 ]; then
16125                 echo "connect flag $flagname is not set"
16126                 return
16127         fi
16128
16129         # check if multiple modify RPCs data is set
16130         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16131         echo "$out"
16132
16133         echo "$out" | grep -qw $connect_data_name ||
16134                 error "import should have connect data $connect_data_name"
16135 }
16136 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16137
16138 test_246() { # LU-7371
16139         remote_ost_nodsh && skip "remote OST with nodsh"
16140         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16141                 skip "Need OST version >= 2.7.62"
16142
16143         do_facet ost1 $LCTL set_param fail_val=4095
16144 #define OBD_FAIL_OST_READ_SIZE          0x234
16145         do_facet ost1 $LCTL set_param fail_loc=0x234
16146         $LFS setstripe $DIR/$tfile -i 0 -c 1
16147         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16148         cancel_lru_locks $FSNAME-OST0000
16149         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16150 }
16151 run_test 246 "Read file of size 4095 should return right length"
16152
16153 cleanup_247() {
16154         local submount=$1
16155
16156         trap 0
16157         umount_client $submount
16158         rmdir $submount
16159 }
16160
16161 test_247a() {
16162         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16163                 grep -q subtree ||
16164                 skip_env "Fileset feature is not supported"
16165
16166         local submount=${MOUNT}_$tdir
16167
16168         mkdir $MOUNT/$tdir
16169         mkdir -p $submount || error "mkdir $submount failed"
16170         FILESET="$FILESET/$tdir" mount_client $submount ||
16171                 error "mount $submount failed"
16172         trap "cleanup_247 $submount" EXIT
16173         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16174         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16175                 error "read $MOUNT/$tdir/$tfile failed"
16176         cleanup_247 $submount
16177 }
16178 run_test 247a "mount subdir as fileset"
16179
16180 test_247b() {
16181         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16182                 skip_env "Fileset feature is not supported"
16183
16184         local submount=${MOUNT}_$tdir
16185
16186         rm -rf $MOUNT/$tdir
16187         mkdir -p $submount || error "mkdir $submount failed"
16188         SKIP_FILESET=1
16189         FILESET="$FILESET/$tdir" mount_client $submount &&
16190                 error "mount $submount should fail"
16191         rmdir $submount
16192 }
16193 run_test 247b "mount subdir that dose not exist"
16194
16195 test_247c() {
16196         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16197                 skip_env "Fileset feature is not supported"
16198
16199         local submount=${MOUNT}_$tdir
16200
16201         mkdir -p $MOUNT/$tdir/dir1
16202         mkdir -p $submount || error "mkdir $submount failed"
16203         trap "cleanup_247 $submount" EXIT
16204         FILESET="$FILESET/$tdir" mount_client $submount ||
16205                 error "mount $submount failed"
16206         local fid=$($LFS path2fid $MOUNT/)
16207         $LFS fid2path $submount $fid && error "fid2path should fail"
16208         cleanup_247 $submount
16209 }
16210 run_test 247c "running fid2path outside root"
16211
16212 test_247d() {
16213         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16214                 skip "Fileset feature is not supported"
16215
16216         local submount=${MOUNT}_$tdir
16217
16218         mkdir -p $MOUNT/$tdir/dir1
16219         mkdir -p $submount || error "mkdir $submount failed"
16220         FILESET="$FILESET/$tdir" mount_client $submount ||
16221                 error "mount $submount failed"
16222         trap "cleanup_247 $submount" EXIT
16223         local fid=$($LFS path2fid $submount/dir1)
16224         $LFS fid2path $submount $fid || error "fid2path should succeed"
16225         cleanup_247 $submount
16226 }
16227 run_test 247d "running fid2path inside root"
16228
16229 # LU-8037
16230 test_247e() {
16231         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16232                 grep -q subtree ||
16233                 skip "Fileset feature is not supported"
16234
16235         local submount=${MOUNT}_$tdir
16236
16237         mkdir $MOUNT/$tdir
16238         mkdir -p $submount || error "mkdir $submount failed"
16239         FILESET="$FILESET/.." mount_client $submount &&
16240                 error "mount $submount should fail"
16241         rmdir $submount
16242 }
16243 run_test 247e "mount .. as fileset"
16244
16245 test_248() {
16246         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16247         [ -z "$fast_read_sav" ] && skip "no fast read support"
16248
16249         # create a large file for fast read verification
16250         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16251
16252         # make sure the file is created correctly
16253         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16254                 { rm -f $DIR/$tfile; skip "file creation error"; }
16255
16256         echo "Test 1: verify that fast read is 4 times faster on cache read"
16257
16258         # small read with fast read enabled
16259         $LCTL set_param -n llite.*.fast_read=1
16260         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16261                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16262                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16263         # small read with fast read disabled
16264         $LCTL set_param -n llite.*.fast_read=0
16265         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16266                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16267                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16268
16269         # verify that fast read is 4 times faster for cache read
16270         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16271                 error_not_in_vm "fast read was not 4 times faster: " \
16272                            "$t_fast vs $t_slow"
16273
16274         echo "Test 2: verify the performance between big and small read"
16275         $LCTL set_param -n llite.*.fast_read=1
16276
16277         # 1k non-cache read
16278         cancel_lru_locks osc
16279         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16280                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16281                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16282
16283         # 1M non-cache read
16284         cancel_lru_locks osc
16285         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16286                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16287                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16288
16289         # verify that big IO is not 4 times faster than small IO
16290         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16291                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16292
16293         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16294         rm -f $DIR/$tfile
16295 }
16296 run_test 248 "fast read verification"
16297
16298 test_249() { # LU-7890
16299         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16300                 skip "Need at least version 2.8.54"
16301
16302         rm -f $DIR/$tfile
16303         $LFS setstripe -c 1 $DIR/$tfile
16304         # Offset 2T == 4k * 512M
16305         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16306                 error "dd to 2T offset failed"
16307 }
16308 run_test 249 "Write above 2T file size"
16309
16310 test_250() {
16311         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16312          && skip "no 16TB file size limit on ZFS"
16313
16314         $LFS setstripe -c 1 $DIR/$tfile
16315         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16316         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16317         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16318         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16319                 conv=notrunc,fsync && error "append succeeded"
16320         return 0
16321 }
16322 run_test 250 "Write above 16T limit"
16323
16324 test_251() {
16325         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16326
16327         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16328         #Skip once - writing the first stripe will succeed
16329         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16330         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16331                 error "short write happened"
16332
16333         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16334         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16335                 error "short read happened"
16336
16337         rm -f $DIR/$tfile
16338 }
16339 run_test 251 "Handling short read and write correctly"
16340
16341 test_252() {
16342         remote_mds_nodsh && skip "remote MDS with nodsh"
16343         remote_ost_nodsh && skip "remote OST with nodsh"
16344         if [ "$ost1_FSTYPE" != "ldiskfs" -o "$mds1_FSTYPE" != "ldiskfs" ]; then
16345                 skip_env "ldiskfs only test"
16346         fi
16347
16348         local tgt
16349         local dev
16350         local out
16351         local uuid
16352         local num
16353         local gen
16354
16355         # check lr_reader on OST0000
16356         tgt=ost1
16357         dev=$(facet_device $tgt)
16358         out=$(do_facet $tgt $LR_READER $dev)
16359         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16360         echo "$out"
16361         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16362         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16363                 error "Invalid uuid returned by $LR_READER on target $tgt"
16364         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16365
16366         # check lr_reader -c on MDT0000
16367         tgt=mds1
16368         dev=$(facet_device $tgt)
16369         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16370                 skip "$LR_READER does not support additional options"
16371         fi
16372         out=$(do_facet $tgt $LR_READER -c $dev)
16373         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16374         echo "$out"
16375         num=$(echo "$out" | grep -c "mdtlov")
16376         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16377                 error "Invalid number of mdtlov clients returned by $LR_READER"
16378         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16379
16380         # check lr_reader -cr on MDT0000
16381         out=$(do_facet $tgt $LR_READER -cr $dev)
16382         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16383         echo "$out"
16384         echo "$out" | grep -q "^reply_data:$" ||
16385                 error "$LR_READER should have returned 'reply_data' section"
16386         num=$(echo "$out" | grep -c "client_generation")
16387         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16388 }
16389 run_test 252 "check lr_reader tool"
16390
16391 test_253_fill_ost() {
16392         local size_mb #how many MB should we write to pass watermark
16393         local lwm=$3  #low watermark
16394         local free_10mb #10% of free space
16395
16396         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16397         size_mb=$((free_kb / 1024 - lwm))
16398         free_10mb=$((free_kb / 10240))
16399         #If 10% of free space cross low watermark use it
16400         if (( free_10mb > size_mb )); then
16401                 size_mb=$free_10mb
16402         else
16403                 #At least we need to store 1.1 of difference between
16404                 #free space and low watermark
16405                 size_mb=$((size_mb + size_mb / 10))
16406         fi
16407         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16408                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16409                          oflag=append conv=notrunc
16410         fi
16411
16412         sleep_maxage
16413
16414         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16415         echo "OST still has $((free_kb / 1024)) mbytes free"
16416 }
16417
16418 test_253() {
16419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16420         remote_mds_nodsh && skip "remote MDS with nodsh"
16421         remote_mgs_nodsh && skip "remote MGS with nodsh"
16422
16423         local ostidx=0
16424         local rc=0
16425
16426         local ost_name=$($LFS osts |
16427                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16428         # on the mdt's osc
16429         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16430         do_facet $SINGLEMDS $LCTL get_param -n \
16431                 osp.$mdtosc_proc1.reserved_mb_high ||
16432                 skip  "remote MDS does not support reserved_mb_high"
16433
16434         rm -rf $DIR/$tdir
16435         wait_mds_ost_sync
16436         wait_delete_completed
16437         mkdir $DIR/$tdir
16438
16439         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16440                         osp.$mdtosc_proc1.reserved_mb_high)
16441         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16442                         osp.$mdtosc_proc1.reserved_mb_low)
16443         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16444
16445         if ! combined_mgs_mds ; then
16446                 mount_mgs_client
16447         fi
16448         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16449         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16450                 error "Adding $ost_name to pool failed"
16451
16452         # Wait for client to see a OST at pool
16453         wait_update $HOSTNAME "$LCTL get_param -n
16454                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16455                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16456                 error "Client can not see the pool"
16457         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16458                 error "Setstripe failed"
16459
16460         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16461         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16462         echo "OST still has $((blocks/1024)) mbytes free"
16463
16464         local new_lwm=$((blocks/1024-10))
16465         do_facet $SINGLEMDS $LCTL set_param \
16466                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16467         do_facet $SINGLEMDS $LCTL set_param \
16468                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16469
16470         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16471
16472         #First enospc could execute orphan deletion so repeat.
16473         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16474
16475         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16476                         osp.$mdtosc_proc1.prealloc_status)
16477         echo "prealloc_status $oa_status"
16478
16479         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16480                 error "File creation should fail"
16481         #object allocation was stopped, but we still able to append files
16482         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16483                 error "Append failed"
16484         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16485
16486         wait_delete_completed
16487
16488         sleep_maxage
16489
16490         for i in $(seq 10 12); do
16491                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16492                         error "File creation failed after rm";
16493         done
16494
16495         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16496                         osp.$mdtosc_proc1.prealloc_status)
16497         echo "prealloc_status $oa_status"
16498
16499         if (( oa_status != 0 )); then
16500                 error "Object allocation still disable after rm"
16501         fi
16502         do_facet $SINGLEMDS $LCTL set_param \
16503                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16504         do_facet $SINGLEMDS $LCTL set_param \
16505                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16506
16507
16508         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16509                 error "Remove $ost_name from pool failed"
16510         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16511                 error "Pool destroy fialed"
16512
16513         if ! combined_mgs_mds ; then
16514                 umount_mgs_client
16515         fi
16516 }
16517 run_test 253 "Check object allocation limit"
16518
16519 test_254() {
16520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16521         remote_mds_nodsh && skip "remote MDS with nodsh"
16522         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16523                 skip "MDS does not support changelog_size"
16524
16525         local cl_user
16526         local MDT0=$(facet_svc $SINGLEMDS)
16527
16528         changelog_register || error "changelog_register failed"
16529
16530         changelog_clear 0 || error "changelog_clear failed"
16531
16532         local size1=$(do_facet $SINGLEMDS \
16533                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16534         echo "Changelog size $size1"
16535
16536         rm -rf $DIR/$tdir
16537         $LFS mkdir -i 0 $DIR/$tdir
16538         # change something
16539         mkdir -p $DIR/$tdir/pics/2008/zachy
16540         touch $DIR/$tdir/pics/2008/zachy/timestamp
16541         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16542         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16543         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16544         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16545         rm $DIR/$tdir/pics/desktop.jpg
16546
16547         local size2=$(do_facet $SINGLEMDS \
16548                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16549         echo "Changelog size after work $size2"
16550
16551         (( $size2 > $size1 )) ||
16552                 error "new Changelog size=$size2 less than old size=$size1"
16553 }
16554 run_test 254 "Check changelog size"
16555
16556 ladvise_no_type()
16557 {
16558         local type=$1
16559         local file=$2
16560
16561         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16562                 awk -F: '{print $2}' | grep $type > /dev/null
16563         if [ $? -ne 0 ]; then
16564                 return 0
16565         fi
16566         return 1
16567 }
16568
16569 ladvise_no_ioctl()
16570 {
16571         local file=$1
16572
16573         lfs ladvise -a willread $file > /dev/null 2>&1
16574         if [ $? -eq 0 ]; then
16575                 return 1
16576         fi
16577
16578         lfs ladvise -a willread $file 2>&1 |
16579                 grep "Inappropriate ioctl for device" > /dev/null
16580         if [ $? -eq 0 ]; then
16581                 return 0
16582         fi
16583         return 1
16584 }
16585
16586 percent() {
16587         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16588 }
16589
16590 # run a random read IO workload
16591 # usage: random_read_iops <filename> <filesize> <iosize>
16592 random_read_iops() {
16593         local file=$1
16594         local fsize=$2
16595         local iosize=${3:-4096}
16596
16597         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16598                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16599 }
16600
16601 drop_file_oss_cache() {
16602         local file="$1"
16603         local nodes="$2"
16604
16605         $LFS ladvise -a dontneed $file 2>/dev/null ||
16606                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16607 }
16608
16609 ladvise_willread_performance()
16610 {
16611         local repeat=10
16612         local average_origin=0
16613         local average_cache=0
16614         local average_ladvise=0
16615
16616         for ((i = 1; i <= $repeat; i++)); do
16617                 echo "Iter $i/$repeat: reading without willread hint"
16618                 cancel_lru_locks osc
16619                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16620                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16621                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16622                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16623
16624                 cancel_lru_locks osc
16625                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16626                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16627                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16628
16629                 cancel_lru_locks osc
16630                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16631                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16632                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16633                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16634                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16635         done
16636         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16637         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16638         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16639
16640         speedup_cache=$(percent $average_cache $average_origin)
16641         speedup_ladvise=$(percent $average_ladvise $average_origin)
16642
16643         echo "Average uncached read: $average_origin"
16644         echo "Average speedup with OSS cached read: " \
16645                 "$average_cache = +$speedup_cache%"
16646         echo "Average speedup with ladvise willread: " \
16647                 "$average_ladvise = +$speedup_ladvise%"
16648
16649         local lowest_speedup=20
16650         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16651                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16652                         "got $average_cache%. Skipping ladvise willread check."
16653                 return 0
16654         fi
16655
16656         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16657         # it is still good to run until then to exercise 'ladvise willread'
16658         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16659                 [ "$ost1_FSTYPE" = "zfs" ] &&
16660                 echo "osd-zfs does not support dontneed or drop_caches" &&
16661                 return 0
16662
16663         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16664         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16665                 error_not_in_vm "Speedup with willread is less than " \
16666                         "$lowest_speedup%, got $average_ladvise%"
16667 }
16668
16669 test_255a() {
16670         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16671                 skip "lustre < 2.8.54 does not support ladvise "
16672         remote_ost_nodsh && skip "remote OST with nodsh"
16673
16674         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16675
16676         ladvise_no_type willread $DIR/$tfile &&
16677                 skip "willread ladvise is not supported"
16678
16679         ladvise_no_ioctl $DIR/$tfile &&
16680                 skip "ladvise ioctl is not supported"
16681
16682         local size_mb=100
16683         local size=$((size_mb * 1048576))
16684         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16685                 error "dd to $DIR/$tfile failed"
16686
16687         lfs ladvise -a willread $DIR/$tfile ||
16688                 error "Ladvise failed with no range argument"
16689
16690         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16691                 error "Ladvise failed with no -l or -e argument"
16692
16693         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16694                 error "Ladvise failed with only -e argument"
16695
16696         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16697                 error "Ladvise failed with only -l argument"
16698
16699         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16700                 error "End offset should not be smaller than start offset"
16701
16702         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16703                 error "End offset should not be equal to start offset"
16704
16705         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16706                 error "Ladvise failed with overflowing -s argument"
16707
16708         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16709                 error "Ladvise failed with overflowing -e argument"
16710
16711         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16712                 error "Ladvise failed with overflowing -l argument"
16713
16714         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16715                 error "Ladvise succeeded with conflicting -l and -e arguments"
16716
16717         echo "Synchronous ladvise should wait"
16718         local delay=4
16719 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16720         do_nodes $(comma_list $(osts_nodes)) \
16721                 $LCTL set_param fail_val=$delay fail_loc=0x237
16722
16723         local start_ts=$SECONDS
16724         lfs ladvise -a willread $DIR/$tfile ||
16725                 error "Ladvise failed with no range argument"
16726         local end_ts=$SECONDS
16727         local inteval_ts=$((end_ts - start_ts))
16728
16729         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16730                 error "Synchronous advice didn't wait reply"
16731         fi
16732
16733         echo "Asynchronous ladvise shouldn't wait"
16734         local start_ts=$SECONDS
16735         lfs ladvise -a willread -b $DIR/$tfile ||
16736                 error "Ladvise failed with no range argument"
16737         local end_ts=$SECONDS
16738         local inteval_ts=$((end_ts - start_ts))
16739
16740         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16741                 error "Asynchronous advice blocked"
16742         fi
16743
16744         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16745         ladvise_willread_performance
16746 }
16747 run_test 255a "check 'lfs ladvise -a willread'"
16748
16749 facet_meminfo() {
16750         local facet=$1
16751         local info=$2
16752
16753         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16754 }
16755
16756 test_255b() {
16757         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16758                 skip "lustre < 2.8.54 does not support ladvise "
16759         remote_ost_nodsh && skip "remote OST with nodsh"
16760
16761         lfs setstripe -c 1 -i 0 $DIR/$tfile
16762
16763         ladvise_no_type dontneed $DIR/$tfile &&
16764                 skip "dontneed ladvise is not supported"
16765
16766         ladvise_no_ioctl $DIR/$tfile &&
16767                 skip "ladvise ioctl is not supported"
16768
16769         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16770                 [ "$ost1_FSTYPE" = "zfs" ] &&
16771                 skip "zfs-osd does not support 'ladvise dontneed'"
16772
16773         local size_mb=100
16774         local size=$((size_mb * 1048576))
16775         # In order to prevent disturbance of other processes, only check 3/4
16776         # of the memory usage
16777         local kibibytes=$((size_mb * 1024 * 3 / 4))
16778
16779         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16780                 error "dd to $DIR/$tfile failed"
16781
16782         #force write to complete before dropping OST cache & checking memory
16783         sync
16784
16785         local total=$(facet_meminfo ost1 MemTotal)
16786         echo "Total memory: $total KiB"
16787
16788         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16789         local before_read=$(facet_meminfo ost1 Cached)
16790         echo "Cache used before read: $before_read KiB"
16791
16792         lfs ladvise -a willread $DIR/$tfile ||
16793                 error "Ladvise willread failed"
16794         local after_read=$(facet_meminfo ost1 Cached)
16795         echo "Cache used after read: $after_read KiB"
16796
16797         lfs ladvise -a dontneed $DIR/$tfile ||
16798                 error "Ladvise dontneed again failed"
16799         local no_read=$(facet_meminfo ost1 Cached)
16800         echo "Cache used after dontneed ladvise: $no_read KiB"
16801
16802         if [ $total -lt $((before_read + kibibytes)) ]; then
16803                 echo "Memory is too small, abort checking"
16804                 return 0
16805         fi
16806
16807         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16808                 error "Ladvise willread should use more memory" \
16809                         "than $kibibytes KiB"
16810         fi
16811
16812         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16813                 error "Ladvise dontneed should release more memory" \
16814                         "than $kibibytes KiB"
16815         fi
16816 }
16817 run_test 255b "check 'lfs ladvise -a dontneed'"
16818
16819 test_255c() {
16820         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16821                 skip "lustre < 2.10.53 does not support lockahead"
16822
16823         local count
16824         local new_count
16825         local difference
16826         local i
16827         local rc
16828
16829         test_mkdir -p $DIR/$tdir
16830         $LFS setstripe -i 0 $DIR/$tdir
16831
16832         #test 10 returns only success/failure
16833         i=10
16834         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16835         rc=$?
16836         if [ $rc -eq 255 ]; then
16837                 error "Ladvise test${i} failed, ${rc}"
16838         fi
16839
16840         #test 11 counts lock enqueue requests, all others count new locks
16841         i=11
16842         count=$(do_facet ost1 \
16843                 $LCTL get_param -n ost.OSS.ost.stats)
16844         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16845
16846         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16847         rc=$?
16848         if [ $rc -eq 255 ]; then
16849                 error "Ladvise test${i} failed, ${rc}"
16850         fi
16851
16852         new_count=$(do_facet ost1 \
16853                 $LCTL get_param -n ost.OSS.ost.stats)
16854         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16855                    awk '{ print $2 }')
16856
16857         difference="$((new_count - count))"
16858         if [ $difference -ne $rc ]; then
16859                 error "Ladvise test${i}, bad enqueue count, returned " \
16860                       "${rc}, actual ${difference}"
16861         fi
16862
16863         for i in $(seq 12 21); do
16864                 # If we do not do this, we run the risk of having too many
16865                 # locks and starting lock cancellation while we are checking
16866                 # lock counts.
16867                 cancel_lru_locks osc
16868
16869                 count=$($LCTL get_param -n \
16870                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16871
16872                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16873                 rc=$?
16874                 if [ $rc -eq 255 ]; then
16875                         error "Ladvise test ${i} failed, ${rc}"
16876                 fi
16877
16878                 new_count=$($LCTL get_param -n \
16879                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16880                 difference="$((new_count - count))"
16881
16882                 # Test 15 output is divided by 100 to map down to valid return
16883                 if [ $i -eq 15 ]; then
16884                         rc="$((rc * 100))"
16885                 fi
16886
16887                 if [ $difference -ne $rc ]; then
16888                         error "Ladvise test ${i}, bad lock count, returned " \
16889                               "${rc}, actual ${difference}"
16890                 fi
16891         done
16892
16893         #test 22 returns only success/failure
16894         i=22
16895         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16896         rc=$?
16897         if [ $rc -eq 255 ]; then
16898                 error "Ladvise test${i} failed, ${rc}"
16899         fi
16900 }
16901 run_test 255c "suite of ladvise lockahead tests"
16902
16903 test_256() {
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905         remote_mds_nodsh && skip "remote MDS with nodsh"
16906         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16907         changelog_users $SINGLEMDS | grep "^cl" &&
16908                 skip "active changelog user"
16909
16910         local cl_user
16911         local cat_sl
16912         local mdt_dev
16913
16914         mdt_dev=$(mdsdevname 1)
16915         echo $mdt_dev
16916
16917         changelog_register || error "changelog_register failed"
16918
16919         rm -rf $DIR/$tdir
16920         mkdir -p $DIR/$tdir
16921
16922         changelog_clear 0 || error "changelog_clear failed"
16923
16924         # change something
16925         touch $DIR/$tdir/{1..10}
16926
16927         # stop the MDT
16928         stop $SINGLEMDS || error "Fail to stop MDT"
16929
16930         # remount the MDT
16931
16932         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16933
16934         #after mount new plainllog is used
16935         touch $DIR/$tdir/{11..19}
16936         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16937         cat_sl=$(do_facet $SINGLEMDS "sync; \
16938                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16939                  llog_reader $tmpfile | grep -c type=1064553b")
16940         do_facet $SINGLEMDS llog_reader $tmpfile
16941
16942         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16943
16944         changelog_clear 0 || error "changelog_clear failed"
16945
16946         cat_sl=$(do_facet $SINGLEMDS "sync; \
16947                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16948                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16949
16950         if (( cat_sl == 2 )); then
16951                 error "Empty plain llog was not deleted from changelog catalog"
16952         elif (( cat_sl != 1 )); then
16953                 error "Active plain llog shouldn't be deleted from catalog"
16954         fi
16955 }
16956 run_test 256 "Check llog delete for empty and not full state"
16957
16958 test_257() {
16959         remote_mds_nodsh && skip "remote MDS with nodsh"
16960         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16961                 skip "Need MDS version at least 2.8.55"
16962
16963         test_mkdir $DIR/$tdir
16964
16965         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16966                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16967         stat $DIR/$tdir
16968
16969 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16970         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16971         local facet=mds$((mdtidx + 1))
16972         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16973         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16974
16975         stop $facet || error "stop MDS failed"
16976         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16977                 error "start MDS fail"
16978         wait_recovery_complete $facet
16979 }
16980 run_test 257 "xattr locks are not lost"
16981
16982 # Verify we take the i_mutex when security requires it
16983 test_258a() {
16984 #define OBD_FAIL_IMUTEX_SEC 0x141c
16985         $LCTL set_param fail_loc=0x141c
16986         touch $DIR/$tfile
16987         chmod u+s $DIR/$tfile
16988         chmod a+rwx $DIR/$tfile
16989         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16990         RC=$?
16991         if [ $RC -ne 0 ]; then
16992                 error "error, failed to take i_mutex, rc=$?"
16993         fi
16994         rm -f $DIR/$tfile
16995 }
16996 run_test 258a
16997
16998 # Verify we do NOT take the i_mutex in the normal case
16999 test_258b() {
17000 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17001         $LCTL set_param fail_loc=0x141d
17002         touch $DIR/$tfile
17003         chmod a+rwx $DIR
17004         chmod a+rw $DIR/$tfile
17005         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17006         RC=$?
17007         if [ $RC -ne 0 ]; then
17008                 error "error, took i_mutex unnecessarily, rc=$?"
17009         fi
17010         rm -f $DIR/$tfile
17011
17012 }
17013 run_test 258b "verify i_mutex security behavior"
17014
17015 test_259() {
17016         local file=$DIR/$tfile
17017         local before
17018         local after
17019
17020         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17021
17022         stack_trap "rm -f $file" EXIT
17023
17024         wait_delete_completed
17025         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17026         echo "before: $before"
17027
17028         $LFS setstripe -i 0 -c 1 $file
17029         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17030         sync_all_data
17031         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17032         echo "after write: $after"
17033
17034 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17035         do_facet ost1 $LCTL set_param fail_loc=0x2301
17036         $TRUNCATE $file 0
17037         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17038         echo "after truncate: $after"
17039
17040         stop ost1
17041         do_facet ost1 $LCTL set_param fail_loc=0
17042         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17043         sleep 2
17044         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17045         echo "after restart: $after"
17046         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17047                 error "missing truncate?"
17048
17049         return 0
17050 }
17051 run_test 259 "crash at delayed truncate"
17052
17053 test_260() {
17054 #define OBD_FAIL_MDC_CLOSE               0x806
17055         $LCTL set_param fail_loc=0x80000806
17056         touch $DIR/$tfile
17057
17058 }
17059 run_test 260 "Check mdc_close fail"
17060
17061 ### Data-on-MDT sanity tests ###
17062 test_270a() {
17063         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17064                 skip "Need MDS version at least 2.10.55 for DoM"
17065
17066         # create DoM file
17067         local dom=$DIR/$tdir/dom_file
17068         local tmp=$DIR/$tdir/tmp_file
17069
17070         mkdir -p $DIR/$tdir
17071
17072         # basic checks for DoM component creation
17073         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17074                 error "Can set MDT layout to non-first entry"
17075
17076         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17077                 error "Can define multiple entries as MDT layout"
17078
17079         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17080
17081         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17082         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17083         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17084
17085         local mdtidx=$($LFS getstripe -m $dom)
17086         local mdtname=MDT$(printf %04x $mdtidx)
17087         local facet=mds$((mdtidx + 1))
17088         local space_check=1
17089
17090         # Skip free space checks with ZFS
17091         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17092
17093         # write
17094         sync
17095         local size_tmp=$((65536 * 3))
17096         local mdtfree1=$(do_facet $facet \
17097                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17098
17099         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17100         # check also direct IO along write
17101         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17102         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17103         sync
17104         cmp $tmp $dom || error "file data is different"
17105         [ $(stat -c%s $dom) == $size_tmp ] ||
17106                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17107         if [ $space_check == 1 ]; then
17108                 local mdtfree2=$(do_facet $facet \
17109                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17110
17111                 # increase in usage from by $size_tmp
17112                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17113                         error "MDT free space wrong after write: " \
17114                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17115         fi
17116
17117         # truncate
17118         local size_dom=10000
17119
17120         $TRUNCATE $dom $size_dom
17121         [ $(stat -c%s $dom) == $size_dom ] ||
17122                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17123         if [ $space_check == 1 ]; then
17124                 mdtfree1=$(do_facet $facet \
17125                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17126                 # decrease in usage from $size_tmp to new $size_dom
17127                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17128                   $(((size_tmp - size_dom) / 1024)) ] ||
17129                         error "MDT free space is wrong after truncate: " \
17130                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17131         fi
17132
17133         # append
17134         cat $tmp >> $dom
17135         sync
17136         size_dom=$((size_dom + size_tmp))
17137         [ $(stat -c%s $dom) == $size_dom ] ||
17138                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17139         if [ $space_check == 1 ]; then
17140                 mdtfree2=$(do_facet $facet \
17141                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17142                 # increase in usage by $size_tmp from previous
17143                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17144                         error "MDT free space is wrong after append: " \
17145                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17146         fi
17147
17148         # delete
17149         rm $dom
17150         if [ $space_check == 1 ]; then
17151                 mdtfree1=$(do_facet $facet \
17152                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17153                 # decrease in usage by $size_dom from previous
17154                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17155                         error "MDT free space is wrong after removal: " \
17156                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17157         fi
17158
17159         # combined striping
17160         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17161                 error "Can't create DoM + OST striping"
17162
17163         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17164         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17165         # check also direct IO along write
17166         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17167         sync
17168         cmp $tmp $dom || error "file data is different"
17169         [ $(stat -c%s $dom) == $size_tmp ] ||
17170                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17171         rm $dom $tmp
17172
17173         return 0
17174 }
17175 run_test 270a "DoM: basic functionality tests"
17176
17177 test_270b() {
17178         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17179                 skip "Need MDS version at least 2.10.55"
17180
17181         local dom=$DIR/$tdir/dom_file
17182         local max_size=1048576
17183
17184         mkdir -p $DIR/$tdir
17185         $LFS setstripe -E $max_size -L mdt $dom
17186
17187         # truncate over the limit
17188         $TRUNCATE $dom $(($max_size + 1)) &&
17189                 error "successful truncate over the maximum size"
17190         # write over the limit
17191         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17192                 error "successful write over the maximum size"
17193         # append over the limit
17194         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17195         echo "12345" >> $dom && error "successful append over the maximum size"
17196         rm $dom
17197
17198         return 0
17199 }
17200 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17201
17202 test_270c() {
17203         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17204                 skip "Need MDS version at least 2.10.55"
17205
17206         mkdir -p $DIR/$tdir
17207         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17208
17209         # check files inherit DoM EA
17210         touch $DIR/$tdir/first
17211         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17212                 error "bad pattern"
17213         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17214                 error "bad stripe count"
17215         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17216                 error "bad stripe size"
17217
17218         # check directory inherits DoM EA and uses it as default
17219         mkdir $DIR/$tdir/subdir
17220         touch $DIR/$tdir/subdir/second
17221         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17222                 error "bad pattern in sub-directory"
17223         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17224                 error "bad stripe count in sub-directory"
17225         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17226                 error "bad stripe size in sub-directory"
17227         return 0
17228 }
17229 run_test 270c "DoM: DoM EA inheritance tests"
17230
17231 test_270d() {
17232         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17233                 skip "Need MDS version at least 2.10.55"
17234
17235         mkdir -p $DIR/$tdir
17236         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17237
17238         # inherit default DoM striping
17239         mkdir $DIR/$tdir/subdir
17240         touch $DIR/$tdir/subdir/f1
17241
17242         # change default directory striping
17243         $LFS setstripe -c 1 $DIR/$tdir/subdir
17244         touch $DIR/$tdir/subdir/f2
17245         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17246                 error "wrong default striping in file 2"
17247         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17248                 error "bad pattern in file 2"
17249         return 0
17250 }
17251 run_test 270d "DoM: change striping from DoM to RAID0"
17252
17253 test_270e() {
17254         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17255                 skip "Need MDS version at least 2.10.55"
17256
17257         mkdir -p $DIR/$tdir/dom
17258         mkdir -p $DIR/$tdir/norm
17259         DOMFILES=20
17260         NORMFILES=10
17261         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17262         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17263
17264         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17265         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17266
17267         # find DoM files by layout
17268         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17269         [ $NUM -eq  $DOMFILES ] ||
17270                 error "lfs find -L: found $NUM, expected $DOMFILES"
17271         echo "Test 1: lfs find 20 DOM files by layout: OK"
17272
17273         # there should be 1 dir with default DOM striping
17274         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17275         [ $NUM -eq  1 ] ||
17276                 error "lfs find -L: found $NUM, expected 1 dir"
17277         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17278
17279         # find DoM files by stripe size
17280         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17281         [ $NUM -eq  $DOMFILES ] ||
17282                 error "lfs find -S: found $NUM, expected $DOMFILES"
17283         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17284
17285         # find files by stripe offset except DoM files
17286         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17287         [ $NUM -eq  $NORMFILES ] ||
17288                 error "lfs find -i: found $NUM, expected $NORMFILES"
17289         echo "Test 5: lfs find no DOM files by stripe index: OK"
17290         return 0
17291 }
17292 run_test 270e "DoM: lfs find with DoM files test"
17293
17294 test_270f() {
17295         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17296                 skip "Need MDS version at least 2.10.55"
17297
17298         local mdtname=${FSNAME}-MDT0000-mdtlov
17299         local dom=$DIR/$tdir/dom_file
17300         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17301                                                 lod.$mdtname.dom_stripesize)
17302         local dom_limit=131072
17303
17304         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17305         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17306                                                 lod.$mdtname.dom_stripesize)
17307         [ ${dom_limit} -eq ${dom_current} ] ||
17308                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17309
17310         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17311         $LFS setstripe -d $DIR/$tdir
17312         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17313                 error "Can't set directory default striping"
17314
17315         # exceed maximum stripe size
17316         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17317                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17318         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17319                 error "Able to create DoM component size more than LOD limit"
17320
17321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17322         dom_current=$(do_facet mds1 $LCTL get_param -n \
17323                                                 lod.$mdtname.dom_stripesize)
17324         [ 0 -eq ${dom_current} ] ||
17325                 error "Can't set zero DoM stripe limit"
17326         rm $dom
17327
17328         # attempt to create DoM file on server with disabled DoM should
17329         # remove DoM entry from layout and be succeed
17330         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17331                 error "Can't create DoM file (DoM is disabled)"
17332         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17333                 error "File has DoM component while DoM is disabled"
17334         rm $dom
17335
17336         # attempt to create DoM file with only DoM stripe should return error
17337         $LFS setstripe -E $dom_limit -L mdt $dom &&
17338                 error "Able to create DoM-only file while DoM is disabled"
17339
17340         # too low values to be aligned with smallest stripe size 64K
17341         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17342         dom_current=$(do_facet mds1 $LCTL get_param -n \
17343                                                 lod.$mdtname.dom_stripesize)
17344         [ 30000 -eq ${dom_current} ] &&
17345                 error "Can set too small DoM stripe limit"
17346
17347         # 64K is a minimal stripe size in Lustre, expect limit of that size
17348         [ 65536 -eq ${dom_current} ] ||
17349                 error "Limit is not set to 64K but ${dom_current}"
17350
17351         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17352         dom_current=$(do_facet mds1 $LCTL get_param -n \
17353                                                 lod.$mdtname.dom_stripesize)
17354         echo $dom_current
17355         [ 2147483648 -eq ${dom_current} ] &&
17356                 error "Can set too large DoM stripe limit"
17357
17358         do_facet mds1 $LCTL set_param -n \
17359                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17360         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17361                 error "Can't create DoM component size after limit change"
17362         do_facet mds1 $LCTL set_param -n \
17363                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17364         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17365                 error "Can't create DoM file after limit decrease"
17366         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17367                 error "Can create big DoM component after limit decrease"
17368         touch ${dom}_def ||
17369                 error "Can't create file with old default layout"
17370
17371         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17372         return 0
17373 }
17374 run_test 270f "DoM: maximum DoM stripe size checks"
17375
17376 test_271a() {
17377         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17378                 skip "Need MDS version at least 2.10.55"
17379
17380         local dom=$DIR/$tdir/dom
17381
17382         mkdir -p $DIR/$tdir
17383
17384         $LFS setstripe -E 1024K -L mdt $dom
17385
17386         lctl set_param -n mdc.*.stats=clear
17387         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17388         cat $dom > /dev/null
17389         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17390         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17391         ls $dom
17392         rm -f $dom
17393 }
17394 run_test 271a "DoM: data is cached for read after write"
17395
17396 test_271b() {
17397         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17398                 skip "Need MDS version at least 2.10.55"
17399
17400         local dom=$DIR/$tdir/dom
17401
17402         mkdir -p $DIR/$tdir
17403
17404         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17405
17406         lctl set_param -n mdc.*.stats=clear
17407         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17408         cancel_lru_locks mdc
17409         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17410         # second stat to check size is cached on client
17411         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17412         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17413         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17414         rm -f $dom
17415 }
17416 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17417
17418 test_271ba() {
17419         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17420                 skip "Need MDS version at least 2.10.55"
17421
17422         local dom=$DIR/$tdir/dom
17423
17424         mkdir -p $DIR/$tdir
17425
17426         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17427
17428         lctl set_param -n mdc.*.stats=clear
17429         lctl set_param -n osc.*.stats=clear
17430         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17431         cancel_lru_locks mdc
17432         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17433         # second stat to check size is cached on client
17434         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17435         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17436         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17437         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17438         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17439         rm -f $dom
17440 }
17441 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17442
17443
17444 get_mdc_stats() {
17445         local mdtidx=$1
17446         local param=$2
17447         local mdt=MDT$(printf %04x $mdtidx)
17448
17449         if [ -z $param ]; then
17450                 lctl get_param -n mdc.*$mdt*.stats
17451         else
17452                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17453         fi
17454 }
17455
17456 test_271c() {
17457         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17458                 skip "Need MDS version at least 2.10.55"
17459
17460         local dom=$DIR/$tdir/dom
17461
17462         mkdir -p $DIR/$tdir
17463
17464         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17465
17466         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17467         local facet=mds$((mdtidx + 1))
17468
17469         cancel_lru_locks mdc
17470         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17471         createmany -o $dom 1000
17472         lctl set_param -n mdc.*.stats=clear
17473         smalliomany -w $dom 1000 200
17474         get_mdc_stats $mdtidx
17475         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17476         # Each file has 1 open, 1 IO enqueues, total 2000
17477         # but now we have also +1 getxattr for security.capability, total 3000
17478         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17479         unlinkmany $dom 1000
17480
17481         cancel_lru_locks mdc
17482         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17483         createmany -o $dom 1000
17484         lctl set_param -n mdc.*.stats=clear
17485         smalliomany -w $dom 1000 200
17486         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17487         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17488         # for OPEN and IO lock.
17489         [ $((enq - enq_2)) -ge 1000 ] ||
17490                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17491         unlinkmany $dom 1000
17492         return 0
17493 }
17494 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17495
17496 cleanup_271def_tests() {
17497         trap 0
17498         rm -f $1
17499 }
17500
17501 test_271d() {
17502         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17503                 skip "Need MDS version at least 2.10.57"
17504
17505         local dom=$DIR/$tdir/dom
17506         local tmp=$TMP/$tfile
17507         trap "cleanup_271def_tests $tmp" EXIT
17508
17509         mkdir -p $DIR/$tdir
17510
17511         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17512
17513         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17514
17515         cancel_lru_locks mdc
17516         dd if=/dev/urandom of=$tmp bs=1000 count=1
17517         dd if=$tmp of=$dom bs=1000 count=1
17518         cancel_lru_locks mdc
17519
17520         cat /etc/hosts >> $tmp
17521         lctl set_param -n mdc.*.stats=clear
17522
17523         # append data to the same file it should update local page
17524         echo "Append to the same page"
17525         cat /etc/hosts >> $dom
17526         local num=$(get_mdc_stats $mdtidx ost_read)
17527         local ra=$(get_mdc_stats $mdtidx req_active)
17528         local rw=$(get_mdc_stats $mdtidx req_waittime)
17529
17530         [ -z $num ] || error "$num READ RPC occured"
17531         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17532         echo "... DONE"
17533
17534         # compare content
17535         cmp $tmp $dom || error "file miscompare"
17536
17537         cancel_lru_locks mdc
17538         lctl set_param -n mdc.*.stats=clear
17539
17540         echo "Open and read file"
17541         cat $dom > /dev/null
17542         local num=$(get_mdc_stats $mdtidx ost_read)
17543         local ra=$(get_mdc_stats $mdtidx req_active)
17544         local rw=$(get_mdc_stats $mdtidx req_waittime)
17545
17546         [ -z $num ] || error "$num READ RPC occured"
17547         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17548         echo "... DONE"
17549
17550         # compare content
17551         cmp $tmp $dom || error "file miscompare"
17552
17553         return 0
17554 }
17555 run_test 271d "DoM: read on open (1K file in reply buffer)"
17556
17557 test_271e() {
17558         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17559                 skip "Need MDS version at least 2.10.57"
17560
17561         local dom=$DIR/$tdir/dom
17562         local tmp=$TMP/${tfile}.data
17563         trap "cleanup_271def_tests $tmp" EXIT
17564
17565         mkdir -p $DIR/$tdir
17566
17567         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17568
17569         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17570
17571         cancel_lru_locks mdc
17572         dd if=/dev/urandom of=$tmp bs=30K count=1
17573         dd if=$tmp of=$dom bs=30K count=1
17574         cancel_lru_locks mdc
17575         cat /etc/hosts >> $tmp
17576         lctl set_param -n mdc.*.stats=clear
17577
17578         echo "Append to the same page"
17579         cat /etc/hosts >> $dom
17580
17581         local num=$(get_mdc_stats $mdtidx ost_read)
17582         local ra=$(get_mdc_stats $mdtidx req_active)
17583         local rw=$(get_mdc_stats $mdtidx req_waittime)
17584
17585         [ -z $num ] || error "$num READ RPC occured"
17586         # Reply buffer can be adjusted for larger buffer by resend
17587         echo "... DONE with $((ra - rw)) resends"
17588
17589         # compare content
17590         cmp $tmp $dom || error "file miscompare"
17591
17592         cancel_lru_locks mdc
17593         lctl set_param -n mdc.*.stats=clear
17594
17595         echo "Open and read file"
17596         cat $dom > /dev/null
17597         local num=$(get_mdc_stats $mdtidx ost_read)
17598         local ra=$(get_mdc_stats $mdtidx req_active)
17599         local rw=$(get_mdc_stats $mdtidx req_waittime)
17600
17601         [ -z $num ] || error "$num READ RPC occured"
17602         # Reply buffer can be adjusted for larger buffer by resend
17603         echo "... DONE with $((ra - rw)) resends"
17604
17605         # compare content
17606         cmp $tmp $dom || error "file miscompare"
17607
17608         return 0
17609 }
17610 run_test 271e "DoM: read on open (30K file with reply buffer adjusting)"
17611
17612 test_271f() {
17613         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17614                 skip "Need MDS version at least 2.10.57"
17615
17616         local dom=$DIR/$tdir/dom
17617         local tmp=$TMP/$tfile
17618         trap "cleanup_271def_tests $tmp" EXIT
17619
17620         mkdir -p $DIR/$tdir
17621
17622         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17623
17624         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17625
17626         cancel_lru_locks mdc
17627         dd if=/dev/urandom of=$tmp bs=200000 count=1
17628         dd if=$tmp of=$dom bs=200000 count=1
17629         cancel_lru_locks mdc
17630         cat /etc/hosts >> $tmp
17631         lctl set_param -n mdc.*.stats=clear
17632
17633         echo "Append to the same page"
17634         cat /etc/hosts >> $dom
17635         local num=$(get_mdc_stats $mdtidx ost_read)
17636         local ra=$(get_mdc_stats $mdtidx req_active)
17637         local rw=$(get_mdc_stats $mdtidx req_waittime)
17638
17639         [ -z $num ] || error "$num READ RPC occured"
17640         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17641         echo "... DONE"
17642
17643         # compare content
17644         cmp $tmp $dom || error "file miscompare"
17645
17646         cancel_lru_locks mdc
17647         lctl set_param -n mdc.*.stats=clear
17648
17649         echo "Open and read file"
17650         cat $dom > /dev/null
17651         local num=$(get_mdc_stats $mdtidx ost_read)
17652         local ra=$(get_mdc_stats $mdtidx req_active)
17653         local rw=$(get_mdc_stats $mdtidx req_waittime)
17654
17655         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17656         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17657         echo "... DONE"
17658
17659         # compare content
17660         cmp $tmp $dom || error "file miscompare"
17661
17662         return 0
17663 }
17664 run_test 271f "DoM: read on open (200K file and read tail)"
17665
17666 test_272a() {
17667         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17668                 skip "Need MDS version at least 2.11.50"
17669
17670         local dom=$DIR/$tdir/dom
17671         mkdir -p $DIR/$tdir
17672
17673         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17674         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17675                 error "failed to write data into $dom"
17676         local old_md5=$(md5sum $dom)
17677
17678         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17679                 error "failed to migrate to the same DoM component"
17680
17681         local new_md5=$(md5sum $dom)
17682
17683         [ "$old_md5" == "$new_md5" ] ||
17684                 error "md5sum differ: $old_md5, $new_md5"
17685
17686         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17687                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17688 }
17689 run_test 272a "DoM migration: new layout with the same DOM component"
17690
17691 test_272b() {
17692         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17693                 skip "Need MDS version at least 2.11.50"
17694
17695         local dom=$DIR/$tdir/dom
17696         mkdir -p $DIR/$tdir
17697         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17698
17699         local mdtidx=$($LFS getstripe -m $dom)
17700         local mdtname=MDT$(printf %04x $mdtidx)
17701         local facet=mds$((mdtidx + 1))
17702
17703         local mdtfree1=$(do_facet $facet \
17704                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17705         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17706                 error "failed to write data into $dom"
17707         local old_md5=$(md5sum $dom)
17708         cancel_lru_locks mdc
17709         local mdtfree1=$(do_facet $facet \
17710                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17711
17712         $LFS migrate -c2 $dom ||
17713                 error "failed to migrate to the new composite layout"
17714         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17715                 error "MDT stripe was not removed"
17716
17717         cancel_lru_locks mdc
17718         local new_md5=$(md5sum $dom)
17719         [ "$old_md5" != "$new_md5" ] &&
17720                 error "$old_md5 != $new_md5"
17721
17722         # Skip free space checks with ZFS
17723         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17724                 local mdtfree2=$(do_facet $facet \
17725                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17726                 [ $mdtfree2 -gt $mdtfree1 ] ||
17727                         error "MDT space is not freed after migration"
17728         fi
17729         return 0
17730 }
17731 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17732
17733 test_272c() {
17734         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17735                 skip "Need MDS version at least 2.11.50"
17736
17737         local dom=$DIR/$tdir/$tfile
17738         mkdir -p $DIR/$tdir
17739         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17740
17741         local mdtidx=$($LFS getstripe -m $dom)
17742         local mdtname=MDT$(printf %04x $mdtidx)
17743         local facet=mds$((mdtidx + 1))
17744
17745         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17746                 error "failed to write data into $dom"
17747         local old_md5=$(md5sum $dom)
17748         cancel_lru_locks mdc
17749         local mdtfree1=$(do_facet $facet \
17750                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17751
17752         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17753                 error "failed to migrate to the new composite layout"
17754         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17755                 error "MDT stripe was not removed"
17756
17757         cancel_lru_locks mdc
17758         local new_md5=$(md5sum $dom)
17759         [ "$old_md5" != "$new_md5" ] &&
17760                 error "$old_md5 != $new_md5"
17761
17762         # Skip free space checks with ZFS
17763         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17764                 local mdtfree2=$(do_facet $facet \
17765                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17766                 [ $mdtfree2 -gt $mdtfree1 ] ||
17767                         error "MDS space is not freed after migration"
17768         fi
17769         return 0
17770 }
17771 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17772
17773 test_273a() {
17774         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17775                 skip "Need MDS version at least 2.11.50"
17776
17777         # Layout swap cannot be done if either file has DOM component,
17778         # this will never be supported, migration should be used instead
17779
17780         local dom=$DIR/$tdir/$tfile
17781         mkdir -p $DIR/$tdir
17782
17783         $LFS setstripe -c2 ${dom}_plain
17784         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17785         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17786                 error "can swap layout with DoM component"
17787         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17788                 error "can swap layout with DoM component"
17789
17790         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17791         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17792                 error "can swap layout with DoM component"
17793         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17794                 error "can swap layout with DoM component"
17795         return 0
17796 }
17797 run_test 273a "DoM: layout swapping should fail with DOM"
17798
17799 test_275() {
17800         remote_ost_nodsh && skip "remote OST with nodsh"
17801         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17802                 skip "Need OST version >= 2.10.57"
17803
17804         local file=$DIR/$tfile
17805         local oss
17806
17807         oss=$(comma_list $(osts_nodes))
17808
17809         dd if=/dev/urandom of=$file bs=1M count=2 ||
17810                 error "failed to create a file"
17811         cancel_lru_locks osc
17812
17813         #lock 1
17814         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17815                 error "failed to read a file"
17816
17817 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17818         $LCTL set_param fail_loc=0x8000031f
17819
17820         cancel_lru_locks osc &
17821         sleep 1
17822
17823 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17824         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17825         #IO takes another lock, but matches the PENDING one
17826         #and places it to the IO RPC
17827         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17828                 error "failed to read a file with PENDING lock"
17829 }
17830 run_test 275 "Read on a canceled duplicate lock"
17831
17832 test_276() {
17833         remote_ost_nodsh && skip "remote OST with nodsh"
17834         local pid
17835
17836         do_facet ost1 "(while true; do \
17837                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17838                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17839         pid=$!
17840
17841         for LOOP in $(seq 20); do
17842                 stop ost1
17843                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17844         done
17845         kill -9 $pid
17846         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17847                 rm $TMP/sanity_276_pid"
17848 }
17849 run_test 276 "Race between mount and obd_statfs"
17850
17851 cleanup_test_300() {
17852         trap 0
17853         umask $SAVE_UMASK
17854 }
17855 test_striped_dir() {
17856         local mdt_index=$1
17857         local stripe_count
17858         local stripe_index
17859
17860         mkdir -p $DIR/$tdir
17861
17862         SAVE_UMASK=$(umask)
17863         trap cleanup_test_300 RETURN EXIT
17864
17865         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17866                                                 $DIR/$tdir/striped_dir ||
17867                 error "set striped dir error"
17868
17869         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17870         [ "$mode" = "755" ] || error "expect 755 got $mode"
17871
17872         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17873                 error "getdirstripe failed"
17874         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17875         if [ "$stripe_count" != "2" ]; then
17876                 error "1:stripe_count is $stripe_count, expect 2"
17877         fi
17878         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17879         if [ "$stripe_count" != "2" ]; then
17880                 error "2:stripe_count is $stripe_count, expect 2"
17881         fi
17882
17883         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17884         if [ "$stripe_index" != "$mdt_index" ]; then
17885                 error "stripe_index is $stripe_index, expect $mdt_index"
17886         fi
17887
17888         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17889                 error "nlink error after create striped dir"
17890
17891         mkdir $DIR/$tdir/striped_dir/a
17892         mkdir $DIR/$tdir/striped_dir/b
17893
17894         stat $DIR/$tdir/striped_dir/a ||
17895                 error "create dir under striped dir failed"
17896         stat $DIR/$tdir/striped_dir/b ||
17897                 error "create dir under striped dir failed"
17898
17899         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17900                 error "nlink error after mkdir"
17901
17902         rmdir $DIR/$tdir/striped_dir/a
17903         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17904                 error "nlink error after rmdir"
17905
17906         rmdir $DIR/$tdir/striped_dir/b
17907         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17908                 error "nlink error after rmdir"
17909
17910         chattr +i $DIR/$tdir/striped_dir
17911         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17912                 error "immutable flags not working under striped dir!"
17913         chattr -i $DIR/$tdir/striped_dir
17914
17915         rmdir $DIR/$tdir/striped_dir ||
17916                 error "rmdir striped dir error"
17917
17918         cleanup_test_300
17919
17920         true
17921 }
17922
17923 test_300a() {
17924         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17925                 skip "skipped for lustre < 2.7.0"
17926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17928
17929         test_striped_dir 0 || error "failed on striped dir on MDT0"
17930         test_striped_dir 1 || error "failed on striped dir on MDT0"
17931 }
17932 run_test 300a "basic striped dir sanity test"
17933
17934 test_300b() {
17935         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17936                 skip "skipped for lustre < 2.7.0"
17937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17939
17940         local i
17941         local mtime1
17942         local mtime2
17943         local mtime3
17944
17945         test_mkdir $DIR/$tdir || error "mkdir fail"
17946         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17947                 error "set striped dir error"
17948         for i in {0..9}; do
17949                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17950                 sleep 1
17951                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17952                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17953                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17954                 sleep 1
17955                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17956                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17957                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17958         done
17959         true
17960 }
17961 run_test 300b "check ctime/mtime for striped dir"
17962
17963 test_300c() {
17964         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17965                 skip "skipped for lustre < 2.7.0"
17966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17968
17969         local file_count
17970
17971         mkdir -p $DIR/$tdir
17972         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17973                 error "set striped dir error"
17974
17975         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17976                 error "chown striped dir failed"
17977
17978         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17979                 error "create 5k files failed"
17980
17981         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17982
17983         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17984
17985         rm -rf $DIR/$tdir
17986 }
17987 run_test 300c "chown && check ls under striped directory"
17988
17989 test_300d() {
17990         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17991                 skip "skipped for lustre < 2.7.0"
17992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17994
17995         local stripe_count
17996         local file
17997
17998         mkdir -p $DIR/$tdir
17999         $LFS setstripe -c 2 $DIR/$tdir
18000
18001         #local striped directory
18002         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18003                 error "set striped dir error"
18004         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18005                 error "create 10 files failed"
18006
18007         #remote striped directory
18008         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18009                 error "set striped dir error"
18010         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18011                 error "create 10 files failed"
18012
18013         for file in $(find $DIR/$tdir); do
18014                 stripe_count=$($LFS getstripe -c $file)
18015                 [ $stripe_count -eq 2 ] ||
18016                         error "wrong stripe $stripe_count for $file"
18017         done
18018
18019         rm -rf $DIR/$tdir
18020 }
18021 run_test 300d "check default stripe under striped directory"
18022
18023 test_300e() {
18024         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18025                 skip "Need MDS version at least 2.7.55"
18026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18028
18029         local stripe_count
18030         local file
18031
18032         mkdir -p $DIR/$tdir
18033
18034         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18035                 error "set striped dir error"
18036
18037         touch $DIR/$tdir/striped_dir/a
18038         touch $DIR/$tdir/striped_dir/b
18039         touch $DIR/$tdir/striped_dir/c
18040
18041         mkdir $DIR/$tdir/striped_dir/dir_a
18042         mkdir $DIR/$tdir/striped_dir/dir_b
18043         mkdir $DIR/$tdir/striped_dir/dir_c
18044
18045         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18046                 error "set striped adir under striped dir error"
18047
18048         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18049                 error "set striped bdir under striped dir error"
18050
18051         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18052                 error "set striped cdir under striped dir error"
18053
18054         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18055                 error "rename dir under striped dir fails"
18056
18057         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18058                 error "rename dir under different stripes fails"
18059
18060         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18061                 error "rename file under striped dir should succeed"
18062
18063         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18064                 error "rename dir under striped dir should succeed"
18065
18066         rm -rf $DIR/$tdir
18067 }
18068 run_test 300e "check rename under striped directory"
18069
18070 test_300f() {
18071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18072         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18073         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18074                 skip "Need MDS version at least 2.7.55"
18075
18076         local stripe_count
18077         local file
18078
18079         rm -rf $DIR/$tdir
18080         mkdir -p $DIR/$tdir
18081
18082         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18083                 error "set striped dir error"
18084
18085         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18086                 error "set striped dir error"
18087
18088         touch $DIR/$tdir/striped_dir/a
18089         mkdir $DIR/$tdir/striped_dir/dir_a
18090         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18091                 error "create striped dir under striped dir fails"
18092
18093         touch $DIR/$tdir/striped_dir1/b
18094         mkdir $DIR/$tdir/striped_dir1/dir_b
18095         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18096                 error "create striped dir under striped dir fails"
18097
18098         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18099                 error "rename dir under different striped dir should fail"
18100
18101         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18102                 error "rename striped dir under diff striped dir should fail"
18103
18104         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18105                 error "rename file under diff striped dirs fails"
18106
18107         rm -rf $DIR/$tdir
18108 }
18109 run_test 300f "check rename cross striped directory"
18110
18111 test_300_check_default_striped_dir()
18112 {
18113         local dirname=$1
18114         local default_count=$2
18115         local default_index=$3
18116         local stripe_count
18117         local stripe_index
18118         local dir_stripe_index
18119         local dir
18120
18121         echo "checking $dirname $default_count $default_index"
18122         $LFS setdirstripe -D -c $default_count -i $default_index \
18123                                 -t all_char $DIR/$tdir/$dirname ||
18124                 error "set default stripe on striped dir error"
18125         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18126         [ $stripe_count -eq $default_count ] ||
18127                 error "expect $default_count get $stripe_count for $dirname"
18128
18129         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18130         [ $stripe_index -eq $default_index ] ||
18131                 error "expect $default_index get $stripe_index for $dirname"
18132
18133         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18134                                                 error "create dirs failed"
18135
18136         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18137         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18138         for dir in $(find $DIR/$tdir/$dirname/*); do
18139                 stripe_count=$($LFS getdirstripe -c $dir)
18140                 [ $stripe_count -eq $default_count ] ||
18141                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
18142                 error "stripe count $default_count != $stripe_count for $dir"
18143
18144                 stripe_index=$($LFS getdirstripe -i $dir)
18145                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
18146                         error "$stripe_index != $default_index for $dir"
18147
18148                 #check default stripe
18149                 stripe_count=$($LFS getdirstripe -D -c $dir)
18150                 [ $stripe_count -eq $default_count ] ||
18151                 error "default count $default_count != $stripe_count for $dir"
18152
18153                 stripe_index=$($LFS getdirstripe -D -i $dir)
18154                 [ $stripe_index -eq $default_index ] ||
18155                 error "default index $default_index != $stripe_index for $dir"
18156         done
18157         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18158 }
18159
18160 test_300g() {
18161         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18162         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18163                 skip "Need MDS version at least 2.7.55"
18164
18165         local dir
18166         local stripe_count
18167         local stripe_index
18168
18169         mkdir $DIR/$tdir
18170         mkdir $DIR/$tdir/normal_dir
18171
18172         #Checking when client cache stripe index
18173         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18174         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18175                 error "create striped_dir failed"
18176
18177         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18178                 error "create dir0 fails"
18179         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18180         [ $stripe_index -eq 0 ] ||
18181                 error "dir0 expect index 0 got $stripe_index"
18182
18183         mkdir $DIR/$tdir/striped_dir/dir1 ||
18184                 error "create dir1 fails"
18185         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18186         [ $stripe_index -eq 1 ] ||
18187                 error "dir1 expect index 1 got $stripe_index"
18188
18189         #check default stripe count/stripe index
18190         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18191         test_300_check_default_striped_dir normal_dir 1 0
18192         test_300_check_default_striped_dir normal_dir 2 1
18193         test_300_check_default_striped_dir normal_dir 2 -1
18194
18195         #delete default stripe information
18196         echo "delete default stripeEA"
18197         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18198                 error "set default stripe on striped dir error"
18199
18200         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18201         for dir in $(find $DIR/$tdir/normal_dir/*); do
18202                 stripe_count=$($LFS getdirstripe -c $dir)
18203                 [ $stripe_count -eq 0 ] ||
18204                         error "expect 1 get $stripe_count for $dir"
18205                 stripe_index=$($LFS getdirstripe -i $dir)
18206                 [ $stripe_index -eq 0 ] ||
18207                         error "expect 0 get $stripe_index for $dir"
18208         done
18209 }
18210 run_test 300g "check default striped directory for normal directory"
18211
18212 test_300h() {
18213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18214         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18215                 skip "Need MDS version at least 2.7.55"
18216
18217         local dir
18218         local stripe_count
18219
18220         mkdir $DIR/$tdir
18221         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18222                 error "set striped dir error"
18223
18224         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18225         test_300_check_default_striped_dir striped_dir 1 0
18226         test_300_check_default_striped_dir striped_dir 2 1
18227         test_300_check_default_striped_dir striped_dir 2 -1
18228
18229         #delete default stripe information
18230         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18231                 error "set default stripe on striped dir error"
18232
18233         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18234         for dir in $(find $DIR/$tdir/striped_dir/*); do
18235                 stripe_count=$($LFS getdirstripe -c $dir)
18236                 [ $stripe_count -eq 0 ] ||
18237                         error "expect 1 get $stripe_count for $dir"
18238         done
18239 }
18240 run_test 300h "check default striped directory for striped directory"
18241
18242 test_300i() {
18243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18244         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18245         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18246                 skip "Need MDS version at least 2.7.55"
18247
18248         local stripe_count
18249         local file
18250
18251         mkdir $DIR/$tdir
18252
18253         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18254                 error "set striped dir error"
18255
18256         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18257                 error "create files under striped dir failed"
18258
18259         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18260                 error "set striped hashdir error"
18261
18262         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18263                 error "create dir0 under hash dir failed"
18264         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18265                 error "create dir1 under hash dir failed"
18266
18267         # unfortunately, we need to umount to clear dir layout cache for now
18268         # once we fully implement dir layout, we can drop this
18269         umount_client $MOUNT || error "umount failed"
18270         mount_client $MOUNT || error "mount failed"
18271
18272         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18273         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18274         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18275
18276         #set the stripe to be unknown hash type
18277         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18278         $LCTL set_param fail_loc=0x1901
18279         for ((i = 0; i < 10; i++)); do
18280                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18281                         error "stat f-$i failed"
18282                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18283         done
18284
18285         touch $DIR/$tdir/striped_dir/f0 &&
18286                 error "create under striped dir with unknown hash should fail"
18287
18288         $LCTL set_param fail_loc=0
18289
18290         umount_client $MOUNT || error "umount failed"
18291         mount_client $MOUNT || error "mount failed"
18292
18293         return 0
18294 }
18295 run_test 300i "client handle unknown hash type striped directory"
18296
18297 test_300j() {
18298         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18300         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18301                 skip "Need MDS version at least 2.7.55"
18302
18303         local stripe_count
18304         local file
18305
18306         mkdir $DIR/$tdir
18307
18308         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18309         $LCTL set_param fail_loc=0x1702
18310         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18311                 error "set striped dir error"
18312
18313         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18314                 error "create files under striped dir failed"
18315
18316         $LCTL set_param fail_loc=0
18317
18318         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18319
18320         return 0
18321 }
18322 run_test 300j "test large update record"
18323
18324 test_300k() {
18325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18327         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18328                 skip "Need MDS version at least 2.7.55"
18329
18330         # this test needs a huge transaction
18331         local kb
18332         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18333         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18334
18335         local stripe_count
18336         local file
18337
18338         mkdir $DIR/$tdir
18339
18340         #define OBD_FAIL_LARGE_STRIPE   0x1703
18341         $LCTL set_param fail_loc=0x1703
18342         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18343                 error "set striped dir error"
18344         $LCTL set_param fail_loc=0
18345
18346         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18347                 error "getstripeddir fails"
18348         rm -rf $DIR/$tdir/striped_dir ||
18349                 error "unlink striped dir fails"
18350
18351         return 0
18352 }
18353 run_test 300k "test large striped directory"
18354
18355 test_300l() {
18356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18358         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18359                 skip "Need MDS version at least 2.7.55"
18360
18361         local stripe_index
18362
18363         test_mkdir -p $DIR/$tdir/striped_dir
18364         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18365                         error "chown $RUNAS_ID failed"
18366         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18367                 error "set default striped dir failed"
18368
18369         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18370         $LCTL set_param fail_loc=0x80000158
18371         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18372
18373         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18374         [ $stripe_index -eq 1 ] ||
18375                 error "expect 1 get $stripe_index for $dir"
18376 }
18377 run_test 300l "non-root user to create dir under striped dir with stale layout"
18378
18379 test_300m() {
18380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18381         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18382         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18383                 skip "Need MDS version at least 2.7.55"
18384
18385         mkdir -p $DIR/$tdir/striped_dir
18386         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18387                 error "set default stripes dir error"
18388
18389         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18390
18391         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18392         [ $stripe_count -eq 0 ] ||
18393                         error "expect 0 get $stripe_count for a"
18394
18395         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18396                 error "set default stripes dir error"
18397
18398         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18399
18400         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18401         [ $stripe_count -eq 0 ] ||
18402                         error "expect 0 get $stripe_count for b"
18403
18404         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18405                 error "set default stripes dir error"
18406
18407         mkdir $DIR/$tdir/striped_dir/c &&
18408                 error "default stripe_index is invalid, mkdir c should fails"
18409
18410         rm -rf $DIR/$tdir || error "rmdir fails"
18411 }
18412 run_test 300m "setstriped directory on single MDT FS"
18413
18414 cleanup_300n() {
18415         local list=$(comma_list $(mdts_nodes))
18416
18417         trap 0
18418         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18419 }
18420
18421 test_300n() {
18422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18423         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18424         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18425                 skip "Need MDS version at least 2.7.55"
18426         remote_mds_nodsh && skip "remote MDS with nodsh"
18427
18428         local stripe_index
18429         local list=$(comma_list $(mdts_nodes))
18430
18431         trap cleanup_300n RETURN EXIT
18432         mkdir -p $DIR/$tdir
18433         chmod 777 $DIR/$tdir
18434         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18435                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18436                 error "create striped dir succeeds with gid=0"
18437
18438         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18439         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18440                 error "create striped dir fails with gid=-1"
18441
18442         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18443         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18444                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18445                 error "set default striped dir succeeds with gid=0"
18446
18447
18448         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18449         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18450                 error "set default striped dir fails with gid=-1"
18451
18452
18453         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18454         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18455                                         error "create test_dir fails"
18456         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18457                                         error "create test_dir1 fails"
18458         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18459                                         error "create test_dir2 fails"
18460         cleanup_300n
18461 }
18462 run_test 300n "non-root user to create dir under striped dir with default EA"
18463
18464 test_300o() {
18465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18467         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18468                 skip "Need MDS version at least 2.7.55"
18469
18470         local numfree1
18471         local numfree2
18472
18473         mkdir -p $DIR/$tdir
18474
18475         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18476         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18477         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
18478                 skip "not enough free inodes $numfree1 $numfree2"
18479         fi
18480
18481         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18482         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18483         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
18484                 skip "not enough free space $numfree1 $numfree2"
18485         fi
18486
18487         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18488                 error "setdirstripe fails"
18489
18490         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18491                 error "create dirs fails"
18492
18493         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18494         ls $DIR/$tdir/striped_dir > /dev/null ||
18495                 error "ls striped dir fails"
18496         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18497                 error "unlink big striped dir fails"
18498 }
18499 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18500
18501 test_300p() {
18502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18504         remote_mds_nodsh && skip "remote MDS with nodsh"
18505
18506         mkdir -p $DIR/$tdir
18507
18508         #define OBD_FAIL_OUT_ENOSPC     0x1704
18509         do_facet mds2 lctl set_param fail_loc=0x80001704
18510         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18511                  && error "create striped directory should fail"
18512
18513         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18514
18515         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18516         true
18517 }
18518 run_test 300p "create striped directory without space"
18519
18520 test_300q() {
18521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18523
18524         local fd=$(free_fd)
18525         local cmd="exec $fd<$tdir"
18526         cd $DIR
18527         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18528         eval $cmd
18529         cmd="exec $fd<&-"
18530         trap "eval $cmd" EXIT
18531         cd $tdir || error "cd $tdir fails"
18532         rmdir  ../$tdir || error "rmdir $tdir fails"
18533         mkdir local_dir && error "create dir succeeds"
18534         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18535         eval $cmd
18536         return 0
18537 }
18538 run_test 300q "create remote directory under orphan directory"
18539
18540 test_300r() {
18541         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18542                 skip "Need MDS version at least 2.7.55" && return
18543         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18544
18545         mkdir $DIR/$tdir
18546
18547         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18548                 error "set striped dir error"
18549
18550         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18551                 error "getstripeddir fails"
18552
18553         local stripe_count
18554         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18555                       awk '/lmv_stripe_count:/ { print $2 }')
18556
18557         [ $MDSCOUNT -ne $stripe_count ] &&
18558                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18559
18560         rm -rf $DIR/$tdir/striped_dir ||
18561                 error "unlink striped dir fails"
18562 }
18563 run_test 300r "test -1 striped directory"
18564
18565 prepare_remote_file() {
18566         mkdir $DIR/$tdir/src_dir ||
18567                 error "create remote source failed"
18568
18569         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18570                  error "cp to remote source failed"
18571         touch $DIR/$tdir/src_dir/a
18572
18573         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18574                 error "create remote target dir failed"
18575
18576         touch $DIR/$tdir/tgt_dir/b
18577
18578         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18579                 error "rename dir cross MDT failed!"
18580
18581         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18582                 error "src_child still exists after rename"
18583
18584         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18585                 error "missing file(a) after rename"
18586
18587         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18588                 error "diff after rename"
18589 }
18590
18591 test_310a() {
18592         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18594
18595         local remote_file=$DIR/$tdir/tgt_dir/b
18596
18597         mkdir -p $DIR/$tdir
18598
18599         prepare_remote_file || error "prepare remote file failed"
18600
18601         #open-unlink file
18602         $OPENUNLINK $remote_file $remote_file ||
18603                 error "openunlink $remote_file failed"
18604         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18605 }
18606 run_test 310a "open unlink remote file"
18607
18608 test_310b() {
18609         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18611
18612         local remote_file=$DIR/$tdir/tgt_dir/b
18613
18614         mkdir -p $DIR/$tdir
18615
18616         prepare_remote_file || error "prepare remote file failed"
18617
18618         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18619         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18620         $CHECKSTAT -t file $remote_file || error "check file failed"
18621 }
18622 run_test 310b "unlink remote file with multiple links while open"
18623
18624 test_310c() {
18625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18626         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18627
18628         local remote_file=$DIR/$tdir/tgt_dir/b
18629
18630         mkdir -p $DIR/$tdir
18631
18632         prepare_remote_file || error "prepare remote file failed"
18633
18634         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18635         multiop_bg_pause $remote_file O_uc ||
18636                         error "mulitop failed for remote file"
18637         MULTIPID=$!
18638         $MULTIOP $DIR/$tfile Ouc
18639         kill -USR1 $MULTIPID
18640         wait $MULTIPID
18641 }
18642 run_test 310c "open-unlink remote file with multiple links"
18643
18644 #LU-4825
18645 test_311() {
18646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18647         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18648         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18649                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18650         remote_mds_nodsh && skip "remote MDS with nodsh"
18651
18652         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18653         local mdts=$(comma_list $(mdts_nodes))
18654
18655         mkdir -p $DIR/$tdir
18656         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18657         createmany -o $DIR/$tdir/$tfile. 1000
18658
18659         # statfs data is not real time, let's just calculate it
18660         old_iused=$((old_iused + 1000))
18661
18662         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18663                         osp.*OST0000*MDT0000.create_count")
18664         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18665                                 osp.*OST0000*MDT0000.max_create_count")
18666         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18667
18668         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18669         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18670         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18671
18672         unlinkmany $DIR/$tdir/$tfile. 1000
18673
18674         do_nodes $mdts "$LCTL set_param -n \
18675                         osp.*OST0000*.max_create_count=$max_count"
18676         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18677                 do_nodes $mdts "$LCTL set_param -n \
18678                                 osp.*OST0000*.create_count=$count"
18679         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18680                         grep "=0" && error "create_count is zero"
18681
18682         local new_iused
18683         for i in $(seq 120); do
18684                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18685                 # system may be too busy to destroy all objs in time, use
18686                 # a somewhat small value to not fail autotest
18687                 [ $((old_iused - new_iused)) -gt 400 ] && break
18688                 sleep 1
18689         done
18690
18691         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18692         [ $((old_iused - new_iused)) -gt 400 ] ||
18693                 error "objs not destroyed after unlink"
18694 }
18695 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18696
18697 zfs_oid_to_objid()
18698 {
18699         local ost=$1
18700         local objid=$2
18701
18702         local vdevdir=$(dirname $(facet_vdevice $ost))
18703         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18704         local zfs_zapid=$(do_facet $ost $cmd |
18705                           grep -w "/O/0/d$((objid%32))" -C 5 |
18706                           awk '/Object/{getline; print $1}')
18707         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18708                           awk "/$objid = /"'{printf $3}')
18709
18710         echo $zfs_objid
18711 }
18712
18713 zfs_object_blksz() {
18714         local ost=$1
18715         local objid=$2
18716
18717         local vdevdir=$(dirname $(facet_vdevice $ost))
18718         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18719         local blksz=$(do_facet $ost $cmd $objid |
18720                       awk '/dblk/{getline; printf $4}')
18721
18722         case "${blksz: -1}" in
18723                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18724                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18725                 *) ;;
18726         esac
18727
18728         echo $blksz
18729 }
18730
18731 test_312() { # LU-4856
18732         remote_ost_nodsh && skip "remote OST with nodsh"
18733         [ "$ost1_FSTYPE" = "zfs" ] ||
18734                 skip_env "the test only applies to zfs"
18735
18736         local max_blksz=$(do_facet ost1 \
18737                           $ZFS get -p recordsize $(facet_device ost1) |
18738                           awk '!/VALUE/{print $3}')
18739
18740         # to make life a little bit easier
18741         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18742         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18743
18744         local tf=$DIR/$tdir/$tfile
18745         touch $tf
18746         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18747
18748         # Get ZFS object id
18749         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18750         # block size change by sequential overwrite
18751         local bs
18752
18753         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18754                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18755
18756                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18757                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18758         done
18759         rm -f $tf
18760
18761         # block size change by sequential append write
18762         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18763         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18764         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18765         local count
18766
18767         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18768                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18769                         oflag=sync conv=notrunc
18770
18771                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18772                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18773                         error "blksz error, actual $blksz, " \
18774                                 "expected: 2 * $count * $PAGE_SIZE"
18775         done
18776         rm -f $tf
18777
18778         # random write
18779         touch $tf
18780         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18781         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18782
18783         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18784         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18785         [ $blksz -eq $PAGE_SIZE ] ||
18786                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18787
18788         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18789         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18790         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18791
18792         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18793         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18794         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18795 }
18796 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18797
18798 test_313() {
18799         remote_ost_nodsh && skip "remote OST with nodsh"
18800
18801         local file=$DIR/$tfile
18802
18803         rm -f $file
18804         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18805
18806         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18807         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18808         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18809                 error "write should failed"
18810         do_facet ost1 "$LCTL set_param fail_loc=0"
18811         rm -f $file
18812 }
18813 run_test 313 "io should fail after last_rcvd update fail"
18814
18815 test_314() {
18816         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18817
18818         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18819         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18820         rm -f $DIR/$tfile
18821         wait_delete_completed
18822         do_facet ost1 "$LCTL set_param fail_loc=0"
18823 }
18824 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18825
18826 test_315() { # LU-618
18827         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18828
18829         local file=$DIR/$tfile
18830         rm -f $file
18831
18832         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18833                 error "multiop file write failed"
18834         $MULTIOP $file oO_RDONLY:r4063232_c &
18835         PID=$!
18836
18837         sleep 2
18838
18839         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18840         kill -USR1 $PID
18841
18842         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18843         rm -f $file
18844 }
18845 run_test 315 "read should be accounted"
18846
18847 test_316() {
18848         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18849         large_xattr_enabled || skip_env "ea_inode feature disabled"
18850
18851         rm -rf $DIR/$tdir/d
18852         mkdir -p $DIR/$tdir/d
18853         chown nobody $DIR/$tdir/d
18854         touch $DIR/$tdir/d/file
18855
18856         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18857 }
18858 run_test 316 "lfs mv"
18859
18860 test_317() {
18861         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18862                 skip "Need MDS version at least 2.11.53"
18863         local trunc_sz
18864         local grant_blk_size
18865
18866         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18867                 skip "LU-10370: no implementation for ZFS" && return
18868         fi
18869
18870         stack_trap "rm -f $DIR/$tfile" EXIT
18871         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18872                         awk '/grant_block_size:/ { print $2; exit; }')
18873         #
18874         # Create File of size 5M. Truncate it to below size's and verify
18875         # blocks count.
18876         #
18877         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18878                 error "Create file : $DIR/$tfile"
18879
18880         for trunc_sz in 2097152 4097 4000 509 0; do
18881                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18882                         error "truncate $tfile to $trunc_sz failed"
18883                 local sz=$(stat --format=%s $DIR/$tfile)
18884                 local blk=$(stat --format=%b $DIR/$tfile)
18885                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18886                                      grant_blk_size) * 8))
18887
18888                 if [[ $blk -ne $trunc_blk ]]; then
18889                         $(which stat) $DIR/$tfile
18890                         error "Expected Block $trunc_blk got $blk for $tfile"
18891                 fi
18892
18893                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18894                         error "Expected Size $trunc_sz got $sz for $tfile"
18895         done
18896
18897         #
18898         # sparse file test
18899         # Create file with a hole and write actual two blocks. Block count
18900         # must be 16.
18901         #
18902         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18903                 conv=fsync || error "Create file : $DIR/$tfile"
18904
18905         # Calculate the final truncate size.
18906         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18907
18908         #
18909         # truncate to size $trunc_sz bytes. Strip the last block
18910         # The block count must drop to 8
18911         #
18912         $TRUNCATE $DIR/$tfile $trunc_sz ||
18913                 error "truncate $tfile to $trunc_sz failed"
18914
18915         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18916         sz=$(stat --format=%s $DIR/$tfile)
18917         blk=$(stat --format=%b $DIR/$tfile)
18918
18919         if [[ $blk -ne $trunc_bsz ]]; then
18920                 $(which stat) $DIR/$tfile
18921                 error "Expected Block $trunc_bsz got $blk for $tfile"
18922         fi
18923
18924         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18925                 error "Expected Size $trunc_sz got $sz for $tfile"
18926 }
18927 run_test 317 "Verify blocks get correctly update after truncate"
18928
18929 test_319() {
18930         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18931
18932         local before=$(date +%s)
18933         local evict
18934         local mdir=$DIR/$tdir
18935         local file=$mdir/xxx
18936
18937         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18938         touch $file
18939
18940 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18941         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18942         $LFS mv -m1 $file &
18943
18944         sleep 1
18945         dd if=$file of=/dev/null
18946         wait
18947         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18948           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18949
18950         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18951 }
18952 run_test 319 "lost lease lock on migrate error"
18953
18954 test_fake_rw() {
18955         local read_write=$1
18956         if [ "$read_write" = "write" ]; then
18957                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18958         elif [ "$read_write" = "read" ]; then
18959                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18960         else
18961                 error "argument error"
18962         fi
18963
18964         # turn off debug for performance testing
18965         local saved_debug=$($LCTL get_param -n debug)
18966         $LCTL set_param debug=0
18967
18968         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18969
18970         # get ost1 size - lustre-OST0000
18971         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18972         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18973         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18974
18975         if [ "$read_write" = "read" ]; then
18976                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18977         fi
18978
18979         local start_time=$(date +%s.%N)
18980         $dd_cmd bs=1M count=$blocks oflag=sync ||
18981                 error "real dd $read_write error"
18982         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18983
18984         if [ "$read_write" = "write" ]; then
18985                 rm -f $DIR/$tfile
18986         fi
18987
18988         # define OBD_FAIL_OST_FAKE_RW           0x238
18989         do_facet ost1 $LCTL set_param fail_loc=0x238
18990
18991         local start_time=$(date +%s.%N)
18992         $dd_cmd bs=1M count=$blocks oflag=sync ||
18993                 error "fake dd $read_write error"
18994         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18995
18996         if [ "$read_write" = "write" ]; then
18997                 # verify file size
18998                 cancel_lru_locks osc
18999                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19000                         error "$tfile size not $blocks MB"
19001         fi
19002         do_facet ost1 $LCTL set_param fail_loc=0
19003
19004         echo "fake $read_write $duration_fake vs. normal $read_write" \
19005                 "$duration in seconds"
19006         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19007                 error_not_in_vm "fake write is slower"
19008
19009         $LCTL set_param -n debug="$saved_debug"
19010         rm -f $DIR/$tfile
19011 }
19012 test_399a() { # LU-7655 for OST fake write
19013         remote_ost_nodsh && skip "remote OST with nodsh"
19014
19015         test_fake_rw write
19016 }
19017 run_test 399a "fake write should not be slower than normal write"
19018
19019 test_399b() { # LU-8726 for OST fake read
19020         remote_ost_nodsh && skip "remote OST with nodsh"
19021         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19022                 skip_env "ldiskfs only test"
19023         fi
19024
19025         test_fake_rw read
19026 }
19027 run_test 399b "fake read should not be slower than normal read"
19028
19029 test_400a() { # LU-1606, was conf-sanity test_74
19030         if ! which $CC > /dev/null 2>&1; then
19031                 skip_env "$CC is not installed"
19032         fi
19033
19034         local extra_flags=''
19035         local out=$TMP/$tfile
19036         local prefix=/usr/include/lustre
19037         local prog
19038
19039         if ! [[ -d $prefix ]]; then
19040                 # Assume we're running in tree and fixup the include path.
19041                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19042                 extra_flags+=" -L$LUSTRE/utils/.lib"
19043         fi
19044
19045         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19046                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19047                         error "client api broken"
19048         done
19049         rm -f $out
19050 }
19051 run_test 400a "Lustre client api program can compile and link"
19052
19053 test_400b() { # LU-1606, LU-5011
19054         local header
19055         local out=$TMP/$tfile
19056         local prefix=/usr/include/linux/lustre
19057
19058         # We use a hard coded prefix so that this test will not fail
19059         # when run in tree. There are headers in lustre/include/lustre/
19060         # that are not packaged (like lustre_idl.h) and have more
19061         # complicated include dependencies (like config.h and lnet/types.h).
19062         # Since this test about correct packaging we just skip them when
19063         # they don't exist (see below) rather than try to fixup cppflags.
19064
19065         if ! which $CC > /dev/null 2>&1; then
19066                 skip_env "$CC is not installed"
19067         fi
19068
19069         for header in $prefix/*.h; do
19070                 if ! [[ -f "$header" ]]; then
19071                         continue
19072                 fi
19073
19074                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19075                         continue # lustre_ioctl.h is internal header
19076                 fi
19077
19078                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19079                         error "cannot compile '$header'"
19080         done
19081         rm -f $out
19082 }
19083 run_test 400b "packaged headers can be compiled"
19084
19085 test_401a() { #LU-7437
19086         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19087         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19088
19089         #count the number of parameters by "list_param -R"
19090         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19091         #count the number of parameters by listing proc files
19092         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19093         echo "proc_dirs='$proc_dirs'"
19094         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19095         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19096                       sort -u | wc -l)
19097
19098         [ $params -eq $procs ] ||
19099                 error "found $params parameters vs. $procs proc files"
19100
19101         # test the list_param -D option only returns directories
19102         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19103         #count the number of parameters by listing proc directories
19104         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19105                 sort -u | wc -l)
19106
19107         [ $params -eq $procs ] ||
19108                 error "found $params parameters vs. $procs proc files"
19109 }
19110 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19111
19112 test_401b() {
19113         local save=$($LCTL get_param -n jobid_var)
19114         local tmp=testing
19115
19116         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19117                 error "no error returned when setting bad parameters"
19118
19119         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19120         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19121
19122         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19123         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19124         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19125 }
19126 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19127
19128 test_401c() {
19129         local jobid_var_old=$($LCTL get_param -n jobid_var)
19130         local jobid_var_new
19131
19132         $LCTL set_param jobid_var= &&
19133                 error "no error returned for 'set_param a='"
19134
19135         jobid_var_new=$($LCTL get_param -n jobid_var)
19136         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19137                 error "jobid_var was changed by setting without value"
19138
19139         $LCTL set_param jobid_var &&
19140                 error "no error returned for 'set_param a'"
19141
19142         jobid_var_new=$($LCTL get_param -n jobid_var)
19143         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19144                 error "jobid_var was changed by setting without value"
19145 }
19146 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19147
19148 test_401d() {
19149         local jobid_var_old=$($LCTL get_param -n jobid_var)
19150         local jobid_var_new
19151         local new_value="foo=bar"
19152
19153         $LCTL set_param jobid_var=$new_value ||
19154                 error "'set_param a=b' did not accept a value containing '='"
19155
19156         jobid_var_new=$($LCTL get_param -n jobid_var)
19157         [[ "$jobid_var_new" == "$new_value" ]] ||
19158                 error "'set_param a=b' failed on a value containing '='"
19159
19160         # Reset the jobid_var to test the other format
19161         $LCTL set_param jobid_var=$jobid_var_old
19162         jobid_var_new=$($LCTL get_param -n jobid_var)
19163         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19164                 error "failed to reset jobid_var"
19165
19166         $LCTL set_param jobid_var $new_value ||
19167                 error "'set_param a b' did not accept a value containing '='"
19168
19169         jobid_var_new=$($LCTL get_param -n jobid_var)
19170         [[ "$jobid_var_new" == "$new_value" ]] ||
19171                 error "'set_param a b' failed on a value containing '='"
19172
19173         $LCTL set_param jobid_var $jobid_var_old
19174         jobid_var_new=$($LCTL get_param -n jobid_var)
19175         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19176                 error "failed to reset jobid_var"
19177 }
19178 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19179
19180 test_402() {
19181         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19182         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19183                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19184         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19185                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19186                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19187         remote_mds_nodsh && skip "remote MDS with nodsh"
19188
19189         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19190 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19191         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19192         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19193                 echo "Touch failed - OK"
19194 }
19195 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19196
19197 test_403() {
19198         local file1=$DIR/$tfile.1
19199         local file2=$DIR/$tfile.2
19200         local tfile=$TMP/$tfile
19201
19202         rm -f $file1 $file2 $tfile
19203
19204         touch $file1
19205         ln $file1 $file2
19206
19207         # 30 sec OBD_TIMEOUT in ll_getattr()
19208         # right before populating st_nlink
19209         $LCTL set_param fail_loc=0x80001409
19210         stat -c %h $file1 > $tfile &
19211
19212         # create an alias, drop all locks and reclaim the dentry
19213         < $file2
19214         cancel_lru_locks mdc
19215         cancel_lru_locks osc
19216         sysctl -w vm.drop_caches=2
19217
19218         wait
19219
19220         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19221
19222         rm -f $tfile $file1 $file2
19223 }
19224 run_test 403 "i_nlink should not drop to zero due to aliasing"
19225
19226 test_404() { # LU-6601
19227         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19228                 skip "Need server version newer than 2.8.52"
19229         remote_mds_nodsh && skip "remote MDS with nodsh"
19230
19231         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19232                 awk '/osp .*-osc-MDT/ { print $4}')
19233
19234         local osp
19235         for osp in $mosps; do
19236                 echo "Deactivate: " $osp
19237                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19238                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19239                         awk -vp=$osp '$4 == p { print $2 }')
19240                 [ $stat = IN ] || {
19241                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19242                         error "deactivate error"
19243                 }
19244                 echo "Activate: " $osp
19245                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19246                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19247                         awk -vp=$osp '$4 == p { print $2 }')
19248                 [ $stat = UP ] || {
19249                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19250                         error "activate error"
19251                 }
19252         done
19253 }
19254 run_test 404 "validate manual {de}activated works properly for OSPs"
19255
19256 test_405() {
19257         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19258         [ $MDS1_VERSION -lt $(version_code 2.6.92) -o \
19259         [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19260                 skip "Layout swap lock is not supported"
19261         check_swap_layouts_support
19262
19263         test_mkdir $DIR/$tdir
19264         swap_lock_test -d $DIR/$tdir ||
19265                 error "One layout swap locked test failed"
19266 }
19267 run_test 405 "Various layout swap lock tests"
19268
19269 test_406() {
19270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19271         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19272         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19274         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19275                 skip "Need MDS version at least 2.8.50"
19276
19277         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19278         local test_pool=$TESTNAME
19279
19280         if ! combined_mgs_mds ; then
19281                 mount_mgs_client
19282         fi
19283         pool_add $test_pool || error "pool_add failed"
19284         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19285                 error "pool_add_targets failed"
19286
19287         save_layout_restore_at_exit $MOUNT
19288
19289         # parent set default stripe count only, child will stripe from both
19290         # parent and fs default
19291         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19292                 error "setstripe $MOUNT failed"
19293         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19294         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19295         for i in $(seq 10); do
19296                 local f=$DIR/$tdir/$tfile.$i
19297                 touch $f || error "touch failed"
19298                 local count=$($LFS getstripe -c $f)
19299                 [ $count -eq $OSTCOUNT ] ||
19300                         error "$f stripe count $count != $OSTCOUNT"
19301                 local offset=$($LFS getstripe -i $f)
19302                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19303                 local size=$($LFS getstripe -S $f)
19304                 [ $size -eq $((def_stripe_size * 2)) ] ||
19305                         error "$f stripe size $size != $((def_stripe_size * 2))"
19306                 local pool=$($LFS getstripe -p $f)
19307                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19308         done
19309
19310         # change fs default striping, delete parent default striping, now child
19311         # will stripe from new fs default striping only
19312         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19313                 error "change $MOUNT default stripe failed"
19314         $LFS setstripe -c 0 $DIR/$tdir ||
19315                 error "delete $tdir default stripe failed"
19316         for i in $(seq 11 20); do
19317                 local f=$DIR/$tdir/$tfile.$i
19318                 touch $f || error "touch $f failed"
19319                 local count=$($LFS getstripe -c $f)
19320                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19321                 local offset=$($LFS getstripe -i $f)
19322                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19323                 local size=$($LFS getstripe -S $f)
19324                 [ $size -eq $def_stripe_size ] ||
19325                         error "$f stripe size $size != $def_stripe_size"
19326                 local pool=$($LFS getstripe -p $f)
19327                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19328         done
19329
19330         unlinkmany $DIR/$tdir/$tfile. 1 20
19331
19332         local f=$DIR/$tdir/$tfile
19333         pool_remove_all_targets $test_pool $f
19334         pool_remove $test_pool $f
19335
19336         if ! combined_mgs_mds ; then
19337                 umount_mgs_client
19338         fi
19339 }
19340 run_test 406 "DNE support fs default striping"
19341
19342 test_407() {
19343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19344         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19345                 skip "Need MDS version at least 2.8.55"
19346         remote_mds_nodsh && skip "remote MDS with nodsh"
19347
19348         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19349                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19350         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19351                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19352         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19353
19354         #define OBD_FAIL_DT_TXN_STOP    0x2019
19355         for idx in $(seq $MDSCOUNT); do
19356                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19357         done
19358         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19359         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19360                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19361         true
19362 }
19363 run_test 407 "transaction fail should cause operation fail"
19364
19365 test_408() {
19366         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19367
19368         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19369         lctl set_param fail_loc=0x8000040a
19370         # let ll_prepare_partial_page() fail
19371         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19372
19373         rm -f $DIR/$tfile
19374
19375         # create at least 100 unused inodes so that
19376         # shrink_icache_memory(0) should not return 0
19377         touch $DIR/$tfile-{0..100}
19378         rm -f $DIR/$tfile-{0..100}
19379         sync
19380
19381         echo 2 > /proc/sys/vm/drop_caches
19382 }
19383 run_test 408 "drop_caches should not hang due to page leaks"
19384
19385 test_409()
19386 {
19387         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19388
19389         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19390         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19391         touch $DIR/$tdir/guard || error "(2) Fail to create"
19392
19393         local PREFIX=$(str_repeat 'A' 128)
19394         echo "Create 1K hard links start at $(date)"
19395         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19396                 error "(3) Fail to hard link"
19397
19398         echo "Links count should be right although linkEA overflow"
19399         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19400         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19401         [ $linkcount -eq 1001 ] ||
19402                 error "(5) Unexpected hard links count: $linkcount"
19403
19404         echo "List all links start at $(date)"
19405         ls -l $DIR/$tdir/foo > /dev/null ||
19406                 error "(6) Fail to list $DIR/$tdir/foo"
19407
19408         echo "Unlink hard links start at $(date)"
19409         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19410                 error "(7) Fail to unlink"
19411         echo "Unlink hard links finished at $(date)"
19412 }
19413 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19414
19415 test_410()
19416 {
19417         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19418                 skip "Need client version at least 2.9.59"
19419
19420         # Create a file, and stat it from the kernel
19421         local testfile=$DIR/$tfile
19422         touch $testfile
19423
19424         local run_id=$RANDOM
19425         local my_ino=$(stat --format "%i" $testfile)
19426
19427         # Try to insert the module. This will always fail as the
19428         # module is designed to not be inserted.
19429         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19430             &> /dev/null
19431
19432         # Anything but success is a test failure
19433         dmesg | grep -q \
19434             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19435             error "no inode match"
19436 }
19437 run_test 410 "Test inode number returned from kernel thread"
19438
19439 cleanup_test411_cgroup() {
19440         trap 0
19441         rmdir "$1"
19442 }
19443
19444 test_411() {
19445         local cg_basedir=/sys/fs/cgroup/memory
19446         # LU-9966
19447         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19448                 skip "no setup for cgroup"
19449
19450         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19451                 error "test file creation failed"
19452         cancel_lru_locks osc
19453
19454         # Create a very small memory cgroup to force a slab allocation error
19455         local cgdir=$cg_basedir/osc_slab_alloc
19456         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19457         trap "cleanup_test411_cgroup $cgdir" EXIT
19458         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19459         echo 1M > $cgdir/memory.limit_in_bytes
19460
19461         # Should not LBUG, just be killed by oom-killer
19462         # dd will return 0 even allocation failure in some environment.
19463         # So don't check return value
19464         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19465         cleanup_test411_cgroup $cgdir
19466
19467         return 0
19468 }
19469 run_test 411 "Slab allocation error with cgroup does not LBUG"
19470
19471 test_412() {
19472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19473         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19474                 skip "Need server version at least 2.10.55"
19475         fi
19476
19477         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19478                 error "mkdir failed"
19479         $LFS getdirstripe $DIR/$tdir
19480         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19481         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19482                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19483         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19484         [ $stripe_count -eq 2 ] ||
19485                 error "expect 2 get $stripe_count"
19486 }
19487 run_test 412 "mkdir on specific MDTs"
19488
19489 test_413() {
19490         [ $MDSCOUNT -lt 2 ] &&
19491                 skip "We need at least 2 MDTs for this test"
19492
19493         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19494                 skip "Need server version at least 2.10.55"
19495         fi
19496
19497         mkdir $DIR/$tdir || error "mkdir failed"
19498
19499         # find MDT that is the most full
19500         local max=$($LFS df | grep MDT |
19501                 awk 'BEGIN { a=0 }
19502                         { sub("%", "", $5)
19503                           if (0+$5 >= a)
19504                           {
19505                                 a = $5
19506                                 b = $6
19507                           }
19508                         }
19509                      END { split(b, c, ":")
19510                            sub("]", "", c[2])
19511                            print c[2]
19512                          }')
19513
19514         for i in $(seq $((MDSCOUNT - 1))); do
19515                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19516                         error "mkdir d$i failed"
19517                 $LFS getdirstripe $DIR/$tdir/d$i
19518                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19519                 [ $stripe_index -ne $max ] ||
19520                         error "don't expect $max"
19521         done
19522 }
19523 run_test 413 "mkdir on less full MDTs"
19524
19525 test_414() {
19526 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19527         $LCTL set_param fail_loc=0x80000521
19528         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19529         rm -f $DIR/$tfile
19530 }
19531 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19532
19533 test_415() {
19534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19535         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19536                 skip "Need server version at least 2.11.52"
19537
19538         # LU-11102
19539         local total
19540         local setattr_pid
19541         local start_time
19542         local end_time
19543         local duration
19544
19545         total=500
19546         # this test may be slow on ZFS
19547         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19548
19549         # though this test is designed for striped directory, let's test normal
19550         # directory too since lock is always saved as CoS lock.
19551         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19552         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19553
19554         (
19555                 while true; do
19556                         touch $DIR/$tdir
19557                 done
19558         ) &
19559         setattr_pid=$!
19560
19561         start_time=$(date +%s)
19562         for i in $(seq $total); do
19563                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19564                         > /dev/null
19565         done
19566         end_time=$(date +%s)
19567         duration=$((end_time - start_time))
19568
19569         kill -9 $setattr_pid
19570
19571         echo "rename $total files took $duration sec"
19572         [ $duration -lt 100 ] || error "rename took $duration sec"
19573 }
19574 run_test 415 "lock revoke is not missing"
19575
19576 test_416() {
19577         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19578                 skip "Need server version at least 2.11.55"
19579
19580         # define OBD_FAIL_OSD_TXN_START    0x19a
19581         do_facet mds1 lctl set_param fail_loc=0x19a
19582
19583         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19584
19585         true
19586 }
19587 run_test 416 "transaction start failure won't cause system hung"
19588
19589 cleanup_417() {
19590         trap 0
19591         do_nodes $(comma_list $(mdts_nodes)) \
19592                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19593         do_nodes $(comma_list $(mdts_nodes)) \
19594                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19595         do_nodes $(comma_list $(mdts_nodes)) \
19596                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19597 }
19598
19599 test_417() {
19600         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19601         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19602                 skip "Need MDS version at least 2.11.56"
19603
19604         trap cleanup_417 RETURN EXIT
19605
19606         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19607         do_nodes $(comma_list $(mdts_nodes)) \
19608                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19609         $LFS migrate -m 0 $DIR/$tdir.1 &&
19610                 error "migrate dir $tdir.1 should fail"
19611
19612         do_nodes $(comma_list $(mdts_nodes)) \
19613                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19614         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19615                 error "create remote dir $tdir.2 should fail"
19616
19617         do_nodes $(comma_list $(mdts_nodes)) \
19618                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19619         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19620                 error "create striped dir $tdir.3 should fail"
19621         true
19622 }
19623 run_test 417 "disable remote dir, striped dir and dir migration"
19624
19625 # Checks that the outputs of df [-i] and lfs df [-i] match
19626 #
19627 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19628 check_lfs_df() {
19629         local dir=$2
19630         local inodes
19631         local df_out
19632         local lfs_df_out
19633         local count
19634         local passed=false
19635
19636         # blocks or inodes
19637         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19638
19639         for count in {1..100}; do
19640                 cancel_lru_locks
19641                 sync; sleep 0.2
19642
19643                 # read the lines of interest
19644                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19645                         error "df $inodes $dir | tail -n +2 failed"
19646                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19647                         error "lfs df $inodes $dir | grep summary: failed"
19648
19649                 # skip first substrings of each output as they are different
19650                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19651                 # compare the two outputs
19652                 passed=true
19653                 for i in {1..5}; do
19654                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19655                 done
19656                 $passed && break
19657         done
19658
19659         if ! $passed; then
19660                 df -P $inodes $dir
19661                 echo
19662                 lfs df $inodes $dir
19663                 error "df and lfs df $1 output mismatch: "      \
19664                       "df ${inodes}: ${df_out[*]}, "            \
19665                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19666         fi
19667 }
19668
19669 test_418() {
19670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19671
19672         local dir=$DIR/$tdir
19673         local numfiles=$((RANDOM % 4096 + 2))
19674         local numblocks=$((RANDOM % 256 + 1))
19675
19676         wait_delete_completed
19677         test_mkdir $dir
19678
19679         # check block output
19680         check_lfs_df blocks $dir
19681         # check inode output
19682         check_lfs_df inodes $dir
19683
19684         # create a single file and retest
19685         echo "Creating a single file and testing"
19686         createmany -o $dir/$tfile- 1 &>/dev/null ||
19687                 error "creating 1 file in $dir failed"
19688         check_lfs_df blocks $dir
19689         check_lfs_df inodes $dir
19690
19691         # create a random number of files
19692         echo "Creating $((numfiles - 1)) files and testing"
19693         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19694                 error "creating $((numfiles - 1)) files in $dir failed"
19695
19696         # write a random number of blocks to the first test file
19697         echo "Writing $numblocks 4K blocks and testing"
19698         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19699                 count=$numblocks &>/dev/null ||
19700                 error "dd to $dir/${tfile}-0 failed"
19701
19702         # retest
19703         check_lfs_df blocks $dir
19704         check_lfs_df inodes $dir
19705
19706         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19707                 error "unlinking $numfiles files in $dir failed"
19708 }
19709 run_test 418 "df and lfs df outputs match"
19710
19711 prep_801() {
19712         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19713         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19714                 skip "Need server version at least 2.9.55"
19715
19716         start_full_debug_logging
19717 }
19718
19719 post_801() {
19720         stop_full_debug_logging
19721 }
19722
19723 barrier_stat() {
19724         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19725                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19726                            awk '/The barrier for/ { print $7 }')
19727                 echo $st
19728         else
19729                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19730                 echo \'$st\'
19731         fi
19732 }
19733
19734 barrier_expired() {
19735         local expired
19736
19737         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19738                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19739                           awk '/will be expired/ { print $7 }')
19740         else
19741                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19742         fi
19743
19744         echo $expired
19745 }
19746
19747 test_801a() {
19748         prep_801
19749
19750         echo "Start barrier_freeze at: $(date)"
19751         #define OBD_FAIL_BARRIER_DELAY          0x2202
19752         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19753         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19754
19755         sleep 2
19756         local b_status=$(barrier_stat)
19757         echo "Got barrier status at: $(date)"
19758         [ "$b_status" = "'freezing_p1'" ] ||
19759                 error "(1) unexpected barrier status $b_status"
19760
19761         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19762         wait
19763         b_status=$(barrier_stat)
19764         [ "$b_status" = "'frozen'" ] ||
19765                 error "(2) unexpected barrier status $b_status"
19766
19767         local expired=$(barrier_expired)
19768         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19769         sleep $((expired + 3))
19770
19771         b_status=$(barrier_stat)
19772         [ "$b_status" = "'expired'" ] ||
19773                 error "(3) unexpected barrier status $b_status"
19774
19775         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19776                 error "(4) fail to freeze barrier"
19777
19778         b_status=$(barrier_stat)
19779         [ "$b_status" = "'frozen'" ] ||
19780                 error "(5) unexpected barrier status $b_status"
19781
19782         echo "Start barrier_thaw at: $(date)"
19783         #define OBD_FAIL_BARRIER_DELAY          0x2202
19784         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19785         do_facet mgs $LCTL barrier_thaw $FSNAME &
19786
19787         sleep 2
19788         b_status=$(barrier_stat)
19789         echo "Got barrier status at: $(date)"
19790         [ "$b_status" = "'thawing'" ] ||
19791                 error "(6) unexpected barrier status $b_status"
19792
19793         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19794         wait
19795         b_status=$(barrier_stat)
19796         [ "$b_status" = "'thawed'" ] ||
19797                 error "(7) unexpected barrier status $b_status"
19798
19799         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19800         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19801         do_facet mgs $LCTL barrier_freeze $FSNAME
19802
19803         b_status=$(barrier_stat)
19804         [ "$b_status" = "'failed'" ] ||
19805                 error "(8) unexpected barrier status $b_status"
19806
19807         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19808         do_facet mgs $LCTL barrier_thaw $FSNAME
19809
19810         post_801
19811 }
19812 run_test 801a "write barrier user interfaces and stat machine"
19813
19814 test_801b() {
19815         prep_801
19816
19817         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19818         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19819         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19820         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19821         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19822
19823         cancel_lru_locks mdc
19824
19825         # 180 seconds should be long enough
19826         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19827
19828         local b_status=$(barrier_stat)
19829         [ "$b_status" = "'frozen'" ] ||
19830                 error "(6) unexpected barrier status $b_status"
19831
19832         mkdir $DIR/$tdir/d0/d10 &
19833         mkdir_pid=$!
19834
19835         touch $DIR/$tdir/d1/f13 &
19836         touch_pid=$!
19837
19838         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19839         ln_pid=$!
19840
19841         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19842         mv_pid=$!
19843
19844         rm -f $DIR/$tdir/d4/f12 &
19845         rm_pid=$!
19846
19847         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19848
19849         # To guarantee taht the 'stat' is not blocked
19850         b_status=$(barrier_stat)
19851         [ "$b_status" = "'frozen'" ] ||
19852                 error "(8) unexpected barrier status $b_status"
19853
19854         # let above commands to run at background
19855         sleep 5
19856
19857         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19858         ps -p $touch_pid || error "(10) touch should be blocked"
19859         ps -p $ln_pid || error "(11) link should be blocked"
19860         ps -p $mv_pid || error "(12) rename should be blocked"
19861         ps -p $rm_pid || error "(13) unlink should be blocked"
19862
19863         b_status=$(barrier_stat)
19864         [ "$b_status" = "'frozen'" ] ||
19865                 error "(14) unexpected barrier status $b_status"
19866
19867         do_facet mgs $LCTL barrier_thaw $FSNAME
19868         b_status=$(barrier_stat)
19869         [ "$b_status" = "'thawed'" ] ||
19870                 error "(15) unexpected barrier status $b_status"
19871
19872         wait $mkdir_pid || error "(16) mkdir should succeed"
19873         wait $touch_pid || error "(17) touch should succeed"
19874         wait $ln_pid || error "(18) link should succeed"
19875         wait $mv_pid || error "(19) rename should succeed"
19876         wait $rm_pid || error "(20) unlink should succeed"
19877
19878         post_801
19879 }
19880 run_test 801b "modification will be blocked by write barrier"
19881
19882 test_801c() {
19883         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19884
19885         prep_801
19886
19887         stop mds2 || error "(1) Fail to stop mds2"
19888
19889         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19890
19891         local b_status=$(barrier_stat)
19892         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
19893                 do_facet mgs $LCTL barrier_thaw $FSNAME
19894                 error "(2) unexpected barrier status $b_status"
19895         }
19896
19897         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19898                 error "(3) Fail to rescan barrier bitmap"
19899
19900         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19901
19902         b_status=$(barrier_stat)
19903         [ "$b_status" = "'frozen'" ] ||
19904                 error "(4) unexpected barrier status $b_status"
19905
19906         do_facet mgs $LCTL barrier_thaw $FSNAME
19907         b_status=$(barrier_stat)
19908         [ "$b_status" = "'thawed'" ] ||
19909                 error "(5) unexpected barrier status $b_status"
19910
19911         local devname=$(mdsdevname 2)
19912
19913         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19914
19915         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19916                 error "(7) Fail to rescan barrier bitmap"
19917
19918         post_801
19919 }
19920 run_test 801c "rescan barrier bitmap"
19921
19922 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19923 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19924 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19925
19926 cleanup_802a() {
19927         trap 0
19928
19929         stopall
19930         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19931         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19932         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19933         setupall
19934 }
19935
19936 test_802a() {
19937
19938         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19939         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19940                 skip "Need server version at least 2.9.55"
19941
19942         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19943
19944         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19945
19946         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19947                 error "(2) Fail to copy"
19948
19949         trap cleanup_802a EXIT
19950
19951         # sync by force before remount as readonly
19952         sync; sync_all_data; sleep 3; sync_all_data
19953
19954         stopall
19955
19956         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19957         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19958         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19959
19960         echo "Mount the server as read only"
19961         setupall server_only || error "(3) Fail to start servers"
19962
19963         echo "Mount client without ro should fail"
19964         mount_client $MOUNT &&
19965                 error "(4) Mount client without 'ro' should fail"
19966
19967         echo "Mount client with ro should succeed"
19968         mount_client $MOUNT ro ||
19969                 error "(5) Mount client with 'ro' should succeed"
19970
19971         echo "Modify should be refused"
19972         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19973
19974         echo "Read should be allowed"
19975         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19976                 error "(7) Read should succeed under ro mode"
19977
19978         cleanup_802a
19979 }
19980 run_test 802a "simulate readonly device"
19981
19982 test_802b() {
19983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19984         remote_mds_nodsh && skip "remote MDS with nodsh"
19985
19986         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19987                 skip "readonly option not available"
19988
19989         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19990
19991         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19992                 error "(2) Fail to copy"
19993
19994         # write back all cached data before setting MDT to readonly
19995         cancel_lru_locks
19996         sync_all_data
19997
19998         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19999         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20000
20001         echo "Modify should be refused"
20002         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20003
20004         echo "Read should be allowed"
20005         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20006                 error "(7) Read should succeed under ro mode"
20007
20008         # disable readonly
20009         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20010 }
20011 run_test 802b "be able to set MDTs to readonly"
20012
20013 test_803() {
20014         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20015         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20016                 skip "MDS needs to be newer than 2.10.54"
20017
20018         mkdir -p $DIR/$tdir
20019         # Create some objects on all MDTs to trigger related logs objects
20020         for idx in $(seq $MDSCOUNT); do
20021                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20022                         $DIR/$tdir/dir${idx} ||
20023                         error "Fail to create $DIR/$tdir/dir${idx}"
20024         done
20025
20026         sync; sleep 3
20027         wait_delete_completed # ensure old test cleanups are finished
20028         echo "before create:"
20029         $LFS df -i $MOUNT
20030         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20031
20032         for i in {1..10}; do
20033                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20034                         error "Fail to create $DIR/$tdir/foo$i"
20035         done
20036
20037         sync; sleep 3
20038         echo "after create:"
20039         $LFS df -i $MOUNT
20040         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20041
20042         # allow for an llog to be cleaned up during the test
20043         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20044                 error "before ($before_used) + 10 > after ($after_used)"
20045
20046         for i in {1..10}; do
20047                 rm -rf $DIR/$tdir/foo$i ||
20048                         error "Fail to remove $DIR/$tdir/foo$i"
20049         done
20050
20051         sleep 3 # avoid MDT return cached statfs
20052         wait_delete_completed
20053         echo "after unlink:"
20054         $LFS df -i $MOUNT
20055         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20056
20057         # allow for an llog to be created during the test
20058         [ $after_used -le $((before_used + 1)) ] ||
20059                 error "after ($after_used) > before ($before_used) + 1"
20060 }
20061 run_test 803 "verify agent object for remote object"
20062
20063 test_804() {
20064         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20065         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20066                 skip "MDS needs to be newer than 2.10.54"
20067         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20068
20069         mkdir -p $DIR/$tdir
20070         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20071                 error "Fail to create $DIR/$tdir/dir0"
20072
20073         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20074         local dev=$(mdsdevname 2)
20075
20076         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20077                 grep ${fid} || error "NOT found agent entry for dir0"
20078
20079         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20080                 error "Fail to create $DIR/$tdir/dir1"
20081
20082         touch $DIR/$tdir/dir1/foo0 ||
20083                 error "Fail to create $DIR/$tdir/dir1/foo0"
20084         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20085         local rc=0
20086
20087         for idx in $(seq $MDSCOUNT); do
20088                 dev=$(mdsdevname $idx)
20089                 do_facet mds${idx} \
20090                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20091                         grep ${fid} && rc=$idx
20092         done
20093
20094         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20095                 error "Fail to rename foo0 to foo1"
20096         if [ $rc -eq 0 ]; then
20097                 for idx in $(seq $MDSCOUNT); do
20098                         dev=$(mdsdevname $idx)
20099                         do_facet mds${idx} \
20100                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20101                         grep ${fid} && rc=$idx
20102                 done
20103         fi
20104
20105         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20106                 error "Fail to rename foo1 to foo2"
20107         if [ $rc -eq 0 ]; then
20108                 for idx in $(seq $MDSCOUNT); do
20109                         dev=$(mdsdevname $idx)
20110                         do_facet mds${idx} \
20111                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20112                         grep ${fid} && rc=$idx
20113                 done
20114         fi
20115
20116         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20117
20118         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20119                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20120         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20121                 error "Fail to rename foo2 to foo0"
20122         unlink $DIR/$tdir/dir1/foo0 ||
20123                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20124         rm -rf $DIR/$tdir/dir0 ||
20125                 error "Fail to rm $DIR/$tdir/dir0"
20126
20127         for idx in $(seq $MDSCOUNT); do
20128                 dev=$(mdsdevname $idx)
20129                 rc=0
20130
20131                 stop mds${idx}
20132                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20133                         rc=$?
20134                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20135                         error "mount mds$idx failed"
20136                 df $MOUNT > /dev/null 2>&1
20137
20138                 # e2fsck should not return error
20139                 [ $rc -eq 0 ] ||
20140                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20141         done
20142 }
20143 run_test 804 "verify agent entry for remote entry"
20144
20145 cleanup_805() {
20146         do_facet $SINGLEMDS zfs set quota=$old $fsset
20147         unlinkmany $DIR/$tdir/f- 1000000
20148         trap 0
20149 }
20150
20151 test_805() {
20152         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20153         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20154         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20155                 skip "netfree not implemented before 0.7"
20156         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20157                 skip "Need MDS version at least 2.10.57"
20158
20159         local fsset
20160         local freekb
20161         local usedkb
20162         local old
20163         local quota
20164         local pref="osd-zfs.lustre-MDT0000."
20165
20166         # limit available space on MDS dataset to meet nospace issue
20167         # quickly. then ZFS 0.7.2 can use reserved space if asked
20168         # properly (using netfree flag in osd_declare_destroy()
20169         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20170         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20171                 gawk '{print $3}')
20172         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20173         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20174         let "usedkb=usedkb-freekb"
20175         let "freekb=freekb/2"
20176         if let "freekb > 5000"; then
20177                 let "freekb=5000"
20178         fi
20179         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20180         trap cleanup_805 EXIT
20181         mkdir $DIR/$tdir
20182         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20183         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20184         rm -rf $DIR/$tdir || error "not able to remove"
20185         do_facet $SINGLEMDS zfs set quota=$old $fsset
20186         trap 0
20187 }
20188 run_test 805 "ZFS can remove from full fs"
20189
20190 # Size-on-MDS test
20191 check_lsom_data()
20192 {
20193         local file=$1
20194         local size=$($LFS getsom -s $file)
20195         local expect=$(stat -c %s $file)
20196
20197         [[ $size == $expect ]] ||
20198                 error "$file expected size: $expect, got: $size"
20199
20200         local blocks=$($LFS getsom -b $file)
20201         expect=$(stat -c %b $file)
20202         [[ $blocks == $expect ]] ||
20203                 error "$file expected blocks: $expect, got: $blocks"
20204 }
20205
20206 check_lsom_size()
20207 {
20208         local size=$($LFS getsom -s $1)
20209         local expect=$2
20210
20211         [[ $size == $expect ]] ||
20212                 error "$file expected size: $expect, got: $size"
20213 }
20214
20215 test_806() {
20216         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20217                 skip "Need MDS version at least 2.11.52"
20218
20219         local bs=1048576
20220
20221         touch $DIR/$tfile || error "touch $tfile failed"
20222
20223         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20224         save_lustre_params client "llite.*.xattr_cache" > $save
20225         lctl set_param llite.*.xattr_cache=0
20226         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20227
20228         # single-threaded write
20229         echo "Test SOM for single-threaded write"
20230         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20231                 error "write $tfile failed"
20232         check_lsom_size $DIR/$tfile $bs
20233
20234         local num=32
20235         local size=$(($num * $bs))
20236         local offset=0
20237         local i
20238
20239         echo "Test SOM for single client multi-threaded($num) write"
20240         $TRUNCATE $DIR/$tfile 0
20241         for ((i = 0; i < $num; i++)); do
20242                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20243                 local pids[$i]=$!
20244                 offset=$((offset + $bs))
20245         done
20246         for (( i=0; i < $num; i++ )); do
20247                 wait ${pids[$i]}
20248         done
20249         check_lsom_size $DIR/$tfile $size
20250
20251         $TRUNCATE $DIR/$tfile 0
20252         for ((i = 0; i < $num; i++)); do
20253                 offset=$((offset - $bs))
20254                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20255                 local pids[$i]=$!
20256         done
20257         for (( i=0; i < $num; i++ )); do
20258                 wait ${pids[$i]}
20259         done
20260         check_lsom_size $DIR/$tfile $size
20261
20262         # multi-client wirtes
20263         num=$(get_node_count ${CLIENTS//,/ })
20264         size=$(($num * $bs))
20265         offset=0
20266         i=0
20267
20268         echo "Test SOM for multi-client ($num) writes"
20269         $TRUNCATE $DIR/$tfile 0
20270         for client in ${CLIENTS//,/ }; do
20271                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20272                 local pids[$i]=$!
20273                 i=$((i + 1))
20274                 offset=$((offset + $bs))
20275         done
20276         for (( i=0; i < $num; i++ )); do
20277                 wait ${pids[$i]}
20278         done
20279         check_lsom_size $DIR/$tfile $offset
20280
20281         i=0
20282         $TRUNCATE $DIR/$tfile 0
20283         for client in ${CLIENTS//,/ }; do
20284                 offset=$((offset - $bs))
20285                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20286                 local pids[$i]=$!
20287                 i=$((i + 1))
20288         done
20289         for (( i=0; i < $num; i++ )); do
20290                 wait ${pids[$i]}
20291         done
20292         check_lsom_size $DIR/$tfile $size
20293
20294         # verify truncate
20295         echo "Test SOM for truncate"
20296         $TRUNCATE $DIR/$tfile 1048576
20297         check_lsom_size $DIR/$tfile 1048576
20298         $TRUNCATE $DIR/$tfile 1234
20299         check_lsom_size $DIR/$tfile 1234
20300
20301         # verify SOM blocks count
20302         echo "Verify SOM block count"
20303         $TRUNCATE $DIR/$tfile 0
20304         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20305                 error "failed to write file $tfile"
20306         check_lsom_data $DIR/$tfile
20307 }
20308 run_test 806 "Verify Lazy Size on MDS"
20309
20310 test_807() {
20311         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20312         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20313                 skip "Need MDS version at least 2.11.52"
20314
20315         # Registration step
20316         changelog_register || error "changelog_register failed"
20317         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20318         changelog_users $SINGLEMDS | grep -q $cl_user ||
20319                 error "User $cl_user not found in changelog_users"
20320
20321         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20322         save_lustre_params client "llite.*.xattr_cache" > $save
20323         lctl set_param llite.*.xattr_cache=0
20324         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20325
20326         rm -rf $DIR/$tdir || error "rm $tdir failed"
20327         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20328         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20329         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20330         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20331                 error "truncate $tdir/trunc failed"
20332
20333         local bs=1048576
20334         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20335                 error "write $tfile failed"
20336
20337         # multi-client wirtes
20338         local num=$(get_node_count ${CLIENTS//,/ })
20339         local offset=0
20340         local i=0
20341
20342         echo "Test SOM for multi-client ($num) writes"
20343         touch $DIR/$tfile || error "touch $tfile failed"
20344         $TRUNCATE $DIR/$tfile 0
20345         for client in ${CLIENTS//,/ }; do
20346                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20347                 local pids[$i]=$!
20348                 i=$((i + 1))
20349                 offset=$((offset + $bs))
20350         done
20351         for (( i=0; i < $num; i++ )); do
20352                 wait ${pids[$i]}
20353         done
20354
20355         sleep 5
20356         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20357         check_lsom_data $DIR/$tdir/trunc
20358         check_lsom_data $DIR/$tdir/single_dd
20359         check_lsom_data $DIR/$tfile
20360
20361         rm -rf $DIR/$tdir
20362         # Deregistration step
20363         changelog_deregister || error "changelog_deregister failed"
20364 }
20365 run_test 807 "verify LSOM syncing tool"
20366
20367 check_som_nologged()
20368 {
20369         local lines=$($LFS changelog $FSNAME-MDT0000 |
20370                 grep 'x=trusted.som' | wc -l)
20371         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20372 }
20373
20374 test_808() {
20375         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20376                 skip "Need MDS version at least 2.11.55"
20377
20378         # Registration step
20379         changelog_register || error "changelog_register failed"
20380
20381         touch $DIR/$tfile || error "touch $tfile failed"
20382         check_som_nologged
20383
20384         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20385                 error "write $tfile failed"
20386         check_som_nologged
20387
20388         $TRUNCATE $DIR/$tfile 1234
20389         check_som_nologged
20390
20391         $TRUNCATE $DIR/$tfile 1048576
20392         check_som_nologged
20393
20394         # Deregistration step
20395         changelog_deregister || error "changelog_deregister failed"
20396 }
20397 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20398
20399 check_som_nodata()
20400 {
20401         $LFS getsom $1
20402         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20403 }
20404
20405 test_809() {
20406         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20407                 skip "Need MDS version at least 2.11.56"
20408
20409         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20410                 error "failed to create DoM-only file $DIR/$tfile"
20411         touch $DIR/$tfile || error "touch $tfile failed"
20412         check_som_nodata $DIR/$tfile
20413
20414         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20415                 error "write $tfile failed"
20416         check_som_nodata $DIR/$tfile
20417
20418         $TRUNCATE $DIR/$tfile 1234
20419         check_som_nodata $DIR/$tfile
20420
20421         $TRUNCATE $DIR/$tfile 4097
20422         check_som_nodata $DIR/$file
20423 }
20424 run_test 809 "Verify no SOM xattr store for DoM-only files"
20425
20426 test_810() {
20427         local ORIG
20428         local CSUM
20429
20430         # t10 seem to dislike partial pages
20431         lctl set_param osc.*.checksum_type=adler
20432         lctl set_param fail_loc=0x411
20433         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20434         ORIG=$(md5sum $DIR/$tfile)
20435         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20436         CSUM=$(md5sum $DIR/$tfile)
20437         set_checksum_type adler
20438         if [ "$ORIG" != "$CSUM" ]; then
20439                 error "$ORIG != $CSUM"
20440         fi
20441 }
20442 run_test 810 "partial page writes on ZFS (LU-11663)"
20443
20444 test_811() {
20445         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20446                 skip "Need MDS version at least 2.11.56"
20447
20448         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20449         do_facet mds1 $LCTL set_param fail_loc=0x165
20450         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20451
20452         stop mds1
20453         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20454
20455         sleep 5
20456         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20457                 error "MDD orphan cleanup thread not quit"
20458 }
20459 run_test 811 "orphan name stub can be cleaned up in startup"
20460
20461 test_812() {
20462         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20463                 skip "OST < 2.12.51 doesn't support this fail_loc"
20464
20465         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20466         # ensure ost1 is connected
20467         stat $DIR/$tfile >/dev/null || error "can't stat"
20468         wait_osc_import_state client ost1 FULL
20469         # no locks, no reqs to let the connection idle
20470         cancel_lru_locks osc
20471
20472         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20473 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20474         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20475         wait_osc_import_state client ost1 CONNECTING
20476         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20477
20478         stat $DIR/$tfile >/dev/null || error "can't stat file"
20479 }
20480 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20481
20482 test_813() {
20483         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20484         [ -z "$file_heat_sav" ] && skip "no file heat support"
20485
20486         local readsample
20487         local writesample
20488         local readbyte
20489         local writebyte
20490         local readsample1
20491         local writesample1
20492         local readbyte1
20493         local writebyte1
20494
20495         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20496         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20497
20498         $LCTL set_param -n llite.*.file_heat=1
20499         echo "Turn on file heat"
20500         echo "Period second: $period_second, Decay percentage: $decay_pct"
20501
20502         echo "QQQQ" > $DIR/$tfile
20503         echo "QQQQ" > $DIR/$tfile
20504         echo "QQQQ" > $DIR/$tfile
20505         cat $DIR/$tfile > /dev/null
20506         cat $DIR/$tfile > /dev/null
20507         cat $DIR/$tfile > /dev/null
20508         cat $DIR/$tfile > /dev/null
20509
20510         local out=$($LFS heat_get $DIR/$tfile)
20511
20512         $LFS heat_get $DIR/$tfile
20513         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20514         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20515         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20516         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20517
20518         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20519         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20520         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20521         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20522
20523         sleep $((period_second + 3))
20524         echo "Sleep $((period_second + 3)) seconds..."
20525         # The recursion formula to calculate the heat of the file f is as
20526         # follow:
20527         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20528         # Where Hi is the heat value in the period between time points i*I and
20529         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20530         # to the weight of Ci.
20531         out=$($LFS heat_get $DIR/$tfile)
20532         $LFS heat_get $DIR/$tfile
20533         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20534         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20535         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20536         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20537
20538         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20539                 error "read sample ($readsample) is wrong"
20540         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20541                 error "write sample ($writesample) is wrong"
20542         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20543                 error "read bytes ($readbyte) is wrong"
20544         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20545                 error "write bytes ($writebyte) is wrong"
20546
20547         echo "QQQQ" > $DIR/$tfile
20548         echo "QQQQ" > $DIR/$tfile
20549         echo "QQQQ" > $DIR/$tfile
20550         cat $DIR/$tfile > /dev/null
20551         cat $DIR/$tfile > /dev/null
20552         cat $DIR/$tfile > /dev/null
20553         cat $DIR/$tfile > /dev/null
20554
20555         sleep $((period_second + 3))
20556         echo "Sleep $((period_second + 3)) seconds..."
20557
20558         out=$($LFS heat_get $DIR/$tfile)
20559         $LFS heat_get $DIR/$tfile
20560         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20561         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20562         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20563         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20564
20565         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20566                 4 * $decay_pct) / 100") -eq 1 ] ||
20567                 error "read sample ($readsample1) is wrong"
20568         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20569                 3 * $decay_pct) / 100") -eq 1 ] ||
20570                 error "write sample ($writesample1) is wrong"
20571         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20572                 20 * $decay_pct) / 100") -eq 1 ] ||
20573                 error "read bytes ($readbyte1) is wrong"
20574         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20575                 15 * $decay_pct) / 100") -eq 1 ] ||
20576                 error "write bytes ($writebyte1) is wrong"
20577
20578         echo "Turn off file heat for the file $DIR/$tfile"
20579         $LFS heat_set -o $DIR/$tfile
20580
20581         echo "QQQQ" > $DIR/$tfile
20582         echo "QQQQ" > $DIR/$tfile
20583         echo "QQQQ" > $DIR/$tfile
20584         cat $DIR/$tfile > /dev/null
20585         cat $DIR/$tfile > /dev/null
20586         cat $DIR/$tfile > /dev/null
20587         cat $DIR/$tfile > /dev/null
20588
20589         out=$($LFS heat_get $DIR/$tfile)
20590         $LFS heat_get $DIR/$tfile
20591         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20592         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20593         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20594         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20595
20596         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20597         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20598         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20599         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20600
20601         echo "Trun on file heat for the file $DIR/$tfile"
20602         $LFS heat_set -O $DIR/$tfile
20603
20604         echo "QQQQ" > $DIR/$tfile
20605         echo "QQQQ" > $DIR/$tfile
20606         echo "QQQQ" > $DIR/$tfile
20607         cat $DIR/$tfile > /dev/null
20608         cat $DIR/$tfile > /dev/null
20609         cat $DIR/$tfile > /dev/null
20610         cat $DIR/$tfile > /dev/null
20611
20612         out=$($LFS heat_get $DIR/$tfile)
20613         $LFS heat_get $DIR/$tfile
20614         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20615         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20616         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20617         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20618
20619         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20620         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20621         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20622         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20623
20624         $LFS heat_set -c $DIR/$tfile
20625         $LCTL set_param -n llite.*.file_heat=0
20626         echo "Turn off file heat support for the Lustre filesystem"
20627
20628         echo "QQQQ" > $DIR/$tfile
20629         echo "QQQQ" > $DIR/$tfile
20630         echo "QQQQ" > $DIR/$tfile
20631         cat $DIR/$tfile > /dev/null
20632         cat $DIR/$tfile > /dev/null
20633         cat $DIR/$tfile > /dev/null
20634         cat $DIR/$tfile > /dev/null
20635
20636         out=$($LFS heat_get $DIR/$tfile)
20637         $LFS heat_get $DIR/$tfile
20638         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20639         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20640         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20641         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20642
20643         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20644         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20645         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20646         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20647
20648         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20649         rm -f $DIR/$tfile
20650 }
20651 run_test 813 "File heat verfication"
20652
20653 #
20654 # tests that do cleanup/setup should be run at the end
20655 #
20656
20657 test_900() {
20658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20659         local ls
20660
20661         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20662         $LCTL set_param fail_loc=0x903
20663
20664         cancel_lru_locks MGC
20665
20666         FAIL_ON_ERROR=true cleanup
20667         FAIL_ON_ERROR=true setup
20668 }
20669 run_test 900 "umount should not race with any mgc requeue thread"
20670
20671 complete $SECONDS
20672 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20673 check_and_cleanup_lustre
20674 if [ "$I_MOUNTED" != "yes" ]; then
20675         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20676 fi
20677 exit_status