Whamcloud - gitweb
LU-12169 llite: fill copied dentry name's ending char properly
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_25a() {
1444         echo '== symlink sanity ============================================='
1445
1446         test_mkdir $DIR/d25
1447         ln -s d25 $DIR/s25
1448         touch $DIR/s25/foo ||
1449                 error "File creation in symlinked directory failed"
1450 }
1451 run_test 25a "create file in symlinked directory ==============="
1452
1453 test_25b() {
1454         [ ! -d $DIR/d25 ] && test_25a
1455         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1456 }
1457 run_test 25b "lookup file in symlinked directory ==============="
1458
1459 test_26a() {
1460         test_mkdir $DIR/d26
1461         test_mkdir $DIR/d26/d26-2
1462         ln -s d26/d26-2 $DIR/s26
1463         touch $DIR/s26/foo || error "File creation failed"
1464 }
1465 run_test 26a "multiple component symlink ======================="
1466
1467 test_26b() {
1468         test_mkdir -p $DIR/$tdir/d26-2
1469         ln -s $tdir/d26-2/foo $DIR/s26-2
1470         touch $DIR/s26-2 || error "File creation failed"
1471 }
1472 run_test 26b "multiple component symlink at end of lookup ======"
1473
1474 test_26c() {
1475         test_mkdir $DIR/d26.2
1476         touch $DIR/d26.2/foo
1477         ln -s d26.2 $DIR/s26.2-1
1478         ln -s s26.2-1 $DIR/s26.2-2
1479         ln -s s26.2-2 $DIR/s26.2-3
1480         chmod 0666 $DIR/s26.2-3/foo
1481 }
1482 run_test 26c "chain of symlinks"
1483
1484 # recursive symlinks (bug 439)
1485 test_26d() {
1486         ln -s d26-3/foo $DIR/d26-3
1487 }
1488 run_test 26d "create multiple component recursive symlink"
1489
1490 test_26e() {
1491         [ ! -h $DIR/d26-3 ] && test_26d
1492         rm $DIR/d26-3
1493 }
1494 run_test 26e "unlink multiple component recursive symlink"
1495
1496 # recursive symlinks (bug 7022)
1497 test_26f() {
1498         test_mkdir $DIR/$tdir
1499         test_mkdir $DIR/$tdir/$tfile
1500         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1501         test_mkdir -p lndir/bar1
1502         test_mkdir $DIR/$tdir/$tfile/$tfile
1503         cd $tfile                || error "cd $tfile failed"
1504         ln -s .. dotdot          || error "ln dotdot failed"
1505         ln -s dotdot/lndir lndir || error "ln lndir failed"
1506         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1507         output=`ls $tfile/$tfile/lndir/bar1`
1508         [ "$output" = bar1 ] && error "unexpected output"
1509         rm -r $tfile             || error "rm $tfile failed"
1510         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1511 }
1512 run_test 26f "rm -r of a directory which has recursive symlink"
1513
1514 test_27a() {
1515         test_mkdir $DIR/$tdir
1516         $LFS getstripe $DIR/$tdir
1517         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1518         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1519         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1520 }
1521 run_test 27a "one stripe file"
1522
1523 test_27b() {
1524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1525
1526         test_mkdir $DIR/$tdir
1527         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $LFS getstripe -c $DIR/$tdir/$tfile
1529         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1530                 error "two-stripe file doesn't have two stripes"
1531
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533 }
1534 run_test 27b "create and write to two stripe file"
1535
1536 test_27d() {
1537         test_mkdir $DIR/$tdir
1538         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1539                 error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1542 }
1543 run_test 27d "create file with default settings"
1544
1545 test_27e() {
1546         # LU-5839 adds check for existed layout before setting it
1547         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1548                 skip "Need MDS version at least 2.7.56"
1549
1550         test_mkdir $DIR/$tdir
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1552         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1553         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1554 }
1555 run_test 27e "setstripe existing file (should return error)"
1556
1557 test_27f() {
1558         test_mkdir $DIR/$tdir
1559         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1560                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1561         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1562                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1564         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1565 }
1566 run_test 27f "setstripe with bad stripe size (should return error)"
1567
1568 test_27g() {
1569         test_mkdir $DIR/$tdir
1570         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1571         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1572                 error "$DIR/$tdir/$tfile has object"
1573 }
1574 run_test 27g "$LFS getstripe with no objects"
1575
1576 test_27i() {
1577         test_mkdir $DIR/$tdir
1578         touch $DIR/$tdir/$tfile || error "touch failed"
1579         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1580                 error "missing objects"
1581 }
1582 run_test 27i "$LFS getstripe with some objects"
1583
1584 test_27j() {
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1587                 error "setstripe failed" || true
1588 }
1589 run_test 27j "setstripe with bad stripe offset (should return error)"
1590
1591 test_27k() { # bug 2844
1592         test_mkdir $DIR/$tdir
1593         local file=$DIR/$tdir/$tfile
1594         local ll_max_blksize=$((4 * 1024 * 1024))
1595         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1596         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1597         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1598         dd if=/dev/zero of=$file bs=4k count=1
1599         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1600         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1601 }
1602 run_test 27k "limit i_blksize for broken user apps"
1603
1604 test_27l() {
1605         mcreate $DIR/$tfile || error "creating file"
1606         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1607                 error "setstripe should have failed" || true
1608 }
1609 run_test 27l "check setstripe permissions (should return error)"
1610
1611 test_27m() {
1612         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1613
1614         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1615                    head -n1)
1616         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1617                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1618         fi
1619         trap simple_cleanup_common EXIT
1620         test_mkdir $DIR/$tdir
1621         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1623                 error "dd should fill OST0"
1624         i=2
1625         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1626                 i=$((i + 1))
1627                 [ $i -gt 256 ] && break
1628         done
1629         i=$((i + 1))
1630         touch $DIR/$tdir/$tfile.$i
1631         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1632             awk '{print $1}'| grep -w "0") ] &&
1633                 error "OST0 was full but new created file still use it"
1634         i=$((i + 1))
1635         touch $DIR/$tdir/$tfile.$i
1636         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1637             awk '{print $1}'| grep -w "0") ] &&
1638                 error "OST0 was full but new created file still use it"
1639         simple_cleanup_common
1640 }
1641 run_test 27m "create file while OST0 was full"
1642
1643 sleep_maxage() {
1644         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1645                       awk '{ print $1 * 2; exit; }')
1646         sleep $delay
1647 }
1648
1649 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1650 # if the OST isn't full anymore.
1651 reset_enospc() {
1652         local OSTIDX=${1:-""}
1653
1654         local list=$(comma_list $(osts_nodes))
1655         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1656
1657         do_nodes $list lctl set_param fail_loc=0
1658         sync    # initiate all OST_DESTROYs from MDS to OST
1659         sleep_maxage
1660 }
1661
1662 exhaust_precreations() {
1663         local OSTIDX=$1
1664         local FAILLOC=$2
1665         local FAILIDX=${3:-$OSTIDX}
1666         local ofacet=ost$((OSTIDX + 1))
1667
1668         test_mkdir -p -c1 $DIR/$tdir
1669         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1670         local mfacet=mds$((mdtidx + 1))
1671         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1672
1673         local OST=$(ostname_from_index $OSTIDX)
1674
1675         # on the mdt's osc
1676         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1677         local last_id=$(do_facet $mfacet lctl get_param -n \
1678                         osc.$mdtosc_proc1.prealloc_last_id)
1679         local next_id=$(do_facet $mfacet lctl get_param -n \
1680                         osc.$mdtosc_proc1.prealloc_next_id)
1681
1682         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1683         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1684
1685         test_mkdir -p $DIR/$tdir/${OST}
1686         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1687 #define OBD_FAIL_OST_ENOSPC              0x215
1688         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1689         echo "Creating to objid $last_id on ost $OST..."
1690         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1691         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1692         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1693         sleep_maxage
1694 }
1695
1696 exhaust_all_precreations() {
1697         local i
1698         for (( i=0; i < OSTCOUNT; i++ )) ; do
1699                 exhaust_precreations $i $1 -1
1700         done
1701 }
1702
1703 test_27n() {
1704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1706         remote_mds_nodsh && skip "remote MDS with nodsh"
1707         remote_ost_nodsh && skip "remote OST with nodsh"
1708
1709         reset_enospc
1710         rm -f $DIR/$tdir/$tfile
1711         exhaust_precreations 0 0x80000215
1712         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1713         touch $DIR/$tdir/$tfile || error "touch failed"
1714         $LFS getstripe $DIR/$tdir/$tfile
1715         reset_enospc
1716 }
1717 run_test 27n "create file with some full OSTs"
1718
1719 test_27o() {
1720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1722         remote_mds_nodsh && skip "remote MDS with nodsh"
1723         remote_ost_nodsh && skip "remote OST with nodsh"
1724
1725         reset_enospc
1726         rm -f $DIR/$tdir/$tfile
1727         exhaust_all_precreations 0x215
1728
1729         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1730
1731         reset_enospc
1732         rm -rf $DIR/$tdir/*
1733 }
1734 run_test 27o "create file with all full OSTs (should error)"
1735
1736 test_27p() {
1737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1739         remote_mds_nodsh && skip "remote MDS with nodsh"
1740         remote_ost_nodsh && skip "remote OST with nodsh"
1741
1742         reset_enospc
1743         rm -f $DIR/$tdir/$tfile
1744         test_mkdir $DIR/$tdir
1745
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1748         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1749
1750         exhaust_precreations 0 0x80000215
1751         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1752         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1753         $LFS getstripe $DIR/$tdir/$tfile
1754
1755         reset_enospc
1756 }
1757 run_test 27p "append to a truncated file with some full OSTs"
1758
1759 test_27q() {
1760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1762         remote_mds_nodsh && skip "remote MDS with nodsh"
1763         remote_ost_nodsh && skip "remote OST with nodsh"
1764
1765         reset_enospc
1766         rm -f $DIR/$tdir/$tfile
1767
1768         test_mkdir $DIR/$tdir
1769         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1770         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1771                 error "truncate $DIR/$tdir/$tfile failed"
1772         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1773
1774         exhaust_all_precreations 0x215
1775
1776         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1777         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1778
1779         reset_enospc
1780 }
1781 run_test 27q "append to truncated file with all OSTs full (should error)"
1782
1783 test_27r() {
1784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1786         remote_mds_nodsh && skip "remote MDS with nodsh"
1787         remote_ost_nodsh && skip "remote OST with nodsh"
1788
1789         reset_enospc
1790         rm -f $DIR/$tdir/$tfile
1791         exhaust_precreations 0 0x80000215
1792
1793         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1794
1795         reset_enospc
1796 }
1797 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1798
1799 test_27s() { # bug 10725
1800         test_mkdir $DIR/$tdir
1801         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1802         local stripe_count=0
1803         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1804         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1805                 error "stripe width >= 2^32 succeeded" || true
1806
1807 }
1808 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1809
1810 test_27t() { # bug 10864
1811         WDIR=$(pwd)
1812         WLFS=$(which lfs)
1813         cd $DIR
1814         touch $tfile
1815         $WLFS getstripe $tfile
1816         cd $WDIR
1817 }
1818 run_test 27t "check that utils parse path correctly"
1819
1820 test_27u() { # bug 4900
1821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1822         remote_mds_nodsh && skip "remote MDS with nodsh"
1823
1824         local index
1825         local list=$(comma_list $(mdts_nodes))
1826
1827 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1828         do_nodes $list $LCTL set_param fail_loc=0x139
1829         test_mkdir -p $DIR/$tdir
1830         trap simple_cleanup_common EXIT
1831         createmany -o $DIR/$tdir/t- 1000
1832         do_nodes $list $LCTL set_param fail_loc=0
1833
1834         TLOG=$TMP/$tfile.getstripe
1835         $LFS getstripe $DIR/$tdir > $TLOG
1836         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1837         unlinkmany $DIR/$tdir/t- 1000
1838         trap 0
1839         [[ $OBJS -gt 0 ]] &&
1840                 error "$OBJS objects created on OST-0. See $TLOG" ||
1841                 rm -f $TLOG
1842 }
1843 run_test 27u "skip object creation on OSC w/o objects"
1844
1845 test_27v() { # bug 4900
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         exhaust_all_precreations 0x215
1852         reset_enospc
1853
1854         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1855
1856         touch $DIR/$tdir/$tfile
1857         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1858         # all except ost1
1859         for (( i=1; i < OSTCOUNT; i++ )); do
1860                 do_facet ost$i lctl set_param fail_loc=0x705
1861         done
1862         local START=`date +%s`
1863         createmany -o $DIR/$tdir/$tfile 32
1864
1865         local FINISH=`date +%s`
1866         local TIMEOUT=`lctl get_param -n timeout`
1867         local PROCESS=$((FINISH - START))
1868         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1869                error "$FINISH - $START >= $TIMEOUT / 2"
1870         sleep $((TIMEOUT / 2 - PROCESS))
1871         reset_enospc
1872 }
1873 run_test 27v "skip object creation on slow OST"
1874
1875 test_27w() { # bug 10997
1876         test_mkdir $DIR/$tdir
1877         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1878         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1879                 error "stripe size $size != 65536" || true
1880         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1881                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1882 }
1883 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1884
1885 test_27wa() {
1886         [[ $OSTCOUNT -lt 2 ]] &&
1887                 skip_env "skipping multiple stripe count/offset test"
1888
1889         test_mkdir $DIR/$tdir
1890         for i in $(seq 1 $OSTCOUNT); do
1891                 offset=$((i - 1))
1892                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1893                         error "setstripe -c $i -i $offset failed"
1894                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1895                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1896                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1897                 [ $index -ne $offset ] &&
1898                         error "stripe offset $index != $offset" || true
1899         done
1900 }
1901 run_test 27wa "check $LFS setstripe -c -i options"
1902
1903 test_27x() {
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907
1908         OFFSET=$(($OSTCOUNT - 1))
1909         OSTIDX=0
1910         local OST=$(ostname_from_index $OSTIDX)
1911
1912         test_mkdir $DIR/$tdir
1913         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1914         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1915         sleep_maxage
1916         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1917         for i in $(seq 0 $OFFSET); do
1918                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1919                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1920                 error "OST0 was degraded but new created file still use it"
1921         done
1922         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1923 }
1924 run_test 27x "create files while OST0 is degraded"
1925
1926 test_27y() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931
1932         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1933         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1934                 osc.$mdtosc.prealloc_last_id)
1935         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1936                 osc.$mdtosc.prealloc_next_id)
1937         local fcount=$((last_id - next_id))
1938         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1939         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1940
1941         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1942                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1943         local OST_DEACTIVE_IDX=-1
1944         local OSC
1945         local OSTIDX
1946         local OST
1947
1948         for OSC in $MDS_OSCS; do
1949                 OST=$(osc_to_ost $OSC)
1950                 OSTIDX=$(index_from_ostuuid $OST)
1951                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1952                         OST_DEACTIVE_IDX=$OSTIDX
1953                 fi
1954                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1955                         echo $OSC "is Deactivated:"
1956                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1957                 fi
1958         done
1959
1960         OSTIDX=$(index_from_ostuuid $OST)
1961         test_mkdir $DIR/$tdir
1962         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1963
1964         for OSC in $MDS_OSCS; do
1965                 OST=$(osc_to_ost $OSC)
1966                 OSTIDX=$(index_from_ostuuid $OST)
1967                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1968                         echo $OST "is degraded:"
1969                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1970                                                 obdfilter.$OST.degraded=1
1971                 fi
1972         done
1973
1974         sleep_maxage
1975         createmany -o $DIR/$tdir/$tfile $fcount
1976
1977         for OSC in $MDS_OSCS; do
1978                 OST=$(osc_to_ost $OSC)
1979                 OSTIDX=$(index_from_ostuuid $OST)
1980                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1981                         echo $OST "is recovered from degraded:"
1982                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1983                                                 obdfilter.$OST.degraded=0
1984                 else
1985                         do_facet $SINGLEMDS lctl --device %$OSC activate
1986                 fi
1987         done
1988
1989         # all osp devices get activated, hence -1 stripe count restored
1990         local stripe_count=0
1991
1992         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1993         # devices get activated.
1994         sleep_maxage
1995         $LFS setstripe -c -1 $DIR/$tfile
1996         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1997         rm -f $DIR/$tfile
1998         [ $stripe_count -ne $OSTCOUNT ] &&
1999                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2000         return 0
2001 }
2002 run_test 27y "create files while OST0 is degraded and the rest inactive"
2003
2004 check_seq_oid()
2005 {
2006         log "check file $1"
2007
2008         lmm_count=$($LFS getstripe -c $1)
2009         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2010         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2011
2012         local old_ifs="$IFS"
2013         IFS=$'[:]'
2014         fid=($($LFS path2fid $1))
2015         IFS="$old_ifs"
2016
2017         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2018         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2019
2020         # compare lmm_seq and lu_fid->f_seq
2021         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2022         # compare lmm_object_id and lu_fid->oid
2023         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2024
2025         # check the trusted.fid attribute of the OST objects of the file
2026         local have_obdidx=false
2027         local stripe_nr=0
2028         $LFS getstripe $1 | while read obdidx oid hex seq; do
2029                 # skip lines up to and including "obdidx"
2030                 [ -z "$obdidx" ] && break
2031                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2032                 $have_obdidx || continue
2033
2034                 local ost=$((obdidx + 1))
2035                 local dev=$(ostdevname $ost)
2036                 local oid_hex
2037
2038                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2039
2040                 seq=$(echo $seq | sed -e "s/^0x//g")
2041                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2042                         oid_hex=$(echo $oid)
2043                 else
2044                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2045                 fi
2046                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2047
2048                 local ff=""
2049                 #
2050                 # Don't unmount/remount the OSTs if we don't need to do that.
2051                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2052                 # update too, until that use mount/ll_decode_filter_fid/mount.
2053                 # Re-enable when debugfs will understand new filter_fid.
2054                 #
2055                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2056                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2057                                 $dev 2>/dev/null" | grep "parent=")
2058                 fi
2059                 if [ -z "$ff" ]; then
2060                         stop ost$ost
2061                         mount_fstype ost$ost
2062                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2063                                 $(facet_mntpt ost$ost)/$obj_file)
2064                         unmount_fstype ost$ost
2065                         start ost$ost $dev $OST_MOUNT_OPTS
2066                         clients_up
2067                 fi
2068
2069                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2070
2071                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2072
2073                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2074                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2075                 #
2076                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2077                 #       stripe_size=1048576 component_id=1 component_start=0 \
2078                 #       component_end=33554432
2079                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2080                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2081                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2082                 local ff_pstripe
2083                 if grep -q 'stripe=' <<<$ff; then
2084                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2085                 else
2086                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2087                         # into f_ver in this case.  See comment on ff_parent.
2088                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2089                 fi
2090
2091                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2092                 [ $ff_pseq = $lmm_seq ] ||
2093                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2094                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2095                 [ $ff_poid = $lmm_oid ] ||
2096                         error "FF parent OID $ff_poid != $lmm_oid"
2097                 (($ff_pstripe == $stripe_nr)) ||
2098                         error "FF stripe $ff_pstripe != $stripe_nr"
2099
2100                 stripe_nr=$((stripe_nr + 1))
2101                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2102                         continue
2103                 if grep -q 'stripe_count=' <<<$ff; then
2104                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2105                                             -e 's/ .*//' <<<$ff)
2106                         [ $lmm_count = $ff_scnt ] ||
2107                                 error "FF stripe count $lmm_count != $ff_scnt"
2108                 fi
2109         done
2110 }
2111
2112 test_27z() {
2113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2114         remote_ost_nodsh && skip "remote OST with nodsh"
2115
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2118                 { error "setstripe -c -1 failed"; return 1; }
2119         # We need to send a write to every object to get parent FID info set.
2120         # This _should_ also work for setattr, but does not currently.
2121         # touch $DIR/$tdir/$tfile-1 ||
2122         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2123                 { error "dd $tfile-1 failed"; return 2; }
2124         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2125                 { error "setstripe -c -1 failed"; return 3; }
2126         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2127                 { error "dd $tfile-2 failed"; return 4; }
2128
2129         # make sure write RPCs have been sent to OSTs
2130         sync; sleep 5; sync
2131
2132         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2133         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2134 }
2135 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2136
2137 test_27A() { # b=19102
2138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2139
2140         save_layout_restore_at_exit $MOUNT
2141         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2142         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2143                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2144         local default_size=$($LFS getstripe -S $MOUNT)
2145         local default_offset=$($LFS getstripe -i $MOUNT)
2146         local dsize=$(do_facet $SINGLEMDS \
2147                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2148         [ $default_size -eq $dsize ] ||
2149                 error "stripe size $default_size != $dsize"
2150         [ $default_offset -eq -1 ] ||
2151                 error "stripe offset $default_offset != -1"
2152 }
2153 run_test 27A "check filesystem-wide default LOV EA values"
2154
2155 test_27B() { # LU-2523
2156         test_mkdir $DIR/$tdir
2157         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2158         touch $DIR/$tdir/f0
2159         # open f1 with O_LOV_DELAY_CREATE
2160         # rename f0 onto f1
2161         # call setstripe ioctl on open file descriptor for f1
2162         # close
2163         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2164                 $DIR/$tdir/f0
2165
2166         rm -f $DIR/$tdir/f1
2167         # open f1 with O_LOV_DELAY_CREATE
2168         # unlink f1
2169         # call setstripe ioctl on open file descriptor for f1
2170         # close
2171         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2172
2173         # Allow multiop to fail in imitation of NFS's busted semantics.
2174         true
2175 }
2176 run_test 27B "call setstripe on open unlinked file/rename victim"
2177
2178 test_27C() { #LU-2871
2179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2180
2181         declare -a ost_idx
2182         local index
2183         local found
2184         local i
2185         local j
2186
2187         test_mkdir $DIR/$tdir
2188         cd $DIR/$tdir
2189         for i in $(seq 0 $((OSTCOUNT - 1))); do
2190                 # set stripe across all OSTs starting from OST$i
2191                 $LFS setstripe -i $i -c -1 $tfile$i
2192                 # get striping information
2193                 ost_idx=($($LFS getstripe $tfile$i |
2194                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2195                 echo ${ost_idx[@]}
2196
2197                 # check the layout
2198                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2199                         error "${#ost_idx[@]} != $OSTCOUNT"
2200
2201                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2202                         found=0
2203                         for j in $(echo ${ost_idx[@]}); do
2204                                 if [ $index -eq $j ]; then
2205                                         found=1
2206                                         break
2207                                 fi
2208                         done
2209                         [ $found = 1 ] ||
2210                                 error "Can not find $index in ${ost_idx[@]}"
2211                 done
2212         done
2213 }
2214 run_test 27C "check full striping across all OSTs"
2215
2216 test_27D() {
2217         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2218         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2219         remote_mds_nodsh && skip "remote MDS with nodsh"
2220
2221         local POOL=${POOL:-testpool}
2222         local first_ost=0
2223         local last_ost=$(($OSTCOUNT - 1))
2224         local ost_step=1
2225         local ost_list=$(seq $first_ost $ost_step $last_ost)
2226         local ost_range="$first_ost $last_ost $ost_step"
2227
2228         if ! combined_mgs_mds ; then
2229                 mount_mgs_client
2230         fi
2231
2232         test_mkdir $DIR/$tdir
2233         pool_add $POOL || error "pool_add failed"
2234         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2235
2236         local skip27D
2237         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2238                 skip27D+="-s 29"
2239         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2240                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2241                         skip27D+=" -s 30,31"
2242         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2243                 error "llapi_layout_test failed"
2244
2245         destroy_test_pools || error "destroy test pools failed"
2246
2247         if ! combined_mgs_mds ; then
2248                 umount_mgs_client
2249         fi
2250 }
2251 run_test 27D "validate llapi_layout API"
2252
2253 # Verify that default_easize is increased from its initial value after
2254 # accessing a widely striped file.
2255 test_27E() {
2256         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2257         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2258                 skip "client does not have LU-3338 fix"
2259
2260         # 72 bytes is the minimum space required to store striping
2261         # information for a file striped across one OST:
2262         # (sizeof(struct lov_user_md_v3) +
2263         #  sizeof(struct lov_user_ost_data_v1))
2264         local min_easize=72
2265         $LCTL set_param -n llite.*.default_easize $min_easize ||
2266                 error "lctl set_param failed"
2267         local easize=$($LCTL get_param -n llite.*.default_easize)
2268
2269         [ $easize -eq $min_easize ] ||
2270                 error "failed to set default_easize"
2271
2272         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2273                 error "setstripe failed"
2274         cat $DIR/$tfile
2275         rm $DIR/$tfile
2276
2277         easize=$($LCTL get_param -n llite.*.default_easize)
2278
2279         [ $easize -gt $min_easize ] ||
2280                 error "default_easize not updated"
2281 }
2282 run_test 27E "check that default extended attribute size properly increases"
2283
2284 test_27F() { # LU-5346/LU-7975
2285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2286         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2287         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2288                 skip "Need MDS version at least 2.8.51"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         rm -f $DIR/$tdir/f0
2293         $LFS setstripe -c 2 $DIR/$tdir
2294
2295         # stop all OSTs to reproduce situation for LU-7975 ticket
2296         for num in $(seq $OSTCOUNT); do
2297                 stop ost$num
2298         done
2299
2300         # open/create f0 with O_LOV_DELAY_CREATE
2301         # truncate f0 to a non-0 size
2302         # close
2303         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2304
2305         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2306         # open/write it again to force delayed layout creation
2307         cat /etc/hosts > $DIR/$tdir/f0 &
2308         catpid=$!
2309
2310         # restart OSTs
2311         for num in $(seq $OSTCOUNT); do
2312                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2313                         error "ost$num failed to start"
2314         done
2315
2316         wait $catpid || error "cat failed"
2317
2318         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2319         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2320                 error "wrong stripecount"
2321
2322 }
2323 run_test 27F "Client resend delayed layout creation with non-zero size"
2324
2325 test_27G() { #LU-10629
2326         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2327                 skip "Need MDS version at least 2.11.51"
2328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2329         remote_mds_nodsh && skip "remote MDS with nodsh"
2330         local POOL=${POOL:-testpool}
2331         local ostrange="0 0 1"
2332
2333         test_mkdir $DIR/$tdir
2334         pool_add $POOL || error "pool_add failed"
2335         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2336         $LFS setstripe -p $POOL $DIR/$tdir
2337
2338         local pool=$($LFS getstripe -p $DIR/$tdir)
2339
2340         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2341
2342         $LFS setstripe -d $DIR/$tdir
2343
2344         pool=$($LFS getstripe -p $DIR/$tdir)
2345
2346         rmdir $DIR/$tdir
2347
2348         [ -z "$pool" ] || error "'$pool' is not empty"
2349 }
2350 run_test 27G "Clear OST pool from stripe"
2351
2352 test_27H() {
2353         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2354                 skip "Need MDS version newer than 2.11.54"
2355         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2358         touch $DIR/$tdir/$tfile
2359         $LFS getstripe -c $DIR/$tdir/$tfile
2360         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2361                 error "two-stripe file doesn't have two stripes"
2362
2363         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2364         $LFS getstripe -y $DIR/$tdir/$tfile
2365         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2366              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2367                 error "expected l_ost_idx: [02]$ not matched"
2368
2369         # make sure ost list has been cleared
2370         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2371         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2372                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2373         touch $DIR/$tdir/f3
2374         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2375 }
2376 run_test 27H "Set specific OSTs stripe"
2377
2378 test_27I() {
2379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2381         local pool=$TESTNAME
2382         local ostrange="1 1 1"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 2 -i 0 $MOUNT
2386         pool_add $pool || error "pool_add failed"
2387         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2388         test_mkdir $DIR/$tdir
2389         $LFS setstripe -p $pool $DIR/$tdir
2390         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2391         $LFS getstripe $DIR/$tdir/$tfile
2392 }
2393 run_test 27I "check that root dir striping does not break parent dir one"
2394
2395 # createtest also checks that device nodes are created and
2396 # then visible correctly (#2091)
2397 test_28() { # bug 2091
2398         test_mkdir $DIR/d28
2399         $CREATETEST $DIR/d28/ct || error "createtest failed"
2400 }
2401 run_test 28 "create/mknod/mkdir with bad file types ============"
2402
2403 test_29() {
2404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2405
2406         sync; sleep 1; sync # flush out any dirty pages from previous tests
2407         cancel_lru_locks
2408         test_mkdir $DIR/d29
2409         touch $DIR/d29/foo
2410         log 'first d29'
2411         ls -l $DIR/d29
2412
2413         declare -i LOCKCOUNTORIG=0
2414         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2415                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2416         done
2417         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2418
2419         declare -i LOCKUNUSEDCOUNTORIG=0
2420         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2421                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2422         done
2423
2424         log 'second d29'
2425         ls -l $DIR/d29
2426         log 'done'
2427
2428         declare -i LOCKCOUNTCURRENT=0
2429         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2430                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2431         done
2432
2433         declare -i LOCKUNUSEDCOUNTCURRENT=0
2434         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2435                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2436         done
2437
2438         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2439                 $LCTL set_param -n ldlm.dump_namespaces ""
2440                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2441                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2442                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2443                 return 2
2444         fi
2445         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2446                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2447                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2448                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2449                 return 3
2450         fi
2451 }
2452 run_test 29 "IT_GETATTR regression  ============================"
2453
2454 test_30a() { # was test_30
2455         cp $(which ls) $DIR || cp /bin/ls $DIR
2456         $DIR/ls / || error "Can't execute binary from lustre"
2457         rm $DIR/ls
2458 }
2459 run_test 30a "execute binary from Lustre (execve) =============="
2460
2461 test_30b() {
2462         cp `which ls` $DIR || cp /bin/ls $DIR
2463         chmod go+rx $DIR/ls
2464         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2465         rm $DIR/ls
2466 }
2467 run_test 30b "execute binary from Lustre as non-root ==========="
2468
2469 test_30c() { # b=22376
2470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2471
2472         cp `which ls` $DIR || cp /bin/ls $DIR
2473         chmod a-rw $DIR/ls
2474         cancel_lru_locks mdc
2475         cancel_lru_locks osc
2476         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2477         rm -f $DIR/ls
2478 }
2479 run_test 30c "execute binary from Lustre without read perms ===="
2480
2481 test_31a() {
2482         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2483         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2484 }
2485 run_test 31a "open-unlink file =================================="
2486
2487 test_31b() {
2488         touch $DIR/f31 || error "touch $DIR/f31 failed"
2489         ln $DIR/f31 $DIR/f31b || error "ln failed"
2490         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2491         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2492 }
2493 run_test 31b "unlink file with multiple links while open ======="
2494
2495 test_31c() {
2496         touch $DIR/f31 || error "touch $DIR/f31 failed"
2497         ln $DIR/f31 $DIR/f31c || error "ln failed"
2498         multiop_bg_pause $DIR/f31 O_uc ||
2499                 error "multiop_bg_pause for $DIR/f31 failed"
2500         MULTIPID=$!
2501         $MULTIOP $DIR/f31c Ouc
2502         kill -USR1 $MULTIPID
2503         wait $MULTIPID
2504 }
2505 run_test 31c "open-unlink file with multiple links ============="
2506
2507 test_31d() {
2508         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2509         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2510 }
2511 run_test 31d "remove of open directory ========================="
2512
2513 test_31e() { # bug 2904
2514         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2515 }
2516 run_test 31e "remove of open non-empty directory ==============="
2517
2518 test_31f() { # bug 4554
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520
2521         set -vx
2522         test_mkdir $DIR/d31f
2523         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2524         cp /etc/hosts $DIR/d31f
2525         ls -l $DIR/d31f
2526         $LFS getstripe $DIR/d31f/hosts
2527         multiop_bg_pause $DIR/d31f D_c || return 1
2528         MULTIPID=$!
2529
2530         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2531         test_mkdir $DIR/d31f
2532         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2533         cp /etc/hosts $DIR/d31f
2534         ls -l $DIR/d31f
2535         $LFS getstripe $DIR/d31f/hosts
2536         multiop_bg_pause $DIR/d31f D_c || return 1
2537         MULTIPID2=$!
2538
2539         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2540         wait $MULTIPID || error "first opendir $MULTIPID failed"
2541
2542         sleep 6
2543
2544         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2545         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2546         set +vx
2547 }
2548 run_test 31f "remove of open directory with open-unlink file ==="
2549
2550 test_31g() {
2551         echo "-- cross directory link --"
2552         test_mkdir -c1 $DIR/${tdir}ga
2553         test_mkdir -c1 $DIR/${tdir}gb
2554         touch $DIR/${tdir}ga/f
2555         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2556         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2557         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2558         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2559         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2560 }
2561 run_test 31g "cross directory link==============="
2562
2563 test_31h() {
2564         echo "-- cross directory link --"
2565         test_mkdir -c1 $DIR/${tdir}
2566         test_mkdir -c1 $DIR/${tdir}/dir
2567         touch $DIR/${tdir}/f
2568         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2569         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2570         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2571         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2572         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2573 }
2574 run_test 31h "cross directory link under child==============="
2575
2576 test_31i() {
2577         echo "-- cross directory link --"
2578         test_mkdir -c1 $DIR/$tdir
2579         test_mkdir -c1 $DIR/$tdir/dir
2580         touch $DIR/$tdir/dir/f
2581         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2582         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2583         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2584         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2585         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2586 }
2587 run_test 31i "cross directory link under parent==============="
2588
2589 test_31j() {
2590         test_mkdir -c1 -p $DIR/$tdir
2591         test_mkdir -c1 -p $DIR/$tdir/dir1
2592         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2593         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2594         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2595         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2596         return 0
2597 }
2598 run_test 31j "link for directory==============="
2599
2600 test_31k() {
2601         test_mkdir -c1 -p $DIR/$tdir
2602         touch $DIR/$tdir/s
2603         touch $DIR/$tdir/exist
2604         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2605         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2606         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2607         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2608         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2609         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2610         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2611         return 0
2612 }
2613 run_test 31k "link to file: the same, non-existing, dir==============="
2614
2615 test_31m() {
2616         mkdir $DIR/d31m
2617         touch $DIR/d31m/s
2618         mkdir $DIR/d31m2
2619         touch $DIR/d31m2/exist
2620         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2621         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2622         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2623         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2624         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2625         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2626         return 0
2627 }
2628 run_test 31m "link to file: the same, non-existing, dir==============="
2629
2630 test_31n() {
2631         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2632         nlink=$(stat --format=%h $DIR/$tfile)
2633         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2634         local fd=$(free_fd)
2635         local cmd="exec $fd<$DIR/$tfile"
2636         eval $cmd
2637         cmd="exec $fd<&-"
2638         trap "eval $cmd" EXIT
2639         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2640         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2641         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2643         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2644         eval $cmd
2645 }
2646 run_test 31n "check link count of unlinked file"
2647
2648 link_one() {
2649         local TEMPNAME=$(mktemp $1_XXXXXX)
2650         mlink $TEMPNAME $1 2> /dev/null &&
2651                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2652         munlink $TEMPNAME
2653 }
2654
2655 test_31o() { # LU-2901
2656         test_mkdir $DIR/$tdir
2657         for LOOP in $(seq 100); do
2658                 rm -f $DIR/$tdir/$tfile*
2659                 for THREAD in $(seq 8); do
2660                         link_one $DIR/$tdir/$tfile.$LOOP &
2661                 done
2662                 wait
2663                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2664                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2665                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2666                         break || true
2667         done
2668 }
2669 run_test 31o "duplicate hard links with same filename"
2670
2671 test_31p() {
2672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2673
2674         test_mkdir $DIR/$tdir
2675         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2676         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2677
2678         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2679                 error "open unlink test1 failed"
2680         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2681                 error "open unlink test2 failed"
2682
2683         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2684                 error "test1 still exists"
2685         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2686                 error "test2 still exists"
2687 }
2688 run_test 31p "remove of open striped directory"
2689
2690 cleanup_test32_mount() {
2691         local rc=0
2692         trap 0
2693         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2694         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2695         losetup -d $loopdev || true
2696         rm -rf $DIR/$tdir
2697         return $rc
2698 }
2699
2700 test_32a() {
2701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2702
2703         echo "== more mountpoints and symlinks ================="
2704         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2705         trap cleanup_test32_mount EXIT
2706         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2707         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2708                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2709         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2710                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2711         cleanup_test32_mount
2712 }
2713 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2714
2715 test_32b() {
2716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2717
2718         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2719         trap cleanup_test32_mount EXIT
2720         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2721         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2722                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2723         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2724                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2725         cleanup_test32_mount
2726 }
2727 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2728
2729 test_32c() {
2730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2731
2732         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2733         trap cleanup_test32_mount EXIT
2734         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2735         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2736                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2737         test_mkdir -p $DIR/$tdir/d2/test_dir
2738         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2739                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2740         cleanup_test32_mount
2741 }
2742 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2743
2744 test_32d() {
2745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2746
2747         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2748         trap cleanup_test32_mount EXIT
2749         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2750         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2751                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2752         test_mkdir -p $DIR/$tdir/d2/test_dir
2753         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2754                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2755         cleanup_test32_mount
2756 }
2757 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2758
2759 test_32e() {
2760         rm -fr $DIR/$tdir
2761         test_mkdir -p $DIR/$tdir/tmp
2762         local tmp_dir=$DIR/$tdir/tmp
2763         ln -s $DIR/$tdir $tmp_dir/symlink11
2764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2765         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2766         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2767 }
2768 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2769
2770 test_32f() {
2771         rm -fr $DIR/$tdir
2772         test_mkdir -p $DIR/$tdir/tmp
2773         local tmp_dir=$DIR/$tdir/tmp
2774         ln -s $DIR/$tdir $tmp_dir/symlink11
2775         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2776         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2777         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2778 }
2779 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2780
2781 test_32g() {
2782         local tmp_dir=$DIR/$tdir/tmp
2783         test_mkdir -p $tmp_dir
2784         test_mkdir $DIR/${tdir}2
2785         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2786         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2787         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2788         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2789         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2790         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2791 }
2792 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2793
2794 test_32h() {
2795         rm -fr $DIR/$tdir $DIR/${tdir}2
2796         tmp_dir=$DIR/$tdir/tmp
2797         test_mkdir -p $tmp_dir
2798         test_mkdir $DIR/${tdir}2
2799         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2800         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2801         ls $tmp_dir/symlink12 || error "listing symlink12"
2802         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2803 }
2804 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2805
2806 test_32i() {
2807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2808
2809         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2810         trap cleanup_test32_mount EXIT
2811         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2812         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2813                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2814         touch $DIR/$tdir/test_file
2815         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2816                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2817         cleanup_test32_mount
2818 }
2819 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2820
2821 test_32j() {
2822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2823
2824         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2825         trap cleanup_test32_mount EXIT
2826         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2827         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2828                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2829         touch $DIR/$tdir/test_file
2830         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2831                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2832         cleanup_test32_mount
2833 }
2834 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2835
2836 test_32k() {
2837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2838
2839         rm -fr $DIR/$tdir
2840         trap cleanup_test32_mount EXIT
2841         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2842         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2843                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2844         test_mkdir -p $DIR/$tdir/d2
2845         touch $DIR/$tdir/d2/test_file || error "touch failed"
2846         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2847                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2848         cleanup_test32_mount
2849 }
2850 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2851
2852 test_32l() {
2853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2854
2855         rm -fr $DIR/$tdir
2856         trap cleanup_test32_mount EXIT
2857         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2858         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2859                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2860         test_mkdir -p $DIR/$tdir/d2
2861         touch $DIR/$tdir/d2/test_file || error "touch failed"
2862         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2863                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2864         cleanup_test32_mount
2865 }
2866 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2867
2868 test_32m() {
2869         rm -fr $DIR/d32m
2870         test_mkdir -p $DIR/d32m/tmp
2871         TMP_DIR=$DIR/d32m/tmp
2872         ln -s $DIR $TMP_DIR/symlink11
2873         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2874         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2875                 error "symlink11 not a link"
2876         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2877                 error "symlink01 not a link"
2878 }
2879 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2880
2881 test_32n() {
2882         rm -fr $DIR/d32n
2883         test_mkdir -p $DIR/d32n/tmp
2884         TMP_DIR=$DIR/d32n/tmp
2885         ln -s $DIR $TMP_DIR/symlink11
2886         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2887         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2888         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2889 }
2890 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2891
2892 test_32o() {
2893         touch $DIR/$tfile
2894         test_mkdir -p $DIR/d32o/tmp
2895         TMP_DIR=$DIR/d32o/tmp
2896         ln -s $DIR/$tfile $TMP_DIR/symlink12
2897         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2898         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2899                 error "symlink12 not a link"
2900         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2901         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2902                 error "$DIR/d32o/tmp/symlink12 not file type"
2903         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2904                 error "$DIR/d32o/symlink02 not file type"
2905 }
2906 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2907
2908 test_32p() {
2909         log 32p_1
2910         rm -fr $DIR/d32p
2911         log 32p_2
2912         rm -f $DIR/$tfile
2913         log 32p_3
2914         touch $DIR/$tfile
2915         log 32p_4
2916         test_mkdir -p $DIR/d32p/tmp
2917         log 32p_5
2918         TMP_DIR=$DIR/d32p/tmp
2919         log 32p_6
2920         ln -s $DIR/$tfile $TMP_DIR/symlink12
2921         log 32p_7
2922         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2923         log 32p_8
2924         cat $DIR/d32p/tmp/symlink12 ||
2925                 error "Can't open $DIR/d32p/tmp/symlink12"
2926         log 32p_9
2927         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2928         log 32p_10
2929 }
2930 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2931
2932 test_32q() {
2933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2934
2935         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2936         trap cleanup_test32_mount EXIT
2937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2938         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2941         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2942         cleanup_test32_mount
2943 }
2944 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2945
2946 test_32r() {
2947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2948
2949         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2950         trap cleanup_test32_mount EXIT
2951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2952         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2953         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2954                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2955         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2956         cleanup_test32_mount
2957 }
2958 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2959
2960 test_33aa() {
2961         rm -f $DIR/$tfile
2962         touch $DIR/$tfile
2963         chmod 444 $DIR/$tfile
2964         chown $RUNAS_ID $DIR/$tfile
2965         log 33_1
2966         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2967         log 33_2
2968 }
2969 run_test 33aa "write file with mode 444 (should return error)"
2970
2971 test_33a() {
2972         rm -fr $DIR/$tdir
2973         test_mkdir $DIR/$tdir
2974         chown $RUNAS_ID $DIR/$tdir
2975         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2976                 error "$RUNAS create $tdir/$tfile failed"
2977         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2978                 error "open RDWR" || true
2979 }
2980 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2981
2982 test_33b() {
2983         rm -fr $DIR/$tdir
2984         test_mkdir $DIR/$tdir
2985         chown $RUNAS_ID $DIR/$tdir
2986         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2987 }
2988 run_test 33b "test open file with malformed flags (No panic)"
2989
2990 test_33c() {
2991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2992         remote_ost_nodsh && skip "remote OST with nodsh"
2993
2994         local ostnum
2995         local ostname
2996         local write_bytes
2997         local all_zeros
2998
2999         all_zeros=:
3000         rm -fr $DIR/$tdir
3001         test_mkdir $DIR/$tdir
3002         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3003
3004         sync
3005         for ostnum in $(seq $OSTCOUNT); do
3006                 # test-framework's OST numbering is one-based, while Lustre's
3007                 # is zero-based
3008                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3009                 # Parsing llobdstat's output sucks; we could grep the /proc
3010                 # path, but that's likely to not be as portable as using the
3011                 # llobdstat utility.  So we parse lctl output instead.
3012                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3013                         obdfilter/$ostname/stats |
3014                         awk '/^write_bytes/ {print $7}' )
3015                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3016                 if (( ${write_bytes:-0} > 0 ))
3017                 then
3018                         all_zeros=false
3019                         break;
3020                 fi
3021         done
3022
3023         $all_zeros || return 0
3024
3025         # Write four bytes
3026         echo foo > $DIR/$tdir/bar
3027         # Really write them
3028         sync
3029
3030         # Total up write_bytes after writing.  We'd better find non-zeros.
3031         for ostnum in $(seq $OSTCOUNT); do
3032                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3033                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3034                         obdfilter/$ostname/stats |
3035                         awk '/^write_bytes/ {print $7}' )
3036                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3037                 if (( ${write_bytes:-0} > 0 ))
3038                 then
3039                         all_zeros=false
3040                         break;
3041                 fi
3042         done
3043
3044         if $all_zeros
3045         then
3046                 for ostnum in $(seq $OSTCOUNT); do
3047                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3048                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3049                         do_facet ost$ostnum lctl get_param -n \
3050                                 obdfilter/$ostname/stats
3051                 done
3052                 error "OST not keeping write_bytes stats (b22312)"
3053         fi
3054 }
3055 run_test 33c "test llobdstat and write_bytes"
3056
3057 test_33d() {
3058         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         local MDTIDX=1
3062         local remote_dir=$DIR/$tdir/remote_dir
3063
3064         test_mkdir $DIR/$tdir
3065         $LFS mkdir -i $MDTIDX $remote_dir ||
3066                 error "create remote directory failed"
3067
3068         touch $remote_dir/$tfile
3069         chmod 444 $remote_dir/$tfile
3070         chown $RUNAS_ID $remote_dir/$tfile
3071
3072         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3073
3074         chown $RUNAS_ID $remote_dir
3075         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3076                                         error "create" || true
3077         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3078                                     error "open RDWR" || true
3079         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3080 }
3081 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3082
3083 test_33e() {
3084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3085
3086         mkdir $DIR/$tdir
3087
3088         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3089         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3090         mkdir $DIR/$tdir/local_dir
3091
3092         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3093         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3094         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3095
3096         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3097                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3098
3099         rmdir $DIR/$tdir/* || error "rmdir failed"
3100
3101         umask 777
3102         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3103         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3104         mkdir $DIR/$tdir/local_dir
3105
3106         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3107         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3108         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3109
3110         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3111                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3112
3113         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3114
3115         umask 000
3116         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3117         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3118         mkdir $DIR/$tdir/local_dir
3119
3120         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3121         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3122         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3123
3124         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3125                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3126 }
3127 run_test 33e "mkdir and striped directory should have same mode"
3128
3129 cleanup_33f() {
3130         trap 0
3131         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3132 }
3133
3134 test_33f() {
3135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3136         remote_mds_nodsh && skip "remote MDS with nodsh"
3137
3138         mkdir $DIR/$tdir
3139         chmod go+rwx $DIR/$tdir
3140         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3141         trap cleanup_33f EXIT
3142
3143         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3144                 error "cannot create striped directory"
3145
3146         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3147                 error "cannot create files in striped directory"
3148
3149         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3150                 error "cannot remove files in striped directory"
3151
3152         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3153                 error "cannot remove striped directory"
3154
3155         cleanup_33f
3156 }
3157 run_test 33f "nonroot user can create, access, and remove a striped directory"
3158
3159 test_33g() {
3160         mkdir -p $DIR/$tdir/dir2
3161
3162         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3163         echo $err
3164         [[ $err =~ "exists" ]] || error "Not exists error"
3165 }
3166 run_test 33g "nonroot user create already existing root created file"
3167
3168 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3169 test_34a() {
3170         rm -f $DIR/f34
3171         $MCREATE $DIR/f34 || error "mcreate failed"
3172         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3173                 error "getstripe failed"
3174         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3175         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3176                 error "getstripe failed"
3177         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3178                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3179 }
3180 run_test 34a "truncate file that has not been opened ==========="
3181
3182 test_34b() {
3183         [ ! -f $DIR/f34 ] && test_34a
3184         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3185                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3186         $OPENFILE -f O_RDONLY $DIR/f34
3187         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3188                 error "getstripe failed"
3189         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3190                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3191 }
3192 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3193
3194 test_34c() {
3195         [ ! -f $DIR/f34 ] && test_34a
3196         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3197                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3198         $OPENFILE -f O_RDWR $DIR/f34
3199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3200                 error "$LFS getstripe failed"
3201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3203 }
3204 run_test 34c "O_RDWR opening file-with-size works =============="
3205
3206 test_34d() {
3207         [ ! -f $DIR/f34 ] && test_34a
3208         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3209                 error "dd failed"
3210         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3211                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3212         rm $DIR/f34
3213 }
3214 run_test 34d "write to sparse file ============================="
3215
3216 test_34e() {
3217         rm -f $DIR/f34e
3218         $MCREATE $DIR/f34e || error "mcreate failed"
3219         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3220         $CHECKSTAT -s 1000 $DIR/f34e ||
3221                 error "Size of $DIR/f34e not equal to 1000 bytes"
3222         $OPENFILE -f O_RDWR $DIR/f34e
3223         $CHECKSTAT -s 1000 $DIR/f34e ||
3224                 error "Size of $DIR/f34e not equal to 1000 bytes"
3225 }
3226 run_test 34e "create objects, some with size and some without =="
3227
3228 test_34f() { # bug 6242, 6243
3229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3230
3231         SIZE34F=48000
3232         rm -f $DIR/f34f
3233         $MCREATE $DIR/f34f || error "mcreate failed"
3234         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3235         dd if=$DIR/f34f of=$TMP/f34f
3236         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3237         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3238         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3239         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3240         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3241 }
3242 run_test 34f "read from a file with no objects until EOF ======="
3243
3244 test_34g() {
3245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3246
3247         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3248                 error "dd failed"
3249         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3250         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3251                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3252         cancel_lru_locks osc
3253         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3254                 error "wrong size after lock cancel"
3255
3256         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3257         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3258                 error "expanding truncate failed"
3259         cancel_lru_locks osc
3260         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3261                 error "wrong expanded size after lock cancel"
3262 }
3263 run_test 34g "truncate long file ==============================="
3264
3265 test_34h() {
3266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3267
3268         local gid=10
3269         local sz=1000
3270
3271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3272         sync # Flush the cache so that multiop below does not block on cache
3273              # flush when getting the group lock
3274         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3275         MULTIPID=$!
3276
3277         # Since just timed wait is not good enough, let's do a sync write
3278         # that way we are sure enough time for a roundtrip + processing
3279         # passed + 2 seconds of extra margin.
3280         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3281         rm $DIR/${tfile}-1
3282         sleep 2
3283
3284         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3285                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3286                 kill -9 $MULTIPID
3287         fi
3288         wait $MULTIPID
3289         local nsz=`stat -c %s $DIR/$tfile`
3290         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3291 }
3292 run_test 34h "ftruncate file under grouplock should not block"
3293
3294 test_35a() {
3295         cp /bin/sh $DIR/f35a
3296         chmod 444 $DIR/f35a
3297         chown $RUNAS_ID $DIR/f35a
3298         $RUNAS $DIR/f35a && error || true
3299         rm $DIR/f35a
3300 }
3301 run_test 35a "exec file with mode 444 (should return and not leak)"
3302
3303 test_36a() {
3304         rm -f $DIR/f36
3305         utime $DIR/f36 || error "utime failed for MDS"
3306 }
3307 run_test 36a "MDS utime check (mknod, utime)"
3308
3309 test_36b() {
3310         echo "" > $DIR/f36
3311         utime $DIR/f36 || error "utime failed for OST"
3312 }
3313 run_test 36b "OST utime check (open, utime)"
3314
3315 test_36c() {
3316         rm -f $DIR/d36/f36
3317         test_mkdir $DIR/d36
3318         chown $RUNAS_ID $DIR/d36
3319         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3320 }
3321 run_test 36c "non-root MDS utime check (mknod, utime)"
3322
3323 test_36d() {
3324         [ ! -d $DIR/d36 ] && test_36c
3325         echo "" > $DIR/d36/f36
3326         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3327 }
3328 run_test 36d "non-root OST utime check (open, utime)"
3329
3330 test_36e() {
3331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3332
3333         test_mkdir $DIR/$tdir
3334         touch $DIR/$tdir/$tfile
3335         $RUNAS utime $DIR/$tdir/$tfile &&
3336                 error "utime worked, expected failure" || true
3337 }
3338 run_test 36e "utime on non-owned file (should return error)"
3339
3340 subr_36fh() {
3341         local fl="$1"
3342         local LANG_SAVE=$LANG
3343         local LC_LANG_SAVE=$LC_LANG
3344         export LANG=C LC_LANG=C # for date language
3345
3346         DATESTR="Dec 20  2000"
3347         test_mkdir $DIR/$tdir
3348         lctl set_param fail_loc=$fl
3349         date; date +%s
3350         cp /etc/hosts $DIR/$tdir/$tfile
3351         sync & # write RPC generated with "current" inode timestamp, but delayed
3352         sleep 1
3353         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3354         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3355         cancel_lru_locks $OSC
3356         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3357         date; date +%s
3358         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3359                 echo "BEFORE: $LS_BEFORE" && \
3360                 echo "AFTER : $LS_AFTER" && \
3361                 echo "WANT  : $DATESTR" && \
3362                 error "$DIR/$tdir/$tfile timestamps changed" || true
3363
3364         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3365 }
3366
3367 test_36f() {
3368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3369
3370         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3371         subr_36fh "0x80000214"
3372 }
3373 run_test 36f "utime on file racing with OST BRW write =========="
3374
3375 test_36g() {
3376         remote_ost_nodsh && skip "remote OST with nodsh"
3377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3378         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3379                 skip "Need MDS version at least 2.12.51"
3380
3381         local fmd_max_age
3382         local fmd
3383         local facet="ost1"
3384         local tgt="obdfilter"
3385
3386         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3387
3388         test_mkdir $DIR/$tdir
3389         fmd_max_age=$(do_facet $facet \
3390                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3391                 head -n 1")
3392
3393         echo "FMD max age: ${fmd_max_age}s"
3394         touch $DIR/$tdir/$tfile
3395         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3396                 gawk '{cnt=cnt+$1}  END{print cnt}')
3397         echo "FMD before: $fmd"
3398         [[ $fmd == 0 ]] &&
3399                 error "FMD wasn't create by touch"
3400         sleep $((fmd_max_age + 12))
3401         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3402                 gawk '{cnt=cnt+$1}  END{print cnt}')
3403         echo "FMD after: $fmd"
3404         [[ $fmd == 0 ]] ||
3405                 error "FMD wasn't expired by ping"
3406 }
3407 run_test 36g "FMD cache expiry ====================="
3408
3409 test_36h() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3413         subr_36fh "0x80000227"
3414 }
3415 run_test 36h "utime on file racing with OST BRW write =========="
3416
3417 test_36i() {
3418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3419
3420         test_mkdir $DIR/$tdir
3421         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3422
3423         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3424         local new_mtime=$((mtime + 200))
3425
3426         #change Modify time of striped dir
3427         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3428                         error "change mtime failed"
3429
3430         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3431
3432         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3433 }
3434 run_test 36i "change mtime on striped directory"
3435
3436 # test_37 - duplicate with tests 32q 32r
3437
3438 test_38() {
3439         local file=$DIR/$tfile
3440         touch $file
3441         openfile -f O_DIRECTORY $file
3442         local RC=$?
3443         local ENOTDIR=20
3444         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3445         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3446 }
3447 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3448
3449 test_39a() { # was test_39
3450         touch $DIR/$tfile
3451         touch $DIR/${tfile}2
3452 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3453 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3454 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3455         sleep 2
3456         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3457         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3458                 echo "mtime"
3459                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3460                 echo "atime"
3461                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3462                 echo "ctime"
3463                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3464                 error "O_TRUNC didn't change timestamps"
3465         fi
3466 }
3467 run_test 39a "mtime changed on create"
3468
3469 test_39b() {
3470         test_mkdir -c1 $DIR/$tdir
3471         cp -p /etc/passwd $DIR/$tdir/fopen
3472         cp -p /etc/passwd $DIR/$tdir/flink
3473         cp -p /etc/passwd $DIR/$tdir/funlink
3474         cp -p /etc/passwd $DIR/$tdir/frename
3475         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3476
3477         sleep 1
3478         echo "aaaaaa" >> $DIR/$tdir/fopen
3479         echo "aaaaaa" >> $DIR/$tdir/flink
3480         echo "aaaaaa" >> $DIR/$tdir/funlink
3481         echo "aaaaaa" >> $DIR/$tdir/frename
3482
3483         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3484         local link_new=`stat -c %Y $DIR/$tdir/flink`
3485         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3486         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3487
3488         cat $DIR/$tdir/fopen > /dev/null
3489         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3490         rm -f $DIR/$tdir/funlink2
3491         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3492
3493         for (( i=0; i < 2; i++ )) ; do
3494                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3495                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3496                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3497                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3498
3499                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3500                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3501                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3502                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3503
3504                 cancel_lru_locks $OSC
3505                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3506         done
3507 }
3508 run_test 39b "mtime change on open, link, unlink, rename  ======"
3509
3510 # this should be set to past
3511 TEST_39_MTIME=`date -d "1 year ago" +%s`
3512
3513 # bug 11063
3514 test_39c() {
3515         touch $DIR1/$tfile
3516         sleep 2
3517         local mtime0=`stat -c %Y $DIR1/$tfile`
3518
3519         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3520         local mtime1=`stat -c %Y $DIR1/$tfile`
3521         [ "$mtime1" = $TEST_39_MTIME ] || \
3522                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3523
3524         local d1=`date +%s`
3525         echo hello >> $DIR1/$tfile
3526         local d2=`date +%s`
3527         local mtime2=`stat -c %Y $DIR1/$tfile`
3528         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3529                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3530
3531         mv $DIR1/$tfile $DIR1/$tfile-1
3532
3533         for (( i=0; i < 2; i++ )) ; do
3534                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3535                 [ "$mtime2" = "$mtime3" ] || \
3536                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3537
3538                 cancel_lru_locks $OSC
3539                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3540         done
3541 }
3542 run_test 39c "mtime change on rename ==========================="
3543
3544 # bug 21114
3545 test_39d() {
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         touch $DIR1/$tfile
3549         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3550
3551         for (( i=0; i < 2; i++ )) ; do
3552                 local mtime=`stat -c %Y $DIR1/$tfile`
3553                 [ $mtime = $TEST_39_MTIME ] || \
3554                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3555
3556                 cancel_lru_locks $OSC
3557                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3558         done
3559 }
3560 run_test 39d "create, utime, stat =============================="
3561
3562 # bug 21114
3563 test_39e() {
3564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3565
3566         touch $DIR1/$tfile
3567         local mtime1=`stat -c %Y $DIR1/$tfile`
3568
3569         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3570
3571         for (( i=0; i < 2; i++ )) ; do
3572                 local mtime2=`stat -c %Y $DIR1/$tfile`
3573                 [ $mtime2 = $TEST_39_MTIME ] || \
3574                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3575
3576                 cancel_lru_locks $OSC
3577                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3578         done
3579 }
3580 run_test 39e "create, stat, utime, stat ========================"
3581
3582 # bug 21114
3583 test_39f() {
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         touch $DIR1/$tfile
3587         mtime1=`stat -c %Y $DIR1/$tfile`
3588
3589         sleep 2
3590         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3591
3592         for (( i=0; i < 2; i++ )) ; do
3593                 local mtime2=`stat -c %Y $DIR1/$tfile`
3594                 [ $mtime2 = $TEST_39_MTIME ] || \
3595                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3596
3597                 cancel_lru_locks $OSC
3598                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3599         done
3600 }
3601 run_test 39f "create, stat, sleep, utime, stat ================="
3602
3603 # bug 11063
3604 test_39g() {
3605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3606
3607         echo hello >> $DIR1/$tfile
3608         local mtime1=`stat -c %Y $DIR1/$tfile`
3609
3610         sleep 2
3611         chmod o+r $DIR1/$tfile
3612
3613         for (( i=0; i < 2; i++ )) ; do
3614                 local mtime2=`stat -c %Y $DIR1/$tfile`
3615                 [ "$mtime1" = "$mtime2" ] || \
3616                         error "lost mtime: $mtime2, should be $mtime1"
3617
3618                 cancel_lru_locks $OSC
3619                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3620         done
3621 }
3622 run_test 39g "write, chmod, stat ==============================="
3623
3624 # bug 11063
3625 test_39h() {
3626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3627
3628         touch $DIR1/$tfile
3629         sleep 1
3630
3631         local d1=`date`
3632         echo hello >> $DIR1/$tfile
3633         local mtime1=`stat -c %Y $DIR1/$tfile`
3634
3635         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3636         local d2=`date`
3637         if [ "$d1" != "$d2" ]; then
3638                 echo "write and touch not within one second"
3639         else
3640                 for (( i=0; i < 2; i++ )) ; do
3641                         local mtime2=`stat -c %Y $DIR1/$tfile`
3642                         [ "$mtime2" = $TEST_39_MTIME ] || \
3643                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3644
3645                         cancel_lru_locks $OSC
3646                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3647                 done
3648         fi
3649 }
3650 run_test 39h "write, utime within one second, stat ============="
3651
3652 test_39i() {
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         touch $DIR1/$tfile
3656         sleep 1
3657
3658         echo hello >> $DIR1/$tfile
3659         local mtime1=`stat -c %Y $DIR1/$tfile`
3660
3661         mv $DIR1/$tfile $DIR1/$tfile-1
3662
3663         for (( i=0; i < 2; i++ )) ; do
3664                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3665
3666                 [ "$mtime1" = "$mtime2" ] || \
3667                         error "lost mtime: $mtime2, should be $mtime1"
3668
3669                 cancel_lru_locks $OSC
3670                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3671         done
3672 }
3673 run_test 39i "write, rename, stat =============================="
3674
3675 test_39j() {
3676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3677
3678         start_full_debug_logging
3679         touch $DIR1/$tfile
3680         sleep 1
3681
3682         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3683         lctl set_param fail_loc=0x80000412
3684         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3685                 error "multiop failed"
3686         local multipid=$!
3687         local mtime1=`stat -c %Y $DIR1/$tfile`
3688
3689         mv $DIR1/$tfile $DIR1/$tfile-1
3690
3691         kill -USR1 $multipid
3692         wait $multipid || error "multiop close failed"
3693
3694         for (( i=0; i < 2; i++ )) ; do
3695                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3696                 [ "$mtime1" = "$mtime2" ] ||
3697                         error "mtime is lost on close: $mtime2, " \
3698                               "should be $mtime1"
3699
3700                 cancel_lru_locks $OSC
3701                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3702         done
3703         lctl set_param fail_loc=0
3704         stop_full_debug_logging
3705 }
3706 run_test 39j "write, rename, close, stat ======================="
3707
3708 test_39k() {
3709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3710
3711         touch $DIR1/$tfile
3712         sleep 1
3713
3714         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3715         local multipid=$!
3716         local mtime1=`stat -c %Y $DIR1/$tfile`
3717
3718         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3719
3720         kill -USR1 $multipid
3721         wait $multipid || error "multiop close failed"
3722
3723         for (( i=0; i < 2; i++ )) ; do
3724                 local mtime2=`stat -c %Y $DIR1/$tfile`
3725
3726                 [ "$mtime2" = $TEST_39_MTIME ] || \
3727                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3728
3729                 cancel_lru_locks osc
3730                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3731         done
3732 }
3733 run_test 39k "write, utime, close, stat ========================"
3734
3735 # this should be set to future
3736 TEST_39_ATIME=`date -d "1 year" +%s`
3737
3738 test_39l() {
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3740         remote_mds_nodsh && skip "remote MDS with nodsh"
3741
3742         local atime_diff=$(do_facet $SINGLEMDS \
3743                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3744         rm -rf $DIR/$tdir
3745         mkdir -p $DIR/$tdir
3746
3747         # test setting directory atime to future
3748         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3749         local atime=$(stat -c %X $DIR/$tdir)
3750         [ "$atime" = $TEST_39_ATIME ] ||
3751                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3752
3753         # test setting directory atime from future to now
3754         local now=$(date +%s)
3755         touch -a -d @$now $DIR/$tdir
3756
3757         atime=$(stat -c %X $DIR/$tdir)
3758         [ "$atime" -eq "$now"  ] ||
3759                 error "atime is not updated from future: $atime, $now"
3760
3761         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3762         sleep 3
3763
3764         # test setting directory atime when now > dir atime + atime_diff
3765         local d1=$(date +%s)
3766         ls $DIR/$tdir
3767         local d2=$(date +%s)
3768         cancel_lru_locks mdc
3769         atime=$(stat -c %X $DIR/$tdir)
3770         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3771                 error "atime is not updated  : $atime, should be $d2"
3772
3773         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3774         sleep 3
3775
3776         # test not setting directory atime when now < dir atime + atime_diff
3777         ls $DIR/$tdir
3778         cancel_lru_locks mdc
3779         atime=$(stat -c %X $DIR/$tdir)
3780         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3781                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3782
3783         do_facet $SINGLEMDS \
3784                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3785 }
3786 run_test 39l "directory atime update ==========================="
3787
3788 test_39m() {
3789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3790
3791         touch $DIR1/$tfile
3792         sleep 2
3793         local far_past_mtime=$(date -d "May 29 1953" +%s)
3794         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3795
3796         touch -m -d @$far_past_mtime $DIR1/$tfile
3797         touch -a -d @$far_past_atime $DIR1/$tfile
3798
3799         for (( i=0; i < 2; i++ )) ; do
3800                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3801                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3802                         error "atime or mtime set incorrectly"
3803
3804                 cancel_lru_locks $OSC
3805                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3806         done
3807 }
3808 run_test 39m "test atime and mtime before 1970"
3809
3810 test_39n() { # LU-3832
3811         remote_mds_nodsh && skip "remote MDS with nodsh"
3812
3813         local atime_diff=$(do_facet $SINGLEMDS \
3814                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3815         local atime0
3816         local atime1
3817         local atime2
3818
3819         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3820
3821         rm -rf $DIR/$tfile
3822         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3823         atime0=$(stat -c %X $DIR/$tfile)
3824
3825         sleep 5
3826         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3827         atime1=$(stat -c %X $DIR/$tfile)
3828
3829         sleep 5
3830         cancel_lru_locks mdc
3831         cancel_lru_locks osc
3832         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3833         atime2=$(stat -c %X $DIR/$tfile)
3834
3835         do_facet $SINGLEMDS \
3836                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3837
3838         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3839         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3840 }
3841 run_test 39n "check that O_NOATIME is honored"
3842
3843 test_39o() {
3844         TESTDIR=$DIR/$tdir/$tfile
3845         [ -e $TESTDIR ] && rm -rf $TESTDIR
3846         mkdir -p $TESTDIR
3847         cd $TESTDIR
3848         links1=2
3849         ls
3850         mkdir a b
3851         ls
3852         links2=$(stat -c %h .)
3853         [ $(($links1 + 2)) != $links2 ] &&
3854                 error "wrong links count $(($links1 + 2)) != $links2"
3855         rmdir b
3856         links3=$(stat -c %h .)
3857         [ $(($links1 + 1)) != $links3 ] &&
3858                 error "wrong links count $links1 != $links3"
3859         return 0
3860 }
3861 run_test 39o "directory cached attributes updated after create"
3862
3863 test_39p() {
3864         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3865
3866         local MDTIDX=1
3867         TESTDIR=$DIR/$tdir/$tdir
3868         [ -e $TESTDIR ] && rm -rf $TESTDIR
3869         test_mkdir -p $TESTDIR
3870         cd $TESTDIR
3871         links1=2
3872         ls
3873         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3874         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3875         ls
3876         links2=$(stat -c %h .)
3877         [ $(($links1 + 2)) != $links2 ] &&
3878                 error "wrong links count $(($links1 + 2)) != $links2"
3879         rmdir remote_dir2
3880         links3=$(stat -c %h .)
3881         [ $(($links1 + 1)) != $links3 ] &&
3882                 error "wrong links count $links1 != $links3"
3883         return 0
3884 }
3885 run_test 39p "remote directory cached attributes updated after create ========"
3886
3887
3888 test_39q() { # LU-8041
3889         local testdir=$DIR/$tdir
3890         mkdir -p $testdir
3891         multiop_bg_pause $testdir D_c || error "multiop failed"
3892         local multipid=$!
3893         cancel_lru_locks mdc
3894         kill -USR1 $multipid
3895         local atime=$(stat -c %X $testdir)
3896         [ "$atime" -ne 0 ] || error "atime is zero"
3897 }
3898 run_test 39q "close won't zero out atime"
3899
3900 test_40() {
3901         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3902         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3903                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3904         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3905                 error "$tfile is not 4096 bytes in size"
3906 }
3907 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3908
3909 test_41() {
3910         # bug 1553
3911         small_write $DIR/f41 18
3912 }
3913 run_test 41 "test small file write + fstat ====================="
3914
3915 count_ost_writes() {
3916         lctl get_param -n ${OSC}.*.stats |
3917                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3918                         END { printf("%0.0f", writes) }'
3919 }
3920
3921 # decent default
3922 WRITEBACK_SAVE=500
3923 DIRTY_RATIO_SAVE=40
3924 MAX_DIRTY_RATIO=50
3925 BG_DIRTY_RATIO_SAVE=10
3926 MAX_BG_DIRTY_RATIO=25
3927
3928 start_writeback() {
3929         trap 0
3930         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3931         # dirty_ratio, dirty_background_ratio
3932         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3933                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3934                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3935                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3936         else
3937                 # if file not here, we are a 2.4 kernel
3938                 kill -CONT `pidof kupdated`
3939         fi
3940 }
3941
3942 stop_writeback() {
3943         # setup the trap first, so someone cannot exit the test at the
3944         # exact wrong time and mess up a machine
3945         trap start_writeback EXIT
3946         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3947         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3948                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3949                 sysctl -w vm.dirty_writeback_centisecs=0
3950                 sysctl -w vm.dirty_writeback_centisecs=0
3951                 # save and increase /proc/sys/vm/dirty_ratio
3952                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3953                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3954                 # save and increase /proc/sys/vm/dirty_background_ratio
3955                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3956                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3957         else
3958                 # if file not here, we are a 2.4 kernel
3959                 kill -STOP `pidof kupdated`
3960         fi
3961 }
3962
3963 # ensure that all stripes have some grant before we test client-side cache
3964 setup_test42() {
3965         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3966                 dd if=/dev/zero of=$i bs=4k count=1
3967                 rm $i
3968         done
3969 }
3970
3971 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3972 # file truncation, and file removal.
3973 test_42a() {
3974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3975
3976         setup_test42
3977         cancel_lru_locks $OSC
3978         stop_writeback
3979         sync; sleep 1; sync # just to be safe
3980         BEFOREWRITES=`count_ost_writes`
3981         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3982         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3983         AFTERWRITES=`count_ost_writes`
3984         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3985                 error "$BEFOREWRITES < $AFTERWRITES"
3986         start_writeback
3987 }
3988 run_test 42a "ensure that we don't flush on close"
3989
3990 test_42b() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         setup_test42
3994         cancel_lru_locks $OSC
3995         stop_writeback
3996         sync
3997         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3998         BEFOREWRITES=$(count_ost_writes)
3999         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4000         AFTERWRITES=$(count_ost_writes)
4001         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4002                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4003         fi
4004         BEFOREWRITES=$(count_ost_writes)
4005         sync || error "sync: $?"
4006         AFTERWRITES=$(count_ost_writes)
4007         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4008                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4009         fi
4010         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4011         start_writeback
4012         return 0
4013 }
4014 run_test 42b "test destroy of file with cached dirty data ======"
4015
4016 # if these tests just want to test the effect of truncation,
4017 # they have to be very careful.  consider:
4018 # - the first open gets a {0,EOF}PR lock
4019 # - the first write conflicts and gets a {0, count-1}PW
4020 # - the rest of the writes are under {count,EOF}PW
4021 # - the open for truncate tries to match a {0,EOF}PR
4022 #   for the filesize and cancels the PWs.
4023 # any number of fixes (don't get {0,EOF} on open, match
4024 # composite locks, do smarter file size management) fix
4025 # this, but for now we want these tests to verify that
4026 # the cancellation with truncate intent works, so we
4027 # start the file with a full-file pw lock to match against
4028 # until the truncate.
4029 trunc_test() {
4030         test=$1
4031         file=$DIR/$test
4032         offset=$2
4033         cancel_lru_locks $OSC
4034         stop_writeback
4035         # prime the file with 0,EOF PW to match
4036         touch $file
4037         $TRUNCATE $file 0
4038         sync; sync
4039         # now the real test..
4040         dd if=/dev/zero of=$file bs=1024 count=100
4041         BEFOREWRITES=`count_ost_writes`
4042         $TRUNCATE $file $offset
4043         cancel_lru_locks $OSC
4044         AFTERWRITES=`count_ost_writes`
4045         start_writeback
4046 }
4047
4048 test_42c() {
4049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4050
4051         trunc_test 42c 1024
4052         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4053                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4054         rm $file
4055 }
4056 run_test 42c "test partial truncate of file with cached dirty data"
4057
4058 test_42d() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         trunc_test 42d 0
4062         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4063                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4064         rm $file
4065 }
4066 run_test 42d "test complete truncate of file with cached dirty data"
4067
4068 test_42e() { # bug22074
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070
4071         local TDIR=$DIR/${tdir}e
4072         local pages=16 # hardcoded 16 pages, don't change it.
4073         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4074         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4075         local max_dirty_mb
4076         local warmup_files
4077
4078         test_mkdir $DIR/${tdir}e
4079         $LFS setstripe -c 1 $TDIR
4080         createmany -o $TDIR/f $files
4081
4082         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4083
4084         # we assume that with $OSTCOUNT files, at least one of them will
4085         # be allocated on OST0.
4086         warmup_files=$((OSTCOUNT * max_dirty_mb))
4087         createmany -o $TDIR/w $warmup_files
4088
4089         # write a large amount of data into one file and sync, to get good
4090         # avail_grant number from OST.
4091         for ((i=0; i<$warmup_files; i++)); do
4092                 idx=$($LFS getstripe -i $TDIR/w$i)
4093                 [ $idx -ne 0 ] && continue
4094                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4095                 break
4096         done
4097         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4098         sync
4099         $LCTL get_param $proc_osc0/cur_dirty_bytes
4100         $LCTL get_param $proc_osc0/cur_grant_bytes
4101
4102         # create as much dirty pages as we can while not to trigger the actual
4103         # RPCs directly. but depends on the env, VFS may trigger flush during this
4104         # period, hopefully we are good.
4105         for ((i=0; i<$warmup_files; i++)); do
4106                 idx=$($LFS getstripe -i $TDIR/w$i)
4107                 [ $idx -ne 0 ] && continue
4108                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4109         done
4110         $LCTL get_param $proc_osc0/cur_dirty_bytes
4111         $LCTL get_param $proc_osc0/cur_grant_bytes
4112
4113         # perform the real test
4114         $LCTL set_param $proc_osc0/rpc_stats 0
4115         for ((;i<$files; i++)); do
4116                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4117                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4118         done
4119         sync
4120         $LCTL get_param $proc_osc0/rpc_stats
4121
4122         local percent=0
4123         local have_ppr=false
4124         $LCTL get_param $proc_osc0/rpc_stats |
4125                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4126                         # skip lines until we are at the RPC histogram data
4127                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4128                         $have_ppr || continue
4129
4130                         # we only want the percent stat for < 16 pages
4131                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4132
4133                         percent=$((percent + WPCT))
4134                         if [[ $percent -gt 15 ]]; then
4135                                 error "less than 16-pages write RPCs" \
4136                                       "$percent% > 15%"
4137                                 break
4138                         fi
4139                 done
4140         rm -rf $TDIR
4141 }
4142 run_test 42e "verify sub-RPC writes are not done synchronously"
4143
4144 test_43A() { # was test_43
4145         test_mkdir $DIR/$tdir
4146         cp -p /bin/ls $DIR/$tdir/$tfile
4147         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4148         pid=$!
4149         # give multiop a chance to open
4150         sleep 1
4151
4152         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4153         kill -USR1 $pid
4154 }
4155 run_test 43A "execution of file opened for write should return -ETXTBSY"
4156
4157 test_43a() {
4158         test_mkdir $DIR/$tdir
4159         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4160                 cp -p multiop $DIR/$tdir/multiop
4161         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4162                 error "multiop open $TMP/$tfile.junk failed"
4163         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4164         MULTIOP_PID=$!
4165         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4166         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4167         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4168 }
4169 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4170
4171 test_43b() {
4172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4173
4174         test_mkdir $DIR/$tdir
4175         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4176                 cp -p multiop $DIR/$tdir/multiop
4177         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4178                 error "multiop open $TMP/$tfile.junk failed"
4179         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4180         MULTIOP_PID=$!
4181         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4182         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4183         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4184 }
4185 run_test 43b "truncate of file being executed should return -ETXTBSY"
4186
4187 test_43c() {
4188         local testdir="$DIR/$tdir"
4189         test_mkdir $testdir
4190         cp $SHELL $testdir/
4191         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4192                 ( cd $testdir && md5sum -c )
4193 }
4194 run_test 43c "md5sum of copy into lustre"
4195
4196 test_44A() { # was test_44
4197         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4198
4199         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4200         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4201 }
4202 run_test 44A "zero length read from a sparse stripe"
4203
4204 test_44a() {
4205         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4206                 awk '{ print $2 }')
4207         [ -z "$nstripe" ] && skip "can't get stripe info"
4208         [[ $nstripe -gt $OSTCOUNT ]] &&
4209                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4210
4211         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4212                 awk '{ print $2 }')
4213         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4214                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4215                         awk '{ print $2 }')
4216         fi
4217
4218         OFFSETS="0 $((stride/2)) $((stride-1))"
4219         for offset in $OFFSETS; do
4220                 for i in $(seq 0 $((nstripe-1))); do
4221                         local GLOBALOFFSETS=""
4222                         # size in Bytes
4223                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4224                         local myfn=$DIR/d44a-$size
4225                         echo "--------writing $myfn at $size"
4226                         ll_sparseness_write $myfn $size ||
4227                                 error "ll_sparseness_write"
4228                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4229                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4230                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4231
4232                         for j in $(seq 0 $((nstripe-1))); do
4233                                 # size in Bytes
4234                                 size=$((((j + $nstripe )*$stride + $offset)))
4235                                 ll_sparseness_write $myfn $size ||
4236                                         error "ll_sparseness_write"
4237                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4238                         done
4239                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4240                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4241                         rm -f $myfn
4242                 done
4243         done
4244 }
4245 run_test 44a "test sparse pwrite ==============================="
4246
4247 dirty_osc_total() {
4248         tot=0
4249         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4250                 tot=$(($tot + $d))
4251         done
4252         echo $tot
4253 }
4254 do_dirty_record() {
4255         before=`dirty_osc_total`
4256         echo executing "\"$*\""
4257         eval $*
4258         after=`dirty_osc_total`
4259         echo before $before, after $after
4260 }
4261 test_45() {
4262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4263
4264         f="$DIR/f45"
4265         # Obtain grants from OST if it supports it
4266         echo blah > ${f}_grant
4267         stop_writeback
4268         sync
4269         do_dirty_record "echo blah > $f"
4270         [[ $before -eq $after ]] && error "write wasn't cached"
4271         do_dirty_record "> $f"
4272         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4273         do_dirty_record "echo blah > $f"
4274         [[ $before -eq $after ]] && error "write wasn't cached"
4275         do_dirty_record "sync"
4276         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4277         do_dirty_record "echo blah > $f"
4278         [[ $before -eq $after ]] && error "write wasn't cached"
4279         do_dirty_record "cancel_lru_locks osc"
4280         [[ $before -gt $after ]] ||
4281                 error "lock cancellation didn't lower dirty count"
4282         start_writeback
4283 }
4284 run_test 45 "osc io page accounting ============================"
4285
4286 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4287 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4288 # objects offset and an assert hit when an rpc was built with 1023's mapped
4289 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4290 test_46() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         f="$DIR/f46"
4294         stop_writeback
4295         sync
4296         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4297         sync
4298         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4299         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4300         sync
4301         start_writeback
4302 }
4303 run_test 46 "dirtying a previously written page ================"
4304
4305 # test_47 is removed "Device nodes check" is moved to test_28
4306
4307 test_48a() { # bug 2399
4308         [ "$mds1_FSTYPE" = "zfs" ] &&
4309         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4310                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4311
4312         test_mkdir $DIR/$tdir
4313         cd $DIR/$tdir
4314         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4315         test_mkdir $DIR/$tdir
4316         touch foo || error "'touch foo' failed after recreating cwd"
4317         test_mkdir bar
4318         touch .foo || error "'touch .foo' failed after recreating cwd"
4319         test_mkdir .bar
4320         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4321         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4322         cd . || error "'cd .' failed after recreating cwd"
4323         mkdir . && error "'mkdir .' worked after recreating cwd"
4324         rmdir . && error "'rmdir .' worked after recreating cwd"
4325         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4326         cd .. || error "'cd ..' failed after recreating cwd"
4327 }
4328 run_test 48a "Access renamed working dir (should return errors)="
4329
4330 test_48b() { # bug 2399
4331         rm -rf $DIR/$tdir
4332         test_mkdir $DIR/$tdir
4333         cd $DIR/$tdir
4334         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4335         touch foo && error "'touch foo' worked after removing cwd"
4336         mkdir foo && error "'mkdir foo' worked after removing cwd"
4337         touch .foo && error "'touch .foo' worked after removing cwd"
4338         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4339         ls . > /dev/null && error "'ls .' worked after removing cwd"
4340         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4341         mkdir . && error "'mkdir .' worked after removing cwd"
4342         rmdir . && error "'rmdir .' worked after removing cwd"
4343         ln -s . foo && error "'ln -s .' worked after removing cwd"
4344         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4345 }
4346 run_test 48b "Access removed working dir (should return errors)="
4347
4348 test_48c() { # bug 2350
4349         #lctl set_param debug=-1
4350         #set -vx
4351         rm -rf $DIR/$tdir
4352         test_mkdir -p $DIR/$tdir/dir
4353         cd $DIR/$tdir/dir
4354         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4355         $TRACE touch foo && error "touch foo worked after removing cwd"
4356         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4357         touch .foo && error "touch .foo worked after removing cwd"
4358         mkdir .foo && error "mkdir .foo worked after removing cwd"
4359         $TRACE ls . && error "'ls .' worked after removing cwd"
4360         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4361         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4362         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4363         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4364         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4365 }
4366 run_test 48c "Access removed working subdir (should return errors)"
4367
4368 test_48d() { # bug 2350
4369         #lctl set_param debug=-1
4370         #set -vx
4371         rm -rf $DIR/$tdir
4372         test_mkdir -p $DIR/$tdir/dir
4373         cd $DIR/$tdir/dir
4374         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4375         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4376         $TRACE touch foo && error "'touch foo' worked after removing parent"
4377         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4378         touch .foo && error "'touch .foo' worked after removing parent"
4379         mkdir .foo && error "mkdir .foo worked after removing parent"
4380         $TRACE ls . && error "'ls .' worked after removing parent"
4381         $TRACE ls .. && error "'ls ..' worked after removing parent"
4382         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4383         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4384         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4385         true
4386 }
4387 run_test 48d "Access removed parent subdir (should return errors)"
4388
4389 test_48e() { # bug 4134
4390         #lctl set_param debug=-1
4391         #set -vx
4392         rm -rf $DIR/$tdir
4393         test_mkdir -p $DIR/$tdir/dir
4394         cd $DIR/$tdir/dir
4395         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4396         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4397         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4398         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4399         # On a buggy kernel addition of "touch foo" after cd .. will
4400         # produce kernel oops in lookup_hash_it
4401         touch ../foo && error "'cd ..' worked after recreate parent"
4402         cd $DIR
4403         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4404 }
4405 run_test 48e "Access to recreated parent subdir (should return errors)"
4406
4407 test_49() { # LU-1030
4408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4409         remote_ost_nodsh && skip "remote OST with nodsh"
4410
4411         # get ost1 size - lustre-OST0000
4412         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4413                 awk '{ print $4 }')
4414         # write 800M at maximum
4415         [[ $ost1_size -lt 2 ]] && ost1_size=2
4416         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4417
4418         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4419         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4420         local dd_pid=$!
4421
4422         # change max_pages_per_rpc while writing the file
4423         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4424         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4425         # loop until dd process exits
4426         while ps ax -opid | grep -wq $dd_pid; do
4427                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4428                 sleep $((RANDOM % 5 + 1))
4429         done
4430         # restore original max_pages_per_rpc
4431         $LCTL set_param $osc1_mppc=$orig_mppc
4432         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4433 }
4434 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4435
4436 test_50() {
4437         # bug 1485
4438         test_mkdir $DIR/$tdir
4439         cd $DIR/$tdir
4440         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4441 }
4442 run_test 50 "special situations: /proc symlinks  ==============="
4443
4444 test_51a() {    # was test_51
4445         # bug 1516 - create an empty entry right after ".." then split dir
4446         test_mkdir -c1 $DIR/$tdir
4447         touch $DIR/$tdir/foo
4448         $MCREATE $DIR/$tdir/bar
4449         rm $DIR/$tdir/foo
4450         createmany -m $DIR/$tdir/longfile 201
4451         FNUM=202
4452         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4453                 $MCREATE $DIR/$tdir/longfile$FNUM
4454                 FNUM=$(($FNUM + 1))
4455                 echo -n "+"
4456         done
4457         echo
4458         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4459 }
4460 run_test 51a "special situations: split htree with empty entry =="
4461
4462 cleanup_print_lfs_df () {
4463         trap 0
4464         $LFS df
4465         $LFS df -i
4466 }
4467
4468 test_51b() {
4469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4470
4471         local dir=$DIR/$tdir
4472         local nrdirs=$((65536 + 100))
4473
4474         # cleanup the directory
4475         rm -fr $dir
4476
4477         test_mkdir -c1 $dir
4478
4479         $LFS df
4480         $LFS df -i
4481         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4482         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4483         [[ $numfree -lt $nrdirs ]] &&
4484                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4485
4486         # need to check free space for the directories as well
4487         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4488         numfree=$(( blkfree / $(fs_inode_ksize) ))
4489         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4490
4491         trap cleanup_print_lfs_df EXIT
4492
4493         # create files
4494         createmany -d $dir/d $nrdirs || {
4495                 unlinkmany $dir/d $nrdirs
4496                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4497         }
4498
4499         # really created :
4500         nrdirs=$(ls -U $dir | wc -l)
4501
4502         # unlink all but 100 subdirectories, then check it still works
4503         local left=100
4504         local delete=$((nrdirs - left))
4505
4506         $LFS df
4507         $LFS df -i
4508
4509         # for ldiskfs the nlink count should be 1, but this is OSD specific
4510         # and so this is listed for informational purposes only
4511         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4512         unlinkmany -d $dir/d $delete ||
4513                 error "unlink of first $delete subdirs failed"
4514
4515         echo "nlink between: $(stat -c %h $dir)"
4516         local found=$(ls -U $dir | wc -l)
4517         [ $found -ne $left ] &&
4518                 error "can't find subdirs: found only $found, expected $left"
4519
4520         unlinkmany -d $dir/d $delete $left ||
4521                 error "unlink of second $left subdirs failed"
4522         # regardless of whether the backing filesystem tracks nlink accurately
4523         # or not, the nlink count shouldn't be more than "." and ".." here
4524         local after=$(stat -c %h $dir)
4525         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4526                 echo "nlink after: $after"
4527
4528         cleanup_print_lfs_df
4529 }
4530 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4531
4532 test_51d() {
4533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4534         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4535
4536         test_mkdir $DIR/$tdir
4537         createmany -o $DIR/$tdir/t- 1000
4538         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4539         for N in $(seq 0 $((OSTCOUNT - 1))); do
4540                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4541                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4542                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4543                         '($1 == '$N') { objs += 1 } \
4544                         END { printf("%0.0f", objs) }')
4545                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4546         done
4547         unlinkmany $DIR/$tdir/t- 1000
4548
4549         NLAST=0
4550         for N in $(seq 1 $((OSTCOUNT - 1))); do
4551                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4552                         error "OST $N has less objects vs OST $NLAST" \
4553                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4554                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4555                         error "OST $N has less objects vs OST $NLAST" \
4556                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4557
4558                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4559                         error "OST $N has less #0 objects vs OST $NLAST" \
4560                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4561                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4562                         error "OST $N has less #0 objects vs OST $NLAST" \
4563                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4564                 NLAST=$N
4565         done
4566         rm -f $TMP/$tfile
4567 }
4568 run_test 51d "check object distribution"
4569
4570 test_51e() {
4571         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4572                 skip_env "ldiskfs only test"
4573         fi
4574
4575         test_mkdir -c1 $DIR/$tdir
4576         test_mkdir -c1 $DIR/$tdir/d0
4577
4578         touch $DIR/$tdir/d0/foo
4579         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4580                 error "file exceed 65000 nlink limit!"
4581         unlinkmany $DIR/$tdir/d0/f- 65001
4582         return 0
4583 }
4584 run_test 51e "check file nlink limit"
4585
4586 test_51f() {
4587         test_mkdir $DIR/$tdir
4588
4589         local max=100000
4590         local ulimit_old=$(ulimit -n)
4591         local spare=20 # number of spare fd's for scripts/libraries, etc.
4592         local mdt=$($LFS getstripe -m $DIR/$tdir)
4593         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4594
4595         echo "MDT$mdt numfree=$numfree, max=$max"
4596         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4597         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4598                 while ! ulimit -n $((numfree + spare)); do
4599                         numfree=$((numfree * 3 / 4))
4600                 done
4601                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4602         else
4603                 echo "left ulimit at $ulimit_old"
4604         fi
4605
4606         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4607                 unlinkmany $DIR/$tdir/f $numfree
4608                 error "create+open $numfree files in $DIR/$tdir failed"
4609         }
4610         ulimit -n $ulimit_old
4611
4612         # if createmany exits at 120s there will be fewer than $numfree files
4613         unlinkmany $DIR/$tdir/f $numfree || true
4614 }
4615 run_test 51f "check many open files limit"
4616
4617 test_52a() {
4618         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4619         test_mkdir $DIR/$tdir
4620         touch $DIR/$tdir/foo
4621         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4622         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4623         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4624         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4625         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4626                                         error "link worked"
4627         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4628         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4629         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4630                                                      error "lsattr"
4631         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4632         cp -r $DIR/$tdir $TMP/
4633         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4634 }
4635 run_test 52a "append-only flag test (should return errors)"
4636
4637 test_52b() {
4638         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4639         test_mkdir $DIR/$tdir
4640         touch $DIR/$tdir/foo
4641         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4642         cat test > $DIR/$tdir/foo && error "cat test worked"
4643         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4644         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4645         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4646                                         error "link worked"
4647         echo foo >> $DIR/$tdir/foo && error "echo worked"
4648         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4649         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4650         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4651         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4652                                                         error "lsattr"
4653         chattr -i $DIR/$tdir/foo || error "chattr failed"
4654
4655         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4656 }
4657 run_test 52b "immutable flag test (should return errors) ======="
4658
4659 test_53() {
4660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4661         remote_mds_nodsh && skip "remote MDS with nodsh"
4662         remote_ost_nodsh && skip "remote OST with nodsh"
4663
4664         local param
4665         local param_seq
4666         local ostname
4667         local mds_last
4668         local mds_last_seq
4669         local ost_last
4670         local ost_last_seq
4671         local ost_last_id
4672         local ostnum
4673         local node
4674         local found=false
4675         local support_last_seq=true
4676
4677         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4678                 support_last_seq=false
4679
4680         # only test MDT0000
4681         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4682         local value
4683         for value in $(do_facet $SINGLEMDS \
4684                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4685                 param=$(echo ${value[0]} | cut -d "=" -f1)
4686                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4687
4688                 if $support_last_seq; then
4689                         param_seq=$(echo $param |
4690                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4691                         mds_last_seq=$(do_facet $SINGLEMDS \
4692                                        $LCTL get_param -n $param_seq)
4693                 fi
4694                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4695
4696                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4697                 node=$(facet_active_host ost$((ostnum+1)))
4698                 param="obdfilter.$ostname.last_id"
4699                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4700                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4701                         ost_last_id=$ost_last
4702
4703                         if $support_last_seq; then
4704                                 ost_last_id=$(echo $ost_last |
4705                                               awk -F':' '{print $2}' |
4706                                               sed -e "s/^0x//g")
4707                                 ost_last_seq=$(echo $ost_last |
4708                                                awk -F':' '{print $1}')
4709                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4710                         fi
4711
4712                         if [[ $ost_last_id != $mds_last ]]; then
4713                                 error "$ost_last_id != $mds_last"
4714                         else
4715                                 found=true
4716                                 break
4717                         fi
4718                 done
4719         done
4720         $found || error "can not match last_seq/last_id for $mdtosc"
4721         return 0
4722 }
4723 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4724
4725 test_54a() {
4726         perl -MSocket -e ';' || skip "no Socket perl module installed"
4727
4728         $SOCKETSERVER $DIR/socket ||
4729                 error "$SOCKETSERVER $DIR/socket failed: $?"
4730         $SOCKETCLIENT $DIR/socket ||
4731                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4732         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4733 }
4734 run_test 54a "unix domain socket test =========================="
4735
4736 test_54b() {
4737         f="$DIR/f54b"
4738         mknod $f c 1 3
4739         chmod 0666 $f
4740         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4741 }
4742 run_test 54b "char device works in lustre ======================"
4743
4744 find_loop_dev() {
4745         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4746         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4747         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4748
4749         for i in $(seq 3 7); do
4750                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4751                 LOOPDEV=$LOOPBASE$i
4752                 LOOPNUM=$i
4753                 break
4754         done
4755 }
4756
4757 cleanup_54c() {
4758         local rc=0
4759         loopdev="$DIR/loop54c"
4760
4761         trap 0
4762         $UMOUNT $DIR/$tdir || rc=$?
4763         losetup -d $loopdev || true
4764         losetup -d $LOOPDEV || true
4765         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4766         return $rc
4767 }
4768
4769 test_54c() {
4770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4771
4772         loopdev="$DIR/loop54c"
4773
4774         find_loop_dev
4775         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4776         trap cleanup_54c EXIT
4777         mknod $loopdev b 7 $LOOPNUM
4778         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4779         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4780         losetup $loopdev $DIR/$tfile ||
4781                 error "can't set up $loopdev for $DIR/$tfile"
4782         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4783         test_mkdir $DIR/$tdir
4784         mount -t ext2 $loopdev $DIR/$tdir ||
4785                 error "error mounting $loopdev on $DIR/$tdir"
4786         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4787                 error "dd write"
4788         df $DIR/$tdir
4789         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4790                 error "dd read"
4791         cleanup_54c
4792 }
4793 run_test 54c "block device works in lustre ====================="
4794
4795 test_54d() {
4796         f="$DIR/f54d"
4797         string="aaaaaa"
4798         mknod $f p
4799         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4800 }
4801 run_test 54d "fifo device works in lustre ======================"
4802
4803 test_54e() {
4804         f="$DIR/f54e"
4805         string="aaaaaa"
4806         cp -aL /dev/console $f
4807         echo $string > $f || error "echo $string to $f failed"
4808 }
4809 run_test 54e "console/tty device works in lustre ======================"
4810
4811 test_56a() {
4812         local numfiles=3
4813         local dir=$DIR/$tdir
4814
4815         rm -rf $dir
4816         test_mkdir -p $dir/dir
4817         for i in $(seq $numfiles); do
4818                 touch $dir/file$i
4819                 touch $dir/dir/file$i
4820         done
4821
4822         local numcomp=$($LFS getstripe --component-count $dir)
4823
4824         [[ $numcomp == 0 ]] && numcomp=1
4825
4826         # test lfs getstripe with --recursive
4827         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4828
4829         [[ $filenum -eq $((numfiles * 2)) ]] ||
4830                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4831         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4832         [[ $filenum -eq $numfiles ]] ||
4833                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4834         echo "$LFS getstripe showed obdidx or l_ost_idx"
4835
4836         # test lfs getstripe with file instead of dir
4837         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4838         [[ $filenum -eq 1 ]] ||
4839                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4840         echo "$LFS getstripe file1 passed"
4841
4842         #test lfs getstripe with --verbose
4843         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4844         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4845                 error "$LFS getstripe --verbose $dir: "\
4846                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4847         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4848                 error "$LFS getstripe $dir: showed lmm_magic"
4849
4850         #test lfs getstripe with -v prints lmm_fid
4851         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4852         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4853                 error "$LFS getstripe -v $dir: "\
4854                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4855         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4856                 error "$LFS getstripe $dir: showed lmm_fid by default"
4857         echo "$LFS getstripe --verbose passed"
4858
4859         #check for FID information
4860         local fid1=$($LFS getstripe --fid $dir/file1)
4861         local fid2=$($LFS getstripe --verbose $dir/file1 |
4862                      awk '/lmm_fid: / { print $2; exit; }')
4863         local fid3=$($LFS path2fid $dir/file1)
4864
4865         [ "$fid1" != "$fid2" ] &&
4866                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4867         [ "$fid1" != "$fid3" ] &&
4868                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4869         echo "$LFS getstripe --fid passed"
4870
4871         #test lfs getstripe with --obd
4872         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4873                 error "$LFS getstripe --obd wrong_uuid: should return error"
4874
4875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4876
4877         local ostidx=1
4878         local obduuid=$(ostuuid_from_index $ostidx)
4879         local found=$($LFS getstripe -r --obd $obduuid $dir |
4880                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4881
4882         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4883         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4884                 ((filenum--))
4885         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4886                 ((filenum--))
4887
4888         [[ $found -eq $filenum ]] ||
4889                 error "$LFS getstripe --obd: found $found expect $filenum"
4890         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4891                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4892                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4893                 error "$LFS getstripe --obd: should not show file on other obd"
4894         echo "$LFS getstripe --obd passed"
4895 }
4896 run_test 56a "check $LFS getstripe"
4897
4898 test_56b() {
4899         local dir=$DIR/$tdir
4900         local numdirs=3
4901
4902         test_mkdir $dir
4903         for i in $(seq $numdirs); do
4904                 test_mkdir $dir/dir$i
4905         done
4906
4907         # test lfs getdirstripe default mode is non-recursion, which is
4908         # different from lfs getstripe
4909         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4910
4911         [[ $dircnt -eq 1 ]] ||
4912                 error "$LFS getdirstripe: found $dircnt, not 1"
4913         dircnt=$($LFS getdirstripe --recursive $dir |
4914                 grep -c lmv_stripe_count)
4915         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4916                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4917 }
4918 run_test 56b "check $LFS getdirstripe"
4919
4920 test_56c() {
4921         remote_ost_nodsh && skip "remote OST with nodsh"
4922
4923         local ost_idx=0
4924         local ost_name=$(ostname_from_index $ost_idx)
4925         local old_status=$(ost_dev_status $ost_idx)
4926
4927         [[ -z "$old_status" ]] ||
4928                 skip_env "OST $ost_name is in $old_status status"
4929
4930         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4931         sleep_maxage
4932
4933         local new_status=$(ost_dev_status $ost_idx)
4934
4935         [[ "$new_status" = "D" ]] ||
4936                 error "OST $ost_name is in status of '$new_status', not 'D'"
4937
4938         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4939         sleep_maxage
4940
4941         new_status=$(ost_dev_status $ost_idx)
4942         [[ -z "$new_status" ]] ||
4943                 error "OST $ost_name is in status of '$new_status', not ''"
4944 }
4945 run_test 56c "check 'lfs df' showing device status"
4946
4947 NUMFILES=3
4948 NUMDIRS=3
4949 setup_56() {
4950         local local_tdir="$1"
4951         local local_numfiles="$2"
4952         local local_numdirs="$3"
4953         local dir_params="$4"
4954         local dir_stripe_params="$5"
4955
4956         if [ ! -d "$local_tdir" ] ; then
4957                 test_mkdir -p $dir_stripe_params $local_tdir
4958                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4959                 for i in $(seq $local_numfiles) ; do
4960                         touch $local_tdir/file$i
4961                 done
4962                 for i in $(seq $local_numdirs) ; do
4963                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4964                         for j in $(seq $local_numfiles) ; do
4965                                 touch $local_tdir/dir$i/file$j
4966                         done
4967                 done
4968         fi
4969 }
4970
4971 setup_56_special() {
4972         local local_tdir=$1
4973         local local_numfiles=$2
4974         local local_numdirs=$3
4975
4976         setup_56 $local_tdir $local_numfiles $local_numdirs
4977
4978         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4979                 for i in $(seq $local_numfiles) ; do
4980                         mknod $local_tdir/loop${i}b b 7 $i
4981                         mknod $local_tdir/null${i}c c 1 3
4982                         ln -s $local_tdir/file1 $local_tdir/link${i}
4983                 done
4984                 for i in $(seq $local_numdirs) ; do
4985                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4986                         mknod $local_tdir/dir$i/null${i}c c 1 3
4987                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4988                 done
4989         fi
4990 }
4991
4992 test_56g() {
4993         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4994         local expected=$(($NUMDIRS + 2))
4995
4996         setup_56 $dir $NUMFILES $NUMDIRS
4997
4998         # test lfs find with -name
4999         for i in $(seq $NUMFILES) ; do
5000                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5001
5002                 [ $nums -eq $expected ] ||
5003                         error "lfs find -name '*$i' $dir wrong: "\
5004                               "found $nums, expected $expected"
5005         done
5006 }
5007 run_test 56g "check lfs find -name"
5008
5009 test_56h() {
5010         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5011         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5012
5013         setup_56 $dir $NUMFILES $NUMDIRS
5014
5015         # test lfs find with ! -name
5016         for i in $(seq $NUMFILES) ; do
5017                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5018
5019                 [ $nums -eq $expected ] ||
5020                         error "lfs find ! -name '*$i' $dir wrong: "\
5021                               "found $nums, expected $expected"
5022         done
5023 }
5024 run_test 56h "check lfs find ! -name"
5025
5026 test_56i() {
5027         local dir=$DIR/$tdir
5028
5029         test_mkdir $dir
5030
5031         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5032         local out=$($cmd)
5033
5034         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5035 }
5036 run_test 56i "check 'lfs find -ost UUID' skips directories"
5037
5038 test_56j() {
5039         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5040
5041         setup_56_special $dir $NUMFILES $NUMDIRS
5042
5043         local expected=$((NUMDIRS + 1))
5044         local cmd="$LFS find -type d $dir"
5045         local nums=$($cmd | wc -l)
5046
5047         [ $nums -eq $expected ] ||
5048                 error "'$cmd' wrong: found $nums, expected $expected"
5049 }
5050 run_test 56j "check lfs find -type d"
5051
5052 test_56k() {
5053         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5054
5055         setup_56_special $dir $NUMFILES $NUMDIRS
5056
5057         local expected=$(((NUMDIRS + 1) * NUMFILES))
5058         local cmd="$LFS find -type f $dir"
5059         local nums=$($cmd | wc -l)
5060
5061         [ $nums -eq $expected ] ||
5062                 error "'$cmd' wrong: found $nums, expected $expected"
5063 }
5064 run_test 56k "check lfs find -type f"
5065
5066 test_56l() {
5067         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5068
5069         setup_56_special $dir $NUMFILES $NUMDIRS
5070
5071         local expected=$((NUMDIRS + NUMFILES))
5072         local cmd="$LFS find -type b $dir"
5073         local nums=$($cmd | wc -l)
5074
5075         [ $nums -eq $expected ] ||
5076                 error "'$cmd' wrong: found $nums, expected $expected"
5077 }
5078 run_test 56l "check lfs find -type b"
5079
5080 test_56m() {
5081         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5082
5083         setup_56_special $dir $NUMFILES $NUMDIRS
5084
5085         local expected=$((NUMDIRS + NUMFILES))
5086         local cmd="$LFS find -type c $dir"
5087         local nums=$($cmd | wc -l)
5088         [ $nums -eq $expected ] ||
5089                 error "'$cmd' wrong: found $nums, expected $expected"
5090 }
5091 run_test 56m "check lfs find -type c"
5092
5093 test_56n() {
5094         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5095         setup_56_special $dir $NUMFILES $NUMDIRS
5096
5097         local expected=$((NUMDIRS + NUMFILES))
5098         local cmd="$LFS find -type l $dir"
5099         local nums=$($cmd | wc -l)
5100
5101         [ $nums -eq $expected ] ||
5102                 error "'$cmd' wrong: found $nums, expected $expected"
5103 }
5104 run_test 56n "check lfs find -type l"
5105
5106 test_56o() {
5107         local dir=$DIR/$tdir
5108
5109         setup_56 $dir $NUMFILES $NUMDIRS
5110         utime $dir/file1 > /dev/null || error "utime (1)"
5111         utime $dir/file2 > /dev/null || error "utime (2)"
5112         utime $dir/dir1 > /dev/null || error "utime (3)"
5113         utime $dir/dir2 > /dev/null || error "utime (4)"
5114         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5115         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5116
5117         local expected=4
5118         local nums=$($LFS find -mtime +0 $dir | wc -l)
5119
5120         [ $nums -eq $expected ] ||
5121                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5122
5123         expected=12
5124         cmd="$LFS find -mtime 0 $dir"
5125         nums=$($cmd | wc -l)
5126         [ $nums -eq $expected ] ||
5127                 error "'$cmd' wrong: found $nums, expected $expected"
5128 }
5129 run_test 56o "check lfs find -mtime for old files"
5130
5131 test_56ob() {
5132         local dir=$DIR/$tdir
5133         local expected=1
5134         local count=0
5135
5136         # just to make sure there is something that won't be found
5137         test_mkdir $dir
5138         touch $dir/$tfile.now
5139
5140         for age in year week day hour min; do
5141                 count=$((count + 1))
5142
5143                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5144                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5145                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5146
5147                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5148                 local nums=$($cmd | wc -l)
5149                 [ $nums -eq $expected ] ||
5150                         error "'$cmd' wrong: found $nums, expected $expected"
5151
5152                 cmd="$LFS find $dir -atime $count${age:0:1}"
5153                 nums=$($cmd | wc -l)
5154                 [ $nums -eq $expected ] ||
5155                         error "'$cmd' wrong: found $nums, expected $expected"
5156         done
5157
5158         sleep 2
5159         cmd="$LFS find $dir -ctime +1s -type f"
5160         nums=$($cmd | wc -l)
5161         (( $nums == $count * 2 + 1)) ||
5162                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5163 }
5164 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5165
5166 test_56p() {
5167         [ $RUNAS_ID -eq $UID ] &&
5168                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5169
5170         local dir=$DIR/$tdir
5171
5172         setup_56 $dir $NUMFILES $NUMDIRS
5173         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5174
5175         local expected=$NUMFILES
5176         local cmd="$LFS find -uid $RUNAS_ID $dir"
5177         local nums=$($cmd | wc -l)
5178
5179         [ $nums -eq $expected ] ||
5180                 error "'$cmd' wrong: found $nums, expected $expected"
5181
5182         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5183         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5184         nums=$($cmd | wc -l)
5185         [ $nums -eq $expected ] ||
5186                 error "'$cmd' wrong: found $nums, expected $expected"
5187 }
5188 run_test 56p "check lfs find -uid and ! -uid"
5189
5190 test_56q() {
5191         [ $RUNAS_ID -eq $UID ] &&
5192                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5193
5194         local dir=$DIR/$tdir
5195
5196         setup_56 $dir $NUMFILES $NUMDIRS
5197         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5198
5199         local expected=$NUMFILES
5200         local cmd="$LFS find -gid $RUNAS_GID $dir"
5201         local nums=$($cmd | wc -l)
5202
5203         [ $nums -eq $expected ] ||
5204                 error "'$cmd' wrong: found $nums, expected $expected"
5205
5206         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5207         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5208         nums=$($cmd | wc -l)
5209         [ $nums -eq $expected ] ||
5210                 error "'$cmd' wrong: found $nums, expected $expected"
5211 }
5212 run_test 56q "check lfs find -gid and ! -gid"
5213
5214 test_56r() {
5215         local dir=$DIR/$tdir
5216
5217         setup_56 $dir $NUMFILES $NUMDIRS
5218
5219         local expected=12
5220         local cmd="$LFS find -size 0 -type f $dir"
5221         local nums=$($cmd | wc -l)
5222
5223         [ $nums -eq $expected ] ||
5224                 error "'$cmd' wrong: found $nums, expected $expected"
5225         expected=0
5226         cmd="$LFS find ! -size 0 -type f $dir"
5227         nums=$($cmd | wc -l)
5228         [ $nums -eq $expected ] ||
5229                 error "'$cmd' wrong: found $nums, expected $expected"
5230         echo "test" > $dir/$tfile
5231         echo "test2" > $dir/$tfile.2 && sync
5232         expected=1
5233         cmd="$LFS find -size 5 -type f $dir"
5234         nums=$($cmd | wc -l)
5235         [ $nums -eq $expected ] ||
5236                 error "'$cmd' wrong: found $nums, expected $expected"
5237         expected=1
5238         cmd="$LFS find -size +5 -type f $dir"
5239         nums=$($cmd | wc -l)
5240         [ $nums -eq $expected ] ||
5241                 error "'$cmd' wrong: found $nums, expected $expected"
5242         expected=2
5243         cmd="$LFS find -size +0 -type f $dir"
5244         nums=$($cmd | wc -l)
5245         [ $nums -eq $expected ] ||
5246                 error "'$cmd' wrong: found $nums, expected $expected"
5247         expected=2
5248         cmd="$LFS find ! -size -5 -type f $dir"
5249         nums=$($cmd | wc -l)
5250         [ $nums -eq $expected ] ||
5251                 error "'$cmd' wrong: found $nums, expected $expected"
5252         expected=12
5253         cmd="$LFS find -size -5 -type f $dir"
5254         nums=$($cmd | wc -l)
5255         [ $nums -eq $expected ] ||
5256                 error "'$cmd' wrong: found $nums, expected $expected"
5257 }
5258 run_test 56r "check lfs find -size works"
5259
5260 test_56s() { # LU-611 #LU-9369
5261         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5262
5263         local dir=$DIR/$tdir
5264         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5265
5266         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5267         for i in $(seq $NUMDIRS); do
5268                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5269         done
5270
5271         local expected=$NUMDIRS
5272         local cmd="$LFS find -c $OSTCOUNT $dir"
5273         local nums=$($cmd | wc -l)
5274
5275         [ $nums -eq $expected ] || {
5276                 $LFS getstripe -R $dir
5277                 error "'$cmd' wrong: found $nums, expected $expected"
5278         }
5279
5280         expected=$((NUMDIRS + onestripe))
5281         cmd="$LFS find -stripe-count +0 -type f $dir"
5282         nums=$($cmd | wc -l)
5283         [ $nums -eq $expected ] || {
5284                 $LFS getstripe -R $dir
5285                 error "'$cmd' wrong: found $nums, expected $expected"
5286         }
5287
5288         expected=$onestripe
5289         cmd="$LFS find -stripe-count 1 -type f $dir"
5290         nums=$($cmd | wc -l)
5291         [ $nums -eq $expected ] || {
5292                 $LFS getstripe -R $dir
5293                 error "'$cmd' wrong: found $nums, expected $expected"
5294         }
5295
5296         cmd="$LFS find -stripe-count -2 -type f $dir"
5297         nums=$($cmd | wc -l)
5298         [ $nums -eq $expected ] || {
5299                 $LFS getstripe -R $dir
5300                 error "'$cmd' wrong: found $nums, expected $expected"
5301         }
5302
5303         expected=0
5304         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5305         nums=$($cmd | wc -l)
5306         [ $nums -eq $expected ] || {
5307                 $LFS getstripe -R $dir
5308                 error "'$cmd' wrong: found $nums, expected $expected"
5309         }
5310 }
5311 run_test 56s "check lfs find -stripe-count works"
5312
5313 test_56t() { # LU-611 #LU-9369
5314         local dir=$DIR/$tdir
5315
5316         setup_56 $dir 0 $NUMDIRS
5317         for i in $(seq $NUMDIRS); do
5318                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5319         done
5320
5321         local expected=$NUMDIRS
5322         local cmd="$LFS find -S 8M $dir"
5323         local nums=$($cmd | wc -l)
5324
5325         [ $nums -eq $expected ] || {
5326                 $LFS getstripe -R $dir
5327                 error "'$cmd' wrong: found $nums, expected $expected"
5328         }
5329         rm -rf $dir
5330
5331         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5332
5333         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5334
5335         expected=$(((NUMDIRS + 1) * NUMFILES))
5336         cmd="$LFS find -stripe-size 512k -type f $dir"
5337         nums=$($cmd | wc -l)
5338         [ $nums -eq $expected ] ||
5339                 error "'$cmd' wrong: found $nums, expected $expected"
5340
5341         cmd="$LFS find -stripe-size +320k -type f $dir"
5342         nums=$($cmd | wc -l)
5343         [ $nums -eq $expected ] ||
5344                 error "'$cmd' wrong: found $nums, expected $expected"
5345
5346         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5347         cmd="$LFS find -stripe-size +200k -type f $dir"
5348         nums=$($cmd | wc -l)
5349         [ $nums -eq $expected ] ||
5350                 error "'$cmd' wrong: found $nums, expected $expected"
5351
5352         cmd="$LFS find -stripe-size -640k -type f $dir"
5353         nums=$($cmd | wc -l)
5354         [ $nums -eq $expected ] ||
5355                 error "'$cmd' wrong: found $nums, expected $expected"
5356
5357         expected=4
5358         cmd="$LFS find -stripe-size 256k -type f $dir"
5359         nums=$($cmd | wc -l)
5360         [ $nums -eq $expected ] ||
5361                 error "'$cmd' wrong: found $nums, expected $expected"
5362
5363         cmd="$LFS find -stripe-size -320k -type f $dir"
5364         nums=$($cmd | wc -l)
5365         [ $nums -eq $expected ] ||
5366                 error "'$cmd' wrong: found $nums, expected $expected"
5367
5368         expected=0
5369         cmd="$LFS find -stripe-size 1024k -type f $dir"
5370         nums=$($cmd | wc -l)
5371         [ $nums -eq $expected ] ||
5372                 error "'$cmd' wrong: found $nums, expected $expected"
5373 }
5374 run_test 56t "check lfs find -stripe-size works"
5375
5376 test_56u() { # LU-611
5377         local dir=$DIR/$tdir
5378
5379         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5380
5381         if [[ $OSTCOUNT -gt 1 ]]; then
5382                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5383                 onestripe=4
5384         else
5385                 onestripe=0
5386         fi
5387
5388         local expected=$(((NUMDIRS + 1) * NUMFILES))
5389         local cmd="$LFS find -stripe-index 0 -type f $dir"
5390         local nums=$($cmd | wc -l)
5391
5392         [ $nums -eq $expected ] ||
5393                 error "'$cmd' wrong: found $nums, expected $expected"
5394
5395         expected=$onestripe
5396         cmd="$LFS find -stripe-index 1 -type f $dir"
5397         nums=$($cmd | wc -l)
5398         [ $nums -eq $expected ] ||
5399                 error "'$cmd' wrong: found $nums, expected $expected"
5400
5401         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5402         nums=$($cmd | wc -l)
5403         [ $nums -eq $expected ] ||
5404                 error "'$cmd' wrong: found $nums, expected $expected"
5405
5406         expected=0
5407         # This should produce an error and not return any files
5408         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5409         nums=$($cmd 2>/dev/null | wc -l)
5410         [ $nums -eq $expected ] ||
5411                 error "'$cmd' wrong: found $nums, expected $expected"
5412
5413         if [[ $OSTCOUNT -gt 1 ]]; then
5414                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5415                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5416                 nums=$($cmd | wc -l)
5417                 [ $nums -eq $expected ] ||
5418                         error "'$cmd' wrong: found $nums, expected $expected"
5419         fi
5420 }
5421 run_test 56u "check lfs find -stripe-index works"
5422
5423 test_56v() {
5424         local mdt_idx=0
5425         local dir=$DIR/$tdir
5426
5427         setup_56 $dir $NUMFILES $NUMDIRS
5428
5429         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5430         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5431
5432         for file in $($LFS find -m $UUID $dir); do
5433                 file_midx=$($LFS getstripe -m $file)
5434                 [ $file_midx -eq $mdt_idx ] ||
5435                         error "lfs find -m $UUID != getstripe -m $file_midx"
5436         done
5437 }
5438 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5439
5440 test_56w() {
5441         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443
5444         local dir=$DIR/$tdir
5445
5446         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5447
5448         local stripe_size=$($LFS getstripe -S -d $dir) ||
5449                 error "$LFS getstripe -S -d $dir failed"
5450         stripe_size=${stripe_size%% *}
5451
5452         local file_size=$((stripe_size * OSTCOUNT))
5453         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5454         local required_space=$((file_num * file_size))
5455         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5456                            head -n1)
5457         [[ $free_space -le $((required_space / 1024)) ]] &&
5458                 skip_env "need $required_space, have $free_space kbytes"
5459
5460         local dd_bs=65536
5461         local dd_count=$((file_size / dd_bs))
5462
5463         # write data into the files
5464         local i
5465         local j
5466         local file
5467
5468         for i in $(seq $NUMFILES); do
5469                 file=$dir/file$i
5470                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5471                         error "write data into $file failed"
5472         done
5473         for i in $(seq $NUMDIRS); do
5474                 for j in $(seq $NUMFILES); do
5475                         file=$dir/dir$i/file$j
5476                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5477                                 error "write data into $file failed"
5478                 done
5479         done
5480
5481         # $LFS_MIGRATE will fail if hard link migration is unsupported
5482         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5483                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5484                         error "creating links to $dir/dir1/file1 failed"
5485         fi
5486
5487         local expected=-1
5488
5489         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5490
5491         # lfs_migrate file
5492         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5493
5494         echo "$cmd"
5495         eval $cmd || error "$cmd failed"
5496
5497         check_stripe_count $dir/file1 $expected
5498
5499         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5500         then
5501                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5502                 # OST 1 if it is on OST 0. This file is small enough to
5503                 # be on only one stripe.
5504                 file=$dir/migr_1_ost
5505                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5506                         error "write data into $file failed"
5507                 local obdidx=$($LFS getstripe -i $file)
5508                 local oldmd5=$(md5sum $file)
5509                 local newobdidx=0
5510
5511                 [[ $obdidx -eq 0 ]] && newobdidx=1
5512                 cmd="$LFS migrate -i $newobdidx $file"
5513                 echo $cmd
5514                 eval $cmd || error "$cmd failed"
5515
5516                 local realobdix=$($LFS getstripe -i $file)
5517                 local newmd5=$(md5sum $file)
5518
5519                 [[ $newobdidx -ne $realobdix ]] &&
5520                         error "new OST is different (was=$obdidx, "\
5521                               "wanted=$newobdidx, got=$realobdix)"
5522                 [[ "$oldmd5" != "$newmd5" ]] &&
5523                         error "md5sum differ: $oldmd5, $newmd5"
5524         fi
5525
5526         # lfs_migrate dir
5527         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5528         echo "$cmd"
5529         eval $cmd || error "$cmd failed"
5530
5531         for j in $(seq $NUMFILES); do
5532                 check_stripe_count $dir/dir1/file$j $expected
5533         done
5534
5535         # lfs_migrate works with lfs find
5536         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5537              $LFS_MIGRATE -y -c $expected"
5538         echo "$cmd"
5539         eval $cmd || error "$cmd failed"
5540
5541         for i in $(seq 2 $NUMFILES); do
5542                 check_stripe_count $dir/file$i $expected
5543         done
5544         for i in $(seq 2 $NUMDIRS); do
5545                 for j in $(seq $NUMFILES); do
5546                 check_stripe_count $dir/dir$i/file$j $expected
5547                 done
5548         done
5549 }
5550 run_test 56w "check lfs_migrate -c stripe_count works"
5551
5552 test_56wb() {
5553         local file1=$DIR/$tdir/file1
5554         local create_pool=false
5555         local initial_pool=$($LFS getstripe -p $DIR)
5556         local pool_list=()
5557         local pool=""
5558
5559         echo -n "Creating test dir..."
5560         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5561         echo "done."
5562
5563         echo -n "Creating test file..."
5564         touch $file1 || error "cannot create file"
5565         echo "done."
5566
5567         echo -n "Detecting existing pools..."
5568         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5569
5570         if [ ${#pool_list[@]} -gt 0 ]; then
5571                 echo "${pool_list[@]}"
5572                 for thispool in "${pool_list[@]}"; do
5573                         if [[ -z "$initial_pool" ||
5574                               "$initial_pool" != "$thispool" ]]; then
5575                                 pool="$thispool"
5576                                 echo "Using existing pool '$pool'"
5577                                 break
5578                         fi
5579                 done
5580         else
5581                 echo "none detected."
5582         fi
5583         if [ -z "$pool" ]; then
5584                 pool=${POOL:-testpool}
5585                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5586                 echo -n "Creating pool '$pool'..."
5587                 create_pool=true
5588                 pool_add $pool &> /dev/null ||
5589                         error "pool_add failed"
5590                 echo "done."
5591
5592                 echo -n "Adding target to pool..."
5593                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5594                         error "pool_add_targets failed"
5595                 echo "done."
5596         fi
5597
5598         echo -n "Setting pool using -p option..."
5599         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5600                 error "migrate failed rc = $?"
5601         echo "done."
5602
5603         echo -n "Verifying test file is in pool after migrating..."
5604         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5605                 error "file was not migrated to pool $pool"
5606         echo "done."
5607
5608         echo -n "Removing test file from pool '$pool'..."
5609         $LFS migrate $file1 &> /dev/null ||
5610                 error "cannot remove from pool"
5611         [ "$($LFS getstripe -p $file1)" ] &&
5612                 error "pool still set"
5613         echo "done."
5614
5615         echo -n "Setting pool using --pool option..."
5616         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5617                 error "migrate failed rc = $?"
5618         echo "done."
5619
5620         # Clean up
5621         rm -f $file1
5622         if $create_pool; then
5623                 destroy_test_pools 2> /dev/null ||
5624                         error "destroy test pools failed"
5625         fi
5626 }
5627 run_test 56wb "check lfs_migrate pool support"
5628
5629 test_56wc() {
5630         local file1="$DIR/$tdir/file1"
5631
5632         echo -n "Creating test dir..."
5633         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5634         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5635         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5636                 error "cannot set stripe"
5637         echo "done"
5638
5639         echo -n "Setting initial stripe for test file..."
5640         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5641                 error "cannot set stripe"
5642         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5643                 error "stripe size not set"
5644         echo "done."
5645
5646         # File currently set to -S 512K -c 1
5647
5648         # Ensure -c and -S options are rejected when -R is set
5649         echo -n "Verifying incompatible options are detected..."
5650         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5651                 error "incompatible -c and -R options not detected"
5652         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5653                 error "incompatible -S and -R options not detected"
5654         echo "done."
5655
5656         # Ensure unrecognized options are passed through to 'lfs migrate'
5657         echo -n "Verifying -S option is passed through to lfs migrate..."
5658         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5659                 error "migration failed"
5660         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5661                 error "file was not restriped"
5662         echo "done."
5663
5664         # File currently set to -S 1M -c 1
5665
5666         # Ensure long options are supported
5667         echo -n "Verifying long options supported..."
5668         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5669                 error "long option without argument not supported"
5670         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5671                 error "long option with argument not supported"
5672         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5673                 error "file not restriped with --stripe-size option"
5674         echo "done."
5675
5676         # File currently set to -S 512K -c 1
5677
5678         if [ "$OSTCOUNT" -gt 1 ]; then
5679                 echo -n "Verifying explicit stripe count can be set..."
5680                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5681                         error "migrate failed"
5682                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5683                         error "file not restriped to explicit count"
5684                 echo "done."
5685         fi
5686
5687         # File currently set to -S 512K -c 1 or -S 512K -c 2
5688
5689         # Ensure parent striping is used if -R is set, and no stripe
5690         # count or size is specified
5691         echo -n "Setting stripe for parent directory..."
5692         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5693                 error "cannot set stripe"
5694         echo "done."
5695
5696         echo -n "Verifying restripe option uses parent stripe settings..."
5697         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5698                 error "migrate failed"
5699         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5700                 error "file not restriped to parent settings"
5701         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5702                 error "file not restriped to parent settings"
5703         echo "done."
5704
5705         # File currently set to -S 1M -c 1
5706
5707         # Ensure striping is preserved if -R is not set, and no stripe
5708         # count or size is specified
5709         echo -n "Verifying striping size preserved when not specified..."
5710         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5711         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5712                 error "cannot set stripe on parent directory"
5713         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5714                 error "migrate failed"
5715         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5716                 error "file was restriped"
5717         echo "done."
5718
5719         # Ensure file name properly detected when final option has no argument
5720         echo -n "Verifying file name properly detected..."
5721         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5722                 error "file name interpreted as option argument"
5723         echo "done."
5724
5725         # Clean up
5726         rm -f "$file1"
5727 }
5728 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5729
5730 test_56wd() {
5731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5732
5733         local file1=$DIR/$tdir/file1
5734
5735         echo -n "Creating test dir..."
5736         test_mkdir $DIR/$tdir || error "cannot create dir"
5737         echo "done."
5738
5739         echo -n "Creating test file..."
5740         touch $file1
5741         echo "done."
5742
5743         # Ensure 'lfs migrate' will fail by using a non-existent option,
5744         # and make sure rsync is not called to recover
5745         echo -n "Make sure --no-rsync option works..."
5746         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5747                 grep -q 'refusing to fall back to rsync' ||
5748                 error "rsync was called with --no-rsync set"
5749         echo "done."
5750
5751         # Ensure rsync is called without trying 'lfs migrate' first
5752         echo -n "Make sure --rsync option works..."
5753         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5754                 grep -q 'falling back to rsync' &&
5755                 error "lfs migrate was called with --rsync set"
5756         echo "done."
5757
5758         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5759         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5760                 grep -q 'at the same time' ||
5761                 error "--rsync and --no-rsync accepted concurrently"
5762         echo "done."
5763
5764         # Clean up
5765         rm -f $file1
5766 }
5767 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5768
5769 test_56x() {
5770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5771         check_swap_layouts_support
5772
5773         local dir=$DIR/$tdir
5774         local ref1=/etc/passwd
5775         local file1=$dir/file1
5776
5777         test_mkdir $dir || error "creating dir $dir"
5778         $LFS setstripe -c 2 $file1
5779         cp $ref1 $file1
5780         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5781         stripe=$($LFS getstripe -c $file1)
5782         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5783         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5784
5785         # clean up
5786         rm -f $file1
5787 }
5788 run_test 56x "lfs migration support"
5789
5790 test_56xa() {
5791         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5792         check_swap_layouts_support
5793
5794         local dir=$DIR/$tdir/$testnum
5795
5796         test_mkdir -p $dir
5797
5798         local ref1=/etc/passwd
5799         local file1=$dir/file1
5800
5801         $LFS setstripe -c 2 $file1
5802         cp $ref1 $file1
5803         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5804
5805         local stripe=$($LFS getstripe -c $file1)
5806
5807         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5808         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5809
5810         # clean up
5811         rm -f $file1
5812 }
5813 run_test 56xa "lfs migration --block support"
5814
5815 check_migrate_links() {
5816         local dir="$1"
5817         local file1="$dir/file1"
5818         local begin="$2"
5819         local count="$3"
5820         local total_count=$(($begin + $count - 1))
5821         local symlink_count=10
5822         local uniq_count=10
5823
5824         if [ ! -f "$file1" ]; then
5825                 echo -n "creating initial file..."
5826                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5827                         error "cannot setstripe initial file"
5828                 echo "done"
5829
5830                 echo -n "creating symlinks..."
5831                 for s in $(seq 1 $symlink_count); do
5832                         ln -s "$file1" "$dir/slink$s" ||
5833                                 error "cannot create symlinks"
5834                 done
5835                 echo "done"
5836
5837                 echo -n "creating nonlinked files..."
5838                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5839                         error "cannot create nonlinked files"
5840                 echo "done"
5841         fi
5842
5843         # create hard links
5844         if [ ! -f "$dir/file$total_count" ]; then
5845                 echo -n "creating hard links $begin:$total_count..."
5846                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5847                         /dev/null || error "cannot create hard links"
5848                 echo "done"
5849         fi
5850
5851         echo -n "checking number of hard links listed in xattrs..."
5852         local fid=$($LFS getstripe -F "$file1")
5853         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5854
5855         echo "${#paths[*]}"
5856         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5857                         skip "hard link list has unexpected size, skipping test"
5858         fi
5859         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5860                         error "link names should exceed xattrs size"
5861         fi
5862
5863         echo -n "migrating files..."
5864         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5865         local rc=$?
5866         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5867         echo "done"
5868
5869         # make sure all links have been properly migrated
5870         echo -n "verifying files..."
5871         fid=$($LFS getstripe -F "$file1") ||
5872                 error "cannot get fid for file $file1"
5873         for i in $(seq 2 $total_count); do
5874                 local fid2=$($LFS getstripe -F $dir/file$i)
5875
5876                 [ "$fid2" == "$fid" ] ||
5877                         error "migrated hard link has mismatched FID"
5878         done
5879
5880         # make sure hard links were properly detected, and migration was
5881         # performed only once for the entire link set; nonlinked files should
5882         # also be migrated
5883         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5884         local expected=$(($uniq_count + 1))
5885
5886         [ "$actual" -eq  "$expected" ] ||
5887                 error "hard links individually migrated ($actual != $expected)"
5888
5889         # make sure the correct number of hard links are present
5890         local hardlinks=$(stat -c '%h' "$file1")
5891
5892         [ $hardlinks -eq $total_count ] ||
5893                 error "num hard links $hardlinks != $total_count"
5894         echo "done"
5895
5896         return 0
5897 }
5898
5899 test_56xb() {
5900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5901                 skip "Need MDS version at least 2.10.55"
5902
5903         local dir="$DIR/$tdir"
5904
5905         test_mkdir "$dir" || error "cannot create dir $dir"
5906
5907         echo "testing lfs migrate mode when all links fit within xattrs"
5908         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5909
5910         echo "testing rsync mode when all links fit within xattrs"
5911         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5912
5913         echo "testing lfs migrate mode when all links do not fit within xattrs"
5914         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5915
5916         echo "testing rsync mode when all links do not fit within xattrs"
5917         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5918
5919
5920         # clean up
5921         rm -rf $dir
5922 }
5923 run_test 56xb "lfs migration hard link support"
5924
5925 test_56xc() {
5926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5927
5928         local dir="$DIR/$tdir"
5929
5930         test_mkdir "$dir" || error "cannot create dir $dir"
5931
5932         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5933         echo -n "Setting initial stripe for 20MB test file..."
5934         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5935         echo "done"
5936         echo -n "Sizing 20MB test file..."
5937         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5938         echo "done"
5939         echo -n "Verifying small file autostripe count is 1..."
5940         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5941                 error "cannot migrate 20MB file"
5942         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5943                 error "cannot get stripe for $dir/20mb"
5944         [ $stripe_count -eq 1 ] ||
5945                 error "unexpected stripe count $stripe_count for 20MB file"
5946         rm -f "$dir/20mb"
5947         echo "done"
5948
5949         # Test 2: File is small enough to fit within the available space on
5950         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5951         # have at least an additional 1KB for each desired stripe for test 3
5952         echo -n "Setting stripe for 1GB test file..."
5953         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5954         echo "done"
5955         echo -n "Sizing 1GB test file..."
5956         # File size is 1GB + 3KB
5957         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5958                 error "cannot create 1GB test file"
5959         echo "done"
5960         echo -n "Migrating 1GB file..."
5961         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5962                 error "cannot migrate file"
5963         echo "done"
5964         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5965         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5966                 error "cannot get stripe for $dir/1gb"
5967         [ $stripe_count -eq 2 ] ||
5968                 error "unexpected stripe count $stripe_count (expected 2)"
5969         echo "done"
5970
5971         # Test 3: File is too large to fit within the available space on
5972         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5973         if [ $OSTCOUNT -ge 3 ]; then
5974                 # The required available space is calculated as
5975                 # file size (1GB + 3KB) / OST count (3).
5976                 local kb_per_ost=349526
5977
5978                 echo -n "Migrating 1GB file..."
5979                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5980                         /dev/null || error "cannot migrate file"
5981                 echo "done"
5982
5983                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5984                 echo -n "Verifying autostripe count with limited space..."
5985                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5986                         error "unexpected stripe count $stripe_count (wanted 3)"
5987                 echo "done"
5988         fi
5989
5990         # clean up
5991         rm -rf $dir
5992 }
5993 run_test 56xc "lfs migration autostripe"
5994
5995 test_56y() {
5996         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5997                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5998
5999         local res=""
6000         local dir=$DIR/$tdir
6001         local f1=$dir/file1
6002         local f2=$dir/file2
6003
6004         test_mkdir -p $dir || error "creating dir $dir"
6005         touch $f1 || error "creating std file $f1"
6006         $MULTIOP $f2 H2c || error "creating released file $f2"
6007
6008         # a directory can be raid0, so ask only for files
6009         res=$($LFS find $dir -L raid0 -type f | wc -l)
6010         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6011
6012         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6013         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6014
6015         # only files can be released, so no need to force file search
6016         res=$($LFS find $dir -L released)
6017         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6018
6019         res=$($LFS find $dir -type f \! -L released)
6020         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6021 }
6022 run_test 56y "lfs find -L raid0|released"
6023
6024 test_56z() { # LU-4824
6025         # This checks to make sure 'lfs find' continues after errors
6026         # There are two classes of errors that should be caught:
6027         # - If multiple paths are provided, all should be searched even if one
6028         #   errors out
6029         # - If errors are encountered during the search, it should not terminate
6030         #   early
6031         local dir=$DIR/$tdir
6032         local i
6033
6034         test_mkdir $dir
6035         for i in d{0..9}; do
6036                 test_mkdir $dir/$i
6037         done
6038         touch $dir/d{0..9}/$tfile
6039         $LFS find $DIR/non_existent_dir $dir &&
6040                 error "$LFS find did not return an error"
6041         # Make a directory unsearchable. This should NOT be the last entry in
6042         # directory order.  Arbitrarily pick the 6th entry
6043         chmod 700 $($LFS find $dir -type d | sed '6!d')
6044
6045         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6046
6047         # The user should be able to see 10 directories and 9 files
6048         [ $count == 19 ] || error "$LFS find did not continue after error"
6049 }
6050 run_test 56z "lfs find should continue after an error"
6051
6052 test_56aa() { # LU-5937
6053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6054
6055         local dir=$DIR/$tdir
6056
6057         mkdir $dir
6058         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6059
6060         createmany -o $dir/striped_dir/${tfile}- 1024
6061         local dirs=$($LFS find --size +8k $dir/)
6062
6063         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6064 }
6065 run_test 56aa "lfs find --size under striped dir"
6066
6067 test_56ab() { # LU-10705
6068         test_mkdir $DIR/$tdir
6069         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6070         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6071         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6072         # Flush writes to ensure valid blocks.  Need to be more thorough for
6073         # ZFS, since blocks are not allocated/returned to client immediately.
6074         sync_all_data
6075         wait_zfs_commit ost1 2
6076         cancel_lru_locks osc
6077         ls -ls $DIR/$tdir
6078
6079         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6080
6081         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6082
6083         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6084         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6085
6086         rm -f $DIR/$tdir/$tfile.[123]
6087 }
6088 run_test 56ab "lfs find --blocks"
6089
6090 test_56ba() {
6091         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6092                 skip "Need MDS version at least 2.10.50"
6093
6094         # Create composite files with one component
6095         local dir=$DIR/$tdir
6096
6097         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6098         # Create composite files with three components
6099         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6100         # Create non-composite files
6101         createmany -o $dir/${tfile}- 10
6102
6103         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6104
6105         [[ $nfiles == 10 ]] ||
6106                 error "lfs find -E 1M found $nfiles != 10 files"
6107
6108         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6109         [[ $nfiles == 25 ]] ||
6110                 error "lfs find ! -E 1M found $nfiles != 25 files"
6111
6112         # All files have a component that starts at 0
6113         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6114         [[ $nfiles == 35 ]] ||
6115                 error "lfs find --component-start 0 - $nfiles != 35 files"
6116
6117         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6118         [[ $nfiles == 15 ]] ||
6119                 error "lfs find --component-start 2M - $nfiles != 15 files"
6120
6121         # All files created here have a componenet that does not starts at 2M
6122         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6123         [[ $nfiles == 35 ]] ||
6124                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6125
6126         # Find files with a specified number of components
6127         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6128         [[ $nfiles == 15 ]] ||
6129                 error "lfs find --component-count 3 - $nfiles != 15 files"
6130
6131         # Remember non-composite files have a component count of zero
6132         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6133         [[ $nfiles == 10 ]] ||
6134                 error "lfs find --component-count 0 - $nfiles != 10 files"
6135
6136         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6137         [[ $nfiles == 20 ]] ||
6138                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6139
6140         # All files have a flag called "init"
6141         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6142         [[ $nfiles == 35 ]] ||
6143                 error "lfs find --component-flags init - $nfiles != 35 files"
6144
6145         # Multi-component files will have a component not initialized
6146         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6147         [[ $nfiles == 15 ]] ||
6148                 error "lfs find !--component-flags init - $nfiles != 15 files"
6149
6150         rm -rf $dir
6151
6152 }
6153 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6154
6155 test_56ca() {
6156         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6157                 skip "Need MDS version at least 2.10.57"
6158
6159         local td=$DIR/$tdir
6160         local tf=$td/$tfile
6161         local dir
6162         local nfiles
6163         local cmd
6164         local i
6165         local j
6166
6167         # create mirrored directories and mirrored files
6168         mkdir $td || error "mkdir $td failed"
6169         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6170         createmany -o $tf- 10 || error "create $tf- failed"
6171
6172         for i in $(seq 2); do
6173                 dir=$td/dir$i
6174                 mkdir $dir || error "mkdir $dir failed"
6175                 $LFS mirror create -N$((3 + i)) $dir ||
6176                         error "create mirrored dir $dir failed"
6177                 createmany -o $dir/$tfile- 10 ||
6178                         error "create $dir/$tfile- failed"
6179         done
6180
6181         # change the states of some mirrored files
6182         echo foo > $tf-6
6183         for i in $(seq 2); do
6184                 dir=$td/dir$i
6185                 for j in $(seq 4 9); do
6186                         echo foo > $dir/$tfile-$j
6187                 done
6188         done
6189
6190         # find mirrored files with specific mirror count
6191         cmd="$LFS find --mirror-count 3 --type f $td"
6192         nfiles=$($cmd | wc -l)
6193         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6194
6195         cmd="$LFS find ! --mirror-count 3 --type f $td"
6196         nfiles=$($cmd | wc -l)
6197         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6198
6199         cmd="$LFS find --mirror-count +2 --type f $td"
6200         nfiles=$($cmd | wc -l)
6201         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6202
6203         cmd="$LFS find --mirror-count -6 --type f $td"
6204         nfiles=$($cmd | wc -l)
6205         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6206
6207         # find mirrored files with specific file state
6208         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6209         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6210
6211         cmd="$LFS find --mirror-state=ro --type f $td"
6212         nfiles=$($cmd | wc -l)
6213         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6214
6215         cmd="$LFS find ! --mirror-state=ro --type f $td"
6216         nfiles=$($cmd | wc -l)
6217         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6218
6219         cmd="$LFS find --mirror-state=wp --type f $td"
6220         nfiles=$($cmd | wc -l)
6221         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6222
6223         cmd="$LFS find ! --mirror-state=sp --type f $td"
6224         nfiles=$($cmd | wc -l)
6225         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6226 }
6227 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6228
6229 test_57a() {
6230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6231         # note test will not do anything if MDS is not local
6232         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6233                 skip_env "ldiskfs only test"
6234         fi
6235         remote_mds_nodsh && skip "remote MDS with nodsh"
6236
6237         local MNTDEV="osd*.*MDT*.mntdev"
6238         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6239         [ -z "$DEV" ] && error "can't access $MNTDEV"
6240         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6241                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6242                         error "can't access $DEV"
6243                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6244                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6245                 rm $TMP/t57a.dump
6246         done
6247 }
6248 run_test 57a "verify MDS filesystem created with large inodes =="
6249
6250 test_57b() {
6251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6252         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6253                 skip_env "ldiskfs only test"
6254         fi
6255         remote_mds_nodsh && skip "remote MDS with nodsh"
6256
6257         local dir=$DIR/$tdir
6258         local filecount=100
6259         local file1=$dir/f1
6260         local fileN=$dir/f$filecount
6261
6262         rm -rf $dir || error "removing $dir"
6263         test_mkdir -c1 $dir
6264         local mdtidx=$($LFS getstripe -m $dir)
6265         local mdtname=MDT$(printf %04x $mdtidx)
6266         local facet=mds$((mdtidx + 1))
6267
6268         echo "mcreating $filecount files"
6269         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6270
6271         # verify that files do not have EAs yet
6272         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6273                 error "$file1 has an EA"
6274         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6275                 error "$fileN has an EA"
6276
6277         sync
6278         sleep 1
6279         df $dir  #make sure we get new statfs data
6280         local mdsfree=$(do_facet $facet \
6281                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6282         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6283         local file
6284
6285         echo "opening files to create objects/EAs"
6286         for file in $(seq -f $dir/f%g 1 $filecount); do
6287                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6288                         error "opening $file"
6289         done
6290
6291         # verify that files have EAs now
6292         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6293         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6294
6295         sleep 1  #make sure we get new statfs data
6296         df $dir
6297         local mdsfree2=$(do_facet $facet \
6298                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6299         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6300
6301         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6302                 if [ "$mdsfree" != "$mdsfree2" ]; then
6303                         error "MDC before $mdcfree != after $mdcfree2"
6304                 else
6305                         echo "MDC before $mdcfree != after $mdcfree2"
6306                         echo "unable to confirm if MDS has large inodes"
6307                 fi
6308         fi
6309         rm -rf $dir
6310 }
6311 run_test 57b "default LOV EAs are stored inside large inodes ==="
6312
6313 test_58() {
6314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6315         [ -z "$(which wiretest 2>/dev/null)" ] &&
6316                         skip_env "could not find wiretest"
6317
6318         wiretest
6319 }
6320 run_test 58 "verify cross-platform wire constants =============="
6321
6322 test_59() {
6323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6324
6325         echo "touch 130 files"
6326         createmany -o $DIR/f59- 130
6327         echo "rm 130 files"
6328         unlinkmany $DIR/f59- 130
6329         sync
6330         # wait for commitment of removal
6331         wait_delete_completed
6332 }
6333 run_test 59 "verify cancellation of llog records async ========="
6334
6335 TEST60_HEAD="test_60 run $RANDOM"
6336 test_60a() {
6337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6338         remote_mgs_nodsh && skip "remote MGS with nodsh"
6339         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6340                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6341                         skip_env "missing subtest run-llog.sh"
6342
6343         log "$TEST60_HEAD - from kernel mode"
6344         do_facet mgs "$LCTL dk > /dev/null"
6345         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6346         do_facet mgs $LCTL dk > $TMP/$tfile
6347
6348         # LU-6388: test llog_reader
6349         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6350         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6351         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6352                         skip_env "missing llog_reader"
6353         local fstype=$(facet_fstype mgs)
6354         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6355                 skip_env "Only for ldiskfs or zfs type mgs"
6356
6357         local mntpt=$(facet_mntpt mgs)
6358         local mgsdev=$(mgsdevname 1)
6359         local fid_list
6360         local fid
6361         local rec_list
6362         local rec
6363         local rec_type
6364         local obj_file
6365         local path
6366         local seq
6367         local oid
6368         local pass=true
6369
6370         #get fid and record list
6371         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6372                 tail -n 4))
6373         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6374                 tail -n 4))
6375         #remount mgs as ldiskfs or zfs type
6376         stop mgs || error "stop mgs failed"
6377         mount_fstype mgs || error "remount mgs failed"
6378         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6379                 fid=${fid_list[i]}
6380                 rec=${rec_list[i]}
6381                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6382                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6383                 oid=$((16#$oid))
6384
6385                 case $fstype in
6386                         ldiskfs )
6387                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6388                         zfs )
6389                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6390                 esac
6391                 echo "obj_file is $obj_file"
6392                 do_facet mgs $llog_reader $obj_file
6393
6394                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6395                         awk '{ print $3 }' | sed -e "s/^type=//g")
6396                 if [ $rec_type != $rec ]; then
6397                         echo "FAILED test_60a wrong record type $rec_type," \
6398                               "should be $rec"
6399                         pass=false
6400                         break
6401                 fi
6402
6403                 #check obj path if record type is LLOG_LOGID_MAGIC
6404                 if [ "$rec" == "1064553b" ]; then
6405                         path=$(do_facet mgs $llog_reader $obj_file |
6406                                 grep "path=" | awk '{ print $NF }' |
6407                                 sed -e "s/^path=//g")
6408                         if [ $obj_file != $mntpt/$path ]; then
6409                                 echo "FAILED test_60a wrong obj path" \
6410                                       "$montpt/$path, should be $obj_file"
6411                                 pass=false
6412                                 break
6413                         fi
6414                 fi
6415         done
6416         rm -f $TMP/$tfile
6417         #restart mgs before "error", otherwise it will block the next test
6418         stop mgs || error "stop mgs failed"
6419         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6420         $pass || error "test failed, see FAILED test_60a messages for specifics"
6421 }
6422 run_test 60a "llog_test run from kernel module and test llog_reader"
6423
6424 test_60b() { # bug 6411
6425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6426
6427         dmesg > $DIR/$tfile
6428         LLOG_COUNT=$(do_facet mgs dmesg |
6429                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6430                           /llog_[a-z]*.c:[0-9]/ {
6431                                 if (marker)
6432                                         from_marker++
6433                                 from_begin++
6434                           }
6435                           END {
6436                                 if (marker)
6437                                         print from_marker
6438                                 else
6439                                         print from_begin
6440                           }")
6441
6442         [[ $LLOG_COUNT -gt 120 ]] &&
6443                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6444 }
6445 run_test 60b "limit repeated messages from CERROR/CWARN"
6446
6447 test_60c() {
6448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6449
6450         echo "create 5000 files"
6451         createmany -o $DIR/f60c- 5000
6452 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6453         lctl set_param fail_loc=0x80000137
6454         unlinkmany $DIR/f60c- 5000
6455         lctl set_param fail_loc=0
6456 }
6457 run_test 60c "unlink file when mds full"
6458
6459 test_60d() {
6460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6461
6462         SAVEPRINTK=$(lctl get_param -n printk)
6463         # verify "lctl mark" is even working"
6464         MESSAGE="test message ID $RANDOM $$"
6465         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6466         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6467
6468         lctl set_param printk=0 || error "set lnet.printk failed"
6469         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6470         MESSAGE="new test message ID $RANDOM $$"
6471         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6472         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6473         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6474
6475         lctl set_param -n printk="$SAVEPRINTK"
6476 }
6477 run_test 60d "test printk console message masking"
6478
6479 test_60e() {
6480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6481         remote_mds_nodsh && skip "remote MDS with nodsh"
6482
6483         touch $DIR/$tfile
6484 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6485         do_facet mds1 lctl set_param fail_loc=0x15b
6486         rm $DIR/$tfile
6487 }
6488 run_test 60e "no space while new llog is being created"
6489
6490 test_60g() {
6491         local pid
6492
6493         test_mkdir -c $MDSCOUNT $DIR/$tdir
6494         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6495
6496         (
6497                 local index=0
6498                 while true; do
6499                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6500                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6501                         index=$((index + 1))
6502                 done
6503         ) &
6504
6505         pid=$!
6506
6507         for i in $(seq 100); do 
6508                 # define OBD_FAIL_OSD_TXN_START    0x19a
6509                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6510                 usleep 100
6511         done
6512
6513         kill -9 $pid
6514
6515         mkdir $DIR/$tdir/new || error "mkdir failed"
6516         rmdir $DIR/$tdir/new || error "rmdir failed"
6517 }
6518 run_test 60g "transaction abort won't cause MDT hung"
6519
6520 test_61a() {
6521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6522
6523         f="$DIR/f61"
6524         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6525         cancel_lru_locks osc
6526         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6527         sync
6528 }
6529 run_test 61a "mmap() writes don't make sync hang ================"
6530
6531 test_61b() {
6532         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6533 }
6534 run_test 61b "mmap() of unstriped file is successful"
6535
6536 # bug 2330 - insufficient obd_match error checking causes LBUG
6537 test_62() {
6538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6539
6540         f="$DIR/f62"
6541         echo foo > $f
6542         cancel_lru_locks osc
6543         lctl set_param fail_loc=0x405
6544         cat $f && error "cat succeeded, expect -EIO"
6545         lctl set_param fail_loc=0
6546 }
6547 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6548 # match every page all of the time.
6549 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6550
6551 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6552 # Though this test is irrelevant anymore, it helped to reveal some
6553 # other grant bugs (LU-4482), let's keep it.
6554 test_63a() {   # was test_63
6555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6556
6557         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6558
6559         for i in `seq 10` ; do
6560                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6561                 sleep 5
6562                 kill $!
6563                 sleep 1
6564         done
6565
6566         rm -f $DIR/f63 || true
6567 }
6568 run_test 63a "Verify oig_wait interruption does not crash ======="
6569
6570 # bug 2248 - async write errors didn't return to application on sync
6571 # bug 3677 - async write errors left page locked
6572 test_63b() {
6573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6574
6575         debugsave
6576         lctl set_param debug=-1
6577
6578         # ensure we have a grant to do async writes
6579         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6580         rm $DIR/$tfile
6581
6582         sync    # sync lest earlier test intercept the fail_loc
6583
6584         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6585         lctl set_param fail_loc=0x80000406
6586         $MULTIOP $DIR/$tfile Owy && \
6587                 error "sync didn't return ENOMEM"
6588         sync; sleep 2; sync     # do a real sync this time to flush page
6589         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6590                 error "locked page left in cache after async error" || true
6591         debugrestore
6592 }
6593 run_test 63b "async write errors should be returned to fsync ==="
6594
6595 test_64a () {
6596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6597
6598         df $DIR
6599         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6600 }
6601 run_test 64a "verify filter grant calculations (in kernel) ====="
6602
6603 test_64b () {
6604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6605
6606         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6607 }
6608 run_test 64b "check out-of-space detection on client"
6609
6610 test_64c() {
6611         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6612 }
6613 run_test 64c "verify grant shrink"
6614
6615 # this does exactly what osc_request.c:osc_announce_cached() does in
6616 # order to calculate max amount of grants to ask from server
6617 want_grant() {
6618         local tgt=$1
6619
6620         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6621         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6622
6623         ((rpc_in_flight ++));
6624         nrpages=$((nrpages * rpc_in_flight))
6625
6626         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6627
6628         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6629
6630         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6631         local undirty=$((nrpages * PAGE_SIZE))
6632
6633         local max_extent_pages
6634         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6635             grep grant_max_extent_size | awk '{print $2}')
6636         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6637         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6638         local grant_extent_tax
6639         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6640             grep grant_extent_tax | awk '{print $2}')
6641
6642         undirty=$((undirty + nrextents * grant_extent_tax))
6643
6644         echo $undirty
6645 }
6646
6647 # this is size of unit for grant allocation. It should be equal to
6648 # what tgt_grant.c:tgt_grant_chunk() calculates
6649 grant_chunk() {
6650         local tgt=$1
6651         local max_brw_size
6652         local grant_extent_tax
6653
6654         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6655             grep max_brw_size | awk '{print $2}')
6656
6657         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6658             grep grant_extent_tax | awk '{print $2}')
6659
6660         echo $(((max_brw_size + grant_extent_tax) * 2))
6661 }
6662
6663 test_64d() {
6664         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6665                 skip "OST < 2.10.55 doesn't limit grants enough"
6666
6667         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6668         local file=$DIR/$tfile
6669
6670         [[ $($LCTL get_param osc.${tgt}.import |
6671              grep "connect_flags:.*grant_param") ]] ||
6672                 skip "no grant_param connect flag"
6673
6674         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6675
6676         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6677
6678         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6679         stack_trap "rm -f $file" EXIT
6680
6681         $LFS setstripe $file -i 0 -c 1
6682         dd if=/dev/zero of=$file bs=1M count=1000 &
6683         ddpid=$!
6684
6685         while true
6686         do
6687                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6688                 if [[ $cur_grant -gt $max_cur_granted ]]
6689                 then
6690                         kill $ddpid
6691                         error "cur_grant $cur_grant > $max_cur_granted"
6692                 fi
6693                 kill -0 $ddpid
6694                 [[ $? -ne 0 ]] && break;
6695                 sleep 2
6696         done
6697
6698         rm -f $DIR/$tfile
6699         wait_delete_completed
6700         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6701 }
6702 run_test 64d "check grant limit exceed"
6703
6704 # bug 1414 - set/get directories' stripe info
6705 test_65a() {
6706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6707
6708         test_mkdir $DIR/$tdir
6709         touch $DIR/$tdir/f1
6710         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6711 }
6712 run_test 65a "directory with no stripe info"
6713
6714 test_65b() {
6715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6716
6717         test_mkdir $DIR/$tdir
6718         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6719
6720         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6721                                                 error "setstripe"
6722         touch $DIR/$tdir/f2
6723         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6724 }
6725 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6726
6727 test_65c() {
6728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6729         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6730
6731         test_mkdir $DIR/$tdir
6732         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6733
6734         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6735                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6736         touch $DIR/$tdir/f3
6737         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6738 }
6739 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6740
6741 test_65d() {
6742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6743
6744         test_mkdir $DIR/$tdir
6745         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6746         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6747
6748         if [[ $STRIPECOUNT -le 0 ]]; then
6749                 sc=1
6750         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6751 #LOV_MAX_STRIPE_COUNT is 2000
6752                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6753         else
6754                 sc=$(($STRIPECOUNT - 1))
6755         fi
6756         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6757         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6758         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6759                 error "lverify failed"
6760 }
6761 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6762
6763 test_65e() {
6764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6765
6766         test_mkdir $DIR/$tdir
6767
6768         $LFS setstripe $DIR/$tdir || error "setstripe"
6769         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6770                                         error "no stripe info failed"
6771         touch $DIR/$tdir/f6
6772         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6773 }
6774 run_test 65e "directory setstripe defaults"
6775
6776 test_65f() {
6777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6778
6779         test_mkdir $DIR/${tdir}f
6780         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6781                 error "setstripe succeeded" || true
6782 }
6783 run_test 65f "dir setstripe permission (should return error) ==="
6784
6785 test_65g() {
6786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6787
6788         test_mkdir $DIR/$tdir
6789         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6790
6791         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6792                 error "setstripe -S failed"
6793         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6794         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6795                 error "delete default stripe failed"
6796 }
6797 run_test 65g "directory setstripe -d"
6798
6799 test_65h() {
6800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6801
6802         test_mkdir $DIR/$tdir
6803         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6804
6805         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6806                 error "setstripe -S failed"
6807         test_mkdir $DIR/$tdir/dd1
6808         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6809                 error "stripe info inherit failed"
6810 }
6811 run_test 65h "directory stripe info inherit ===================="
6812
6813 test_65i() {
6814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6815
6816         save_layout_restore_at_exit $MOUNT
6817
6818         # bug6367: set non-default striping on root directory
6819         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6820
6821         # bug12836: getstripe on -1 default directory striping
6822         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6823
6824         # bug12836: getstripe -v on -1 default directory striping
6825         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6826
6827         # bug12836: new find on -1 default directory striping
6828         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6829 }
6830 run_test 65i "various tests to set root directory striping"
6831
6832 test_65j() { # bug6367
6833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6834
6835         sync; sleep 1
6836
6837         # if we aren't already remounting for each test, do so for this test
6838         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6839                 cleanup || error "failed to unmount"
6840                 setup
6841         fi
6842
6843         save_layout_restore_at_exit $MOUNT
6844
6845         $LFS setstripe -d $MOUNT || error "setstripe failed"
6846 }
6847 run_test 65j "set default striping on root directory (bug 6367)="
6848
6849 cleanup_65k() {
6850         rm -rf $DIR/$tdir
6851         wait_delete_completed
6852         do_facet $SINGLEMDS "lctl set_param -n \
6853                 osp.$ost*MDT0000.max_create_count=$max_count"
6854         do_facet $SINGLEMDS "lctl set_param -n \
6855                 osp.$ost*MDT0000.create_count=$count"
6856         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6857         echo $INACTIVE_OSC "is Activate"
6858
6859         wait_osc_import_state mds ost$ostnum FULL
6860 }
6861
6862 test_65k() { # bug11679
6863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6865         remote_mds_nodsh && skip "remote MDS with nodsh"
6866
6867         local disable_precreate=true
6868         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6869                 disable_precreate=false
6870
6871         echo "Check OST status: "
6872         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6873                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6874
6875         for OSC in $MDS_OSCS; do
6876                 echo $OSC "is active"
6877                 do_facet $SINGLEMDS lctl --device %$OSC activate
6878         done
6879
6880         for INACTIVE_OSC in $MDS_OSCS; do
6881                 local ost=$(osc_to_ost $INACTIVE_OSC)
6882                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6883                                lov.*md*.target_obd |
6884                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6885
6886                 mkdir -p $DIR/$tdir
6887                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6888                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6889
6890                 echo "Deactivate: " $INACTIVE_OSC
6891                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6892
6893                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6894                               osp.$ost*MDT0000.create_count")
6895                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6896                                   osp.$ost*MDT0000.max_create_count")
6897                 $disable_precreate &&
6898                         do_facet $SINGLEMDS "lctl set_param -n \
6899                                 osp.$ost*MDT0000.max_create_count=0"
6900
6901                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6902                         [ -f $DIR/$tdir/$idx ] && continue
6903                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6904                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6905                                 { cleanup_65k;
6906                                   error "setstripe $idx should succeed"; }
6907                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6908                 done
6909                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6910                 rmdir $DIR/$tdir
6911
6912                 do_facet $SINGLEMDS "lctl set_param -n \
6913                         osp.$ost*MDT0000.max_create_count=$max_count"
6914                 do_facet $SINGLEMDS "lctl set_param -n \
6915                         osp.$ost*MDT0000.create_count=$count"
6916                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6917                 echo $INACTIVE_OSC "is Activate"
6918
6919                 wait_osc_import_state mds ost$ostnum FULL
6920         done
6921 }
6922 run_test 65k "validate manual striping works properly with deactivated OSCs"
6923
6924 test_65l() { # bug 12836
6925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6926
6927         test_mkdir -p $DIR/$tdir/test_dir
6928         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6929         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6930 }
6931 run_test 65l "lfs find on -1 stripe dir ========================"
6932
6933 test_65m() {
6934         local layout=$(save_layout $MOUNT)
6935         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6936                 restore_layout $MOUNT $layout
6937                 error "setstripe should fail by non-root users"
6938         }
6939         true
6940 }
6941 run_test 65m "normal user can't set filesystem default stripe"
6942
6943 test_65n() {
6944         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6945         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6946                 skip "Need MDS version at least 2.12.50"
6947         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6948
6949         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6950         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6951         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6952
6953         local root_layout=$(save_layout $MOUNT)
6954         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6955
6956         # new subdirectory under root directory should not inherit
6957         # the default layout from root
6958         local dir1=$MOUNT/$tdir-1
6959         mkdir $dir1 || error "mkdir $dir1 failed"
6960         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6961                 error "$dir1 shouldn't have LOV EA"
6962
6963         # delete the default layout on root directory
6964         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6965
6966         local dir2=$MOUNT/$tdir-2
6967         mkdir $dir2 || error "mkdir $dir2 failed"
6968         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6969                 error "$dir2 shouldn't have LOV EA"
6970
6971         # set a new striping pattern on root directory
6972         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6973         local new_def_stripe_size=$((def_stripe_size * 2))
6974         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6975                 error "set stripe size on $MOUNT failed"
6976
6977         # new file created in $dir2 should inherit the new stripe size from
6978         # the filesystem default
6979         local file2=$dir2/$tfile-2
6980         touch $file2 || error "touch $file2 failed"
6981
6982         local file2_stripe_size=$($LFS getstripe -S $file2)
6983         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6984                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6985
6986         local dir3=$MOUNT/$tdir-3
6987         mkdir $dir3 || error "mkdir $dir3 failed"
6988         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6989                 error "$dir3 shouldn't have LOV EA"
6990
6991         # set OST pool on root directory
6992         local pool=$TESTNAME
6993         pool_add $pool || error "add $pool failed"
6994         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6995                 error "add targets to $pool failed"
6996
6997         $LFS setstripe -p $pool $MOUNT ||
6998                 error "set OST pool on $MOUNT failed"
6999
7000         # new file created in $dir3 should inherit the pool from
7001         # the filesystem default
7002         local file3=$dir3/$tfile-3
7003         touch $file3 || error "touch $file3 failed"
7004
7005         local file3_pool=$($LFS getstripe -p $file3)
7006         [[ "$file3_pool" = "$pool" ]] ||
7007                 error "$file3 didn't inherit OST pool $pool"
7008
7009         local dir4=$MOUNT/$tdir-4
7010         mkdir $dir4 || error "mkdir $dir4 failed"
7011         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7012                 error "$dir4 shouldn't have LOV EA"
7013
7014         # new file created in $dir4 should inherit the pool from
7015         # the filesystem default
7016         local file4=$dir4/$tfile-4
7017         touch $file4 || error "touch $file4 failed"
7018
7019         local file4_pool=$($LFS getstripe -p $file4)
7020         [[ "$file4_pool" = "$pool" ]] ||
7021                 error "$file4 didn't inherit OST pool $pool"
7022
7023         # new subdirectory under non-root directory should inherit
7024         # the default layout from its parent directory
7025         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7026                 error "set directory layout on $dir4 failed"
7027
7028         local dir5=$dir4/$tdir-5
7029         mkdir $dir5 || error "mkdir $dir5 failed"
7030
7031         local dir4_layout=$(get_layout_param $dir4)
7032         local dir5_layout=$(get_layout_param $dir5)
7033         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7034                 error "$dir5 should inherit the default layout from $dir4"
7035 }
7036 run_test 65n "don't inherit default layout from root for new subdirectories"
7037
7038 # bug 2543 - update blocks count on client
7039 test_66() {
7040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7041
7042         COUNT=${COUNT:-8}
7043         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7044         sync; sync_all_data; sync; sync_all_data
7045         cancel_lru_locks osc
7046         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7047         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7048 }
7049 run_test 66 "update inode blocks count on client ==============="
7050
7051 meminfo() {
7052         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7053 }
7054
7055 swap_used() {
7056         swapon -s | awk '($1 == "'$1'") { print $4 }'
7057 }
7058
7059 # bug5265, obdfilter oa2dentry return -ENOENT
7060 # #define OBD_FAIL_SRV_ENOENT 0x217
7061 test_69() {
7062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7063         remote_ost_nodsh && skip "remote OST with nodsh"
7064
7065         f="$DIR/$tfile"
7066         $LFS setstripe -c 1 -i 0 $f
7067
7068         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7069
7070         do_facet ost1 lctl set_param fail_loc=0x217
7071         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7072         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7073
7074         do_facet ost1 lctl set_param fail_loc=0
7075         $DIRECTIO write $f 0 2 || error "write error"
7076
7077         cancel_lru_locks osc
7078         $DIRECTIO read $f 0 1 || error "read error"
7079
7080         do_facet ost1 lctl set_param fail_loc=0x217
7081         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7082
7083         do_facet ost1 lctl set_param fail_loc=0
7084         rm -f $f
7085 }
7086 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7087
7088 test_71() {
7089         test_mkdir $DIR/$tdir
7090         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7091         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7092 }
7093 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7094
7095 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7097         [ "$RUNAS_ID" = "$UID" ] &&
7098                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7099         # Check that testing environment is properly set up. Skip if not
7100         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7101                 skip_env "User $RUNAS_ID does not exist - skipping"
7102
7103         touch $DIR/$tfile
7104         chmod 777 $DIR/$tfile
7105         chmod ug+s $DIR/$tfile
7106         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7107                 error "$RUNAS dd $DIR/$tfile failed"
7108         # See if we are still setuid/sgid
7109         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7110                 error "S/gid is not dropped on write"
7111         # Now test that MDS is updated too
7112         cancel_lru_locks mdc
7113         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7114                 error "S/gid is not dropped on MDS"
7115         rm -f $DIR/$tfile
7116 }
7117 run_test 72a "Test that remove suid works properly (bug5695) ===="
7118
7119 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7120         local perm
7121
7122         [ "$RUNAS_ID" = "$UID" ] &&
7123                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7124         [ "$RUNAS_ID" -eq 0 ] &&
7125                 skip_env "RUNAS_ID = 0 -- skipping"
7126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7127         # Check that testing environment is properly set up. Skip if not
7128         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7129                 skip_env "User $RUNAS_ID does not exist - skipping"
7130
7131         touch $DIR/${tfile}-f{g,u}
7132         test_mkdir $DIR/${tfile}-dg
7133         test_mkdir $DIR/${tfile}-du
7134         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7135         chmod g+s $DIR/${tfile}-{f,d}g
7136         chmod u+s $DIR/${tfile}-{f,d}u
7137         for perm in 777 2777 4777; do
7138                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7139                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7140                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7141                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7142         done
7143         true
7144 }
7145 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7146
7147 # bug 3462 - multiple simultaneous MDC requests
7148 test_73() {
7149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7150
7151         test_mkdir $DIR/d73-1
7152         test_mkdir $DIR/d73-2
7153         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7154         pid1=$!
7155
7156         lctl set_param fail_loc=0x80000129
7157         $MULTIOP $DIR/d73-1/f73-2 Oc &
7158         sleep 1
7159         lctl set_param fail_loc=0
7160
7161         $MULTIOP $DIR/d73-2/f73-3 Oc &
7162         pid3=$!
7163
7164         kill -USR1 $pid1
7165         wait $pid1 || return 1
7166
7167         sleep 25
7168
7169         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7170         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7171         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7172
7173         rm -rf $DIR/d73-*
7174 }
7175 run_test 73 "multiple MDC requests (should not deadlock)"
7176
7177 test_74a() { # bug 6149, 6184
7178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7179
7180         touch $DIR/f74a
7181         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7182         #
7183         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7184         # will spin in a tight reconnection loop
7185         $LCTL set_param fail_loc=0x8000030e
7186         # get any lock that won't be difficult - lookup works.
7187         ls $DIR/f74a
7188         $LCTL set_param fail_loc=0
7189         rm -f $DIR/f74a
7190         true
7191 }
7192 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7193
7194 test_74b() { # bug 13310
7195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7196
7197         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7198         #
7199         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7200         # will spin in a tight reconnection loop
7201         $LCTL set_param fail_loc=0x8000030e
7202         # get a "difficult" lock
7203         touch $DIR/f74b
7204         $LCTL set_param fail_loc=0
7205         rm -f $DIR/f74b
7206         true
7207 }
7208 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7209
7210 test_74c() {
7211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7212
7213         #define OBD_FAIL_LDLM_NEW_LOCK
7214         $LCTL set_param fail_loc=0x319
7215         touch $DIR/$tfile && error "touch successful"
7216         $LCTL set_param fail_loc=0
7217         true
7218 }
7219 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7220
7221 num_inodes() {
7222         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7223 }
7224
7225 test_76() { # Now for bug 20433, added originally in bug 1443
7226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7227
7228         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7229
7230         cancel_lru_locks osc
7231         BEFORE_INODES=$(num_inodes)
7232         echo "before inodes: $BEFORE_INODES"
7233         local COUNT=1000
7234         [ "$SLOW" = "no" ] && COUNT=100
7235         for i in $(seq $COUNT); do
7236                 touch $DIR/$tfile
7237                 rm -f $DIR/$tfile
7238         done
7239         cancel_lru_locks osc
7240         AFTER_INODES=$(num_inodes)
7241         echo "after inodes: $AFTER_INODES"
7242         local wait=0
7243         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7244                 sleep 2
7245                 AFTER_INODES=$(num_inodes)
7246                 wait=$((wait+2))
7247                 echo "wait $wait seconds inodes: $AFTER_INODES"
7248                 if [ $wait -gt 30 ]; then
7249                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7250                 fi
7251         done
7252 }
7253 run_test 76 "confirm clients recycle inodes properly ===="
7254
7255
7256 export ORIG_CSUM=""
7257 set_checksums()
7258 {
7259         # Note: in sptlrpc modes which enable its own bulk checksum, the
7260         # original crc32_le bulk checksum will be automatically disabled,
7261         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7262         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7263         # In this case set_checksums() will not be no-op, because sptlrpc
7264         # bulk checksum will be enabled all through the test.
7265
7266         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7267         lctl set_param -n osc.*.checksums $1
7268         return 0
7269 }
7270
7271 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7272                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7273 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7274                              tr -d [] | head -n1)}
7275 set_checksum_type()
7276 {
7277         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7278         log "set checksum type to $1"
7279         return 0
7280 }
7281 F77_TMP=$TMP/f77-temp
7282 F77SZ=8
7283 setup_f77() {
7284         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7285                 error "error writing to $F77_TMP"
7286 }
7287
7288 test_77a() { # bug 10889
7289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7290         $GSS && skip_env "could not run with gss"
7291
7292         [ ! -f $F77_TMP ] && setup_f77
7293         set_checksums 1
7294         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7295         set_checksums 0
7296         rm -f $DIR/$tfile
7297 }
7298 run_test 77a "normal checksum read/write operation"
7299
7300 test_77b() { # bug 10889
7301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7302         $GSS && skip_env "could not run with gss"
7303
7304         [ ! -f $F77_TMP ] && setup_f77
7305         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7306         $LCTL set_param fail_loc=0x80000409
7307         set_checksums 1
7308
7309         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7310                 error "dd error: $?"
7311         $LCTL set_param fail_loc=0
7312
7313         for algo in $CKSUM_TYPES; do
7314                 cancel_lru_locks osc
7315                 set_checksum_type $algo
7316                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7317                 $LCTL set_param fail_loc=0x80000408
7318                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7319                 $LCTL set_param fail_loc=0
7320         done
7321         set_checksums 0
7322         set_checksum_type $ORIG_CSUM_TYPE
7323         rm -f $DIR/$tfile
7324 }
7325 run_test 77b "checksum error on client write, read"
7326
7327 cleanup_77c() {
7328         trap 0
7329         set_checksums 0
7330         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7331         $check_ost &&
7332                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7333         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7334         $check_ost && [ -n "$ost_file_prefix" ] &&
7335                 do_facet ost1 rm -f ${ost_file_prefix}\*
7336 }
7337
7338 test_77c() {
7339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7340         $GSS && skip_env "could not run with gss"
7341         remote_ost_nodsh && skip "remote OST with nodsh"
7342
7343         local bad1
7344         local osc_file_prefix
7345         local osc_file
7346         local check_ost=false
7347         local ost_file_prefix
7348         local ost_file
7349         local orig_cksum
7350         local dump_cksum
7351         local fid
7352
7353         # ensure corruption will occur on first OSS/OST
7354         $LFS setstripe -i 0 $DIR/$tfile
7355
7356         [ ! -f $F77_TMP ] && setup_f77
7357         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7358                 error "dd write error: $?"
7359         fid=$($LFS path2fid $DIR/$tfile)
7360
7361         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7362         then
7363                 check_ost=true
7364                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7365                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7366         else
7367                 echo "OSS do not support bulk pages dump upon error"
7368         fi
7369
7370         osc_file_prefix=$($LCTL get_param -n debug_path)
7371         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7372
7373         trap cleanup_77c EXIT
7374
7375         set_checksums 1
7376         # enable bulk pages dump upon error on Client
7377         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7378         # enable bulk pages dump upon error on OSS
7379         $check_ost &&
7380                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7381
7382         # flush Client cache to allow next read to reach OSS
7383         cancel_lru_locks osc
7384
7385         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7386         $LCTL set_param fail_loc=0x80000408
7387         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7388         $LCTL set_param fail_loc=0
7389
7390         rm -f $DIR/$tfile
7391
7392         # check cksum dump on Client
7393         osc_file=$(ls ${osc_file_prefix}*)
7394         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7395         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7396         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7397         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7398         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7399                      cksum)
7400         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7401         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7402                 error "dump content does not match on Client"
7403
7404         $check_ost || skip "No need to check cksum dump on OSS"
7405
7406         # check cksum dump on OSS
7407         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7408         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7409         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7410         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7411         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7412                 error "dump content does not match on OSS"
7413
7414         cleanup_77c
7415 }
7416 run_test 77c "checksum error on client read with debug"
7417
7418 test_77d() { # bug 10889
7419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7420         $GSS && skip_env "could not run with gss"
7421
7422         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7423         $LCTL set_param fail_loc=0x80000409
7424         set_checksums 1
7425         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7426                 error "direct write: rc=$?"
7427         $LCTL set_param fail_loc=0
7428         set_checksums 0
7429
7430         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7431         $LCTL set_param fail_loc=0x80000408
7432         set_checksums 1
7433         cancel_lru_locks osc
7434         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7435                 error "direct read: rc=$?"
7436         $LCTL set_param fail_loc=0
7437         set_checksums 0
7438 }
7439 run_test 77d "checksum error on OST direct write, read"
7440
7441 test_77f() { # bug 10889
7442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7443         $GSS && skip_env "could not run with gss"
7444
7445         set_checksums 1
7446         for algo in $CKSUM_TYPES; do
7447                 cancel_lru_locks osc
7448                 set_checksum_type $algo
7449                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7450                 $LCTL set_param fail_loc=0x409
7451                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7452                         error "direct write succeeded"
7453                 $LCTL set_param fail_loc=0
7454         done
7455         set_checksum_type $ORIG_CSUM_TYPE
7456         set_checksums 0
7457 }
7458 run_test 77f "repeat checksum error on write (expect error)"
7459
7460 test_77g() { # bug 10889
7461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7462         $GSS && skip_env "could not run with gss"
7463         remote_ost_nodsh && skip "remote OST with nodsh"
7464
7465         [ ! -f $F77_TMP ] && setup_f77
7466
7467         local file=$DIR/$tfile
7468         stack_trap "rm -f $file" EXIT
7469
7470         $LFS setstripe -c 1 -i 0 $file
7471         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7472         do_facet ost1 lctl set_param fail_loc=0x8000021a
7473         set_checksums 1
7474         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7475                 error "write error: rc=$?"
7476         do_facet ost1 lctl set_param fail_loc=0
7477         set_checksums 0
7478
7479         cancel_lru_locks osc
7480         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7481         do_facet ost1 lctl set_param fail_loc=0x8000021b
7482         set_checksums 1
7483         cmp $F77_TMP $file || error "file compare failed"
7484         do_facet ost1 lctl set_param fail_loc=0
7485         set_checksums 0
7486 }
7487 run_test 77g "checksum error on OST write, read"
7488
7489 test_77k() { # LU-10906
7490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7491         $GSS && skip_env "could not run with gss"
7492
7493         local cksum_param="osc.$FSNAME*.checksums"
7494         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7495         local checksum
7496         local i
7497
7498         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7499         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7500         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7501                 EXIT
7502
7503         for i in 0 1; do
7504                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7505                         error "failed to set checksum=$i on MGS"
7506                 wait_update $HOSTNAME "$get_checksum" $i
7507                 #remount
7508                 echo "remount client, checksum should be $i"
7509                 remount_client $MOUNT || "failed to remount client"
7510                 checksum=$(eval $get_checksum)
7511                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7512         done
7513         # remove persistent param to avoid races with checksum mountopt below
7514         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7515                 error "failed to delete checksum on MGS"
7516
7517         for opt in "checksum" "nochecksum"; do
7518                 #remount with mount option
7519                 echo "remount client with option $opt, checksum should be $i"
7520                 umount_client $MOUNT || "failed to umount client"
7521                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7522                         "failed to mount client with option '$opt'"
7523                 checksum=$(eval $get_checksum)
7524                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7525                 i=$((i - 1))
7526         done
7527
7528         remount_client $MOUNT || "failed to remount client"
7529 }
7530 run_test 77k "enable/disable checksum correctly"
7531
7532 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7533 rm -f $F77_TMP
7534 unset F77_TMP
7535
7536 cleanup_test_78() {
7537         trap 0
7538         rm -f $DIR/$tfile
7539 }
7540
7541 test_78() { # bug 10901
7542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7543         remote_ost || skip_env "local OST"
7544
7545         NSEQ=5
7546         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7547         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7548         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7549         echo "MemTotal: $MEMTOTAL"
7550
7551         # reserve 256MB of memory for the kernel and other running processes,
7552         # and then take 1/2 of the remaining memory for the read/write buffers.
7553         if [ $MEMTOTAL -gt 512 ] ;then
7554                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7555         else
7556                 # for those poor memory-starved high-end clusters...
7557                 MEMTOTAL=$((MEMTOTAL / 2))
7558         fi
7559         echo "Mem to use for directio: $MEMTOTAL"
7560
7561         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7562         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7563         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7564         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7565                 head -n1)
7566         echo "Smallest OST: $SMALLESTOST"
7567         [[ $SMALLESTOST -lt 10240 ]] &&
7568                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7569
7570         trap cleanup_test_78 EXIT
7571
7572         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7573                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7574
7575         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7576         echo "File size: $F78SIZE"
7577         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7578         for i in $(seq 1 $NSEQ); do
7579                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7580                 echo directIO rdwr round $i of $NSEQ
7581                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7582         done
7583
7584         cleanup_test_78
7585 }
7586 run_test 78 "handle large O_DIRECT writes correctly ============"
7587
7588 test_79() { # bug 12743
7589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7590
7591         wait_delete_completed
7592
7593         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7594         BKFREE=$(calc_osc_kbytes kbytesfree)
7595         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7596
7597         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7598         DFTOTAL=`echo $STRING | cut -d, -f1`
7599         DFUSED=`echo $STRING  | cut -d, -f2`
7600         DFAVAIL=`echo $STRING | cut -d, -f3`
7601         DFFREE=$(($DFTOTAL - $DFUSED))
7602
7603         ALLOWANCE=$((64 * $OSTCOUNT))
7604
7605         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7606            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7607                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7608         fi
7609         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7610            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7611                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7612         fi
7613         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7614            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7615                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7616         fi
7617 }
7618 run_test 79 "df report consistency check ======================="
7619
7620 test_80() { # bug 10718
7621         remote_ost_nodsh && skip "remote OST with nodsh"
7622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7623
7624         # relax strong synchronous semantics for slow backends like ZFS
7625         local soc="obdfilter.*.sync_on_lock_cancel"
7626         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7627         local hosts=
7628         if [ "$soc_old" != "never" ] &&
7629                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7630                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7631                                 facet_active_host $host; done | sort -u)
7632                         do_nodes $hosts lctl set_param $soc=never
7633         fi
7634
7635         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7636         sync; sleep 1; sync
7637         local BEFORE=`date +%s`
7638         cancel_lru_locks osc
7639         local AFTER=`date +%s`
7640         local DIFF=$((AFTER-BEFORE))
7641         if [ $DIFF -gt 1 ] ; then
7642                 error "elapsed for 1M@1T = $DIFF"
7643         fi
7644
7645         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7646
7647         rm -f $DIR/$tfile
7648 }
7649 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7650
7651 test_81a() { # 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         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7657         do_facet ost1 lctl set_param fail_loc=0x80000228
7658
7659         # write should trigger a retry and success
7660         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7661         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7662         RC=$?
7663         if [ $RC -ne 0 ] ; then
7664                 error "write should success, but failed for $RC"
7665         fi
7666 }
7667 run_test 81a "OST should retry write when get -ENOSPC ==============="
7668
7669 test_81b() { # LU-456
7670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7671         remote_ost_nodsh && skip "remote OST with nodsh"
7672
7673         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7674         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7675         do_facet ost1 lctl set_param fail_loc=0x228
7676
7677         # write should retry several times and return -ENOSPC finally
7678         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7679         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7680         RC=$?
7681         ENOSPC=28
7682         if [ $RC -ne $ENOSPC ] ; then
7683                 error "dd should fail for -ENOSPC, but succeed."
7684         fi
7685 }
7686 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7687
7688 test_82() { # LU-1031
7689         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7690         local gid1=14091995
7691         local gid2=16022000
7692
7693         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7694         local MULTIPID1=$!
7695         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7696         local MULTIPID2=$!
7697         kill -USR1 $MULTIPID2
7698         sleep 2
7699         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7700                 error "First grouplock does not block second one"
7701         else
7702                 echo "Second grouplock blocks first one"
7703         fi
7704         kill -USR1 $MULTIPID1
7705         wait $MULTIPID1
7706         wait $MULTIPID2
7707 }
7708 run_test 82 "Basic grouplock test"
7709
7710 test_99() {
7711         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7712
7713         test_mkdir $DIR/$tdir.cvsroot
7714         chown $RUNAS_ID $DIR/$tdir.cvsroot
7715
7716         cd $TMP
7717         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7718
7719         cd /etc/init.d
7720         # some versions of cvs import exit(1) when asked to import links or
7721         # files they can't read.  ignore those files.
7722         local toignore=$(find . -type l -printf '-I %f\n' -o \
7723                          ! -perm /4 -printf '-I %f\n')
7724         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7725                 $tdir.reposname vtag rtag
7726
7727         cd $DIR
7728         test_mkdir $DIR/$tdir.reposname
7729         chown $RUNAS_ID $DIR/$tdir.reposname
7730         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7731
7732         cd $DIR/$tdir.reposname
7733         $RUNAS touch foo99
7734         $RUNAS cvs add -m 'addmsg' foo99
7735         $RUNAS cvs update
7736         $RUNAS cvs commit -m 'nomsg' foo99
7737         rm -fr $DIR/$tdir.cvsroot
7738 }
7739 run_test 99 "cvs strange file/directory operations"
7740
7741 test_100() {
7742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7743         [[ "$NETTYPE" =~ tcp ]] ||
7744                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7745         remote_ost_nodsh && skip "remote OST with nodsh"
7746         remote_mds_nodsh && skip "remote MDS with nodsh"
7747         remote_servers ||
7748                 skip "useless for local single node setup"
7749
7750         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7751                 [ "$PROT" != "tcp" ] && continue
7752                 RPORT=$(echo $REMOTE | cut -d: -f2)
7753                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7754
7755                 rc=0
7756                 LPORT=`echo $LOCAL | cut -d: -f2`
7757                 if [ $LPORT -ge 1024 ]; then
7758                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7759                         netstat -tna
7760                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7761                 fi
7762         done
7763         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7764 }
7765 run_test 100 "check local port using privileged port ==========="
7766
7767 function get_named_value()
7768 {
7769     local tag
7770
7771     tag=$1
7772     while read ;do
7773         line=$REPLY
7774         case $line in
7775         $tag*)
7776             echo $line | sed "s/^$tag[ ]*//"
7777             break
7778             ;;
7779         esac
7780     done
7781 }
7782
7783 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7784                    awk '/^max_cached_mb/ { print $2 }')
7785
7786 cleanup_101a() {
7787         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7788         trap 0
7789 }
7790
7791 test_101a() {
7792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7793         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7794
7795         local s
7796         local discard
7797         local nreads=10000
7798         local cache_limit=32
7799
7800         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7801         trap cleanup_101a EXIT
7802         $LCTL set_param -n llite.*.read_ahead_stats 0
7803         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7804
7805         #
7806         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7807         #
7808         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7809         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7810
7811         discard=0
7812         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7813                 get_named_value 'read but discarded' | cut -d" " -f1); do
7814                         discard=$(($discard + $s))
7815         done
7816         cleanup_101a
7817
7818         if [[ $(($discard * 10)) -gt $nreads ]]; then
7819                 $LCTL get_param osc.*-osc*.rpc_stats
7820                 $LCTL get_param llite.*.read_ahead_stats
7821                 error "too many ($discard) discarded pages"
7822         fi
7823         rm -f $DIR/$tfile || true
7824 }
7825 run_test 101a "check read-ahead for random reads"
7826
7827 setup_test101bc() {
7828         test_mkdir $DIR/$tdir
7829         local ssize=$1
7830         local FILE_LENGTH=$2
7831         STRIPE_OFFSET=0
7832
7833         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7834
7835         local list=$(comma_list $(osts_nodes))
7836         set_osd_param $list '' read_cache_enable 0
7837         set_osd_param $list '' writethrough_cache_enable 0
7838
7839         trap cleanup_test101bc EXIT
7840         # prepare the read-ahead file
7841         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7842
7843         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7844                                 count=$FILE_SIZE_MB 2> /dev/null
7845
7846 }
7847
7848 cleanup_test101bc() {
7849         trap 0
7850         rm -rf $DIR/$tdir
7851         rm -f $DIR/$tfile
7852
7853         local list=$(comma_list $(osts_nodes))
7854         set_osd_param $list '' read_cache_enable 1
7855         set_osd_param $list '' writethrough_cache_enable 1
7856 }
7857
7858 calc_total() {
7859         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7860 }
7861
7862 ra_check_101() {
7863         local READ_SIZE=$1
7864         local STRIPE_SIZE=$2
7865         local FILE_LENGTH=$3
7866         local RA_INC=1048576
7867         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7868         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7869                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7870         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7871                         get_named_value 'read but discarded' |
7872                         cut -d" " -f1 | calc_total)
7873         if [[ $DISCARD -gt $discard_limit ]]; then
7874                 $LCTL get_param llite.*.read_ahead_stats
7875                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7876         else
7877                 echo "Read-ahead success for size ${READ_SIZE}"
7878         fi
7879 }
7880
7881 test_101b() {
7882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7883         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7884
7885         local STRIPE_SIZE=1048576
7886         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7887
7888         if [ $SLOW == "yes" ]; then
7889                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7890         else
7891                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7892         fi
7893
7894         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7895
7896         # prepare the read-ahead file
7897         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7898         cancel_lru_locks osc
7899         for BIDX in 2 4 8 16 32 64 128 256
7900         do
7901                 local BSIZE=$((BIDX*4096))
7902                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7903                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7904                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7905                 $LCTL set_param -n llite.*.read_ahead_stats 0
7906                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7907                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7908                 cancel_lru_locks osc
7909                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7910         done
7911         cleanup_test101bc
7912         true
7913 }
7914 run_test 101b "check stride-io mode read-ahead ================="
7915
7916 test_101c() {
7917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7918
7919         local STRIPE_SIZE=1048576
7920         local FILE_LENGTH=$((STRIPE_SIZE*100))
7921         local nreads=10000
7922         local rsize=65536
7923         local osc_rpc_stats
7924
7925         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7926
7927         cancel_lru_locks osc
7928         $LCTL set_param osc.*.rpc_stats 0
7929         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7930         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7931                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7932                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7933                 local size
7934
7935                 if [ $lines -le 20 ]; then
7936                         continue
7937                 fi
7938                 for size in 1 2 4 8; do
7939                         local rpc=$(echo "$stats" |
7940                                     awk '($1 == "'$size':") {print $2; exit; }')
7941                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7942                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7943                 done
7944                 echo "$osc_rpc_stats check passed!"
7945         done
7946         cleanup_test101bc
7947         true
7948 }
7949 run_test 101c "check stripe_size aligned read-ahead ================="
7950
7951 set_read_ahead() {
7952         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7953         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7954 }
7955
7956 test_101d() {
7957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7958
7959         local file=$DIR/$tfile
7960         local sz_MB=${FILESIZE_101d:-500}
7961         local ra_MB=${READAHEAD_MB:-40}
7962
7963         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7964         [ $free_MB -lt $sz_MB ] &&
7965                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7966
7967         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7968         $LFS setstripe -c -1 $file || error "setstripe failed"
7969
7970         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7971         echo Cancel LRU locks on lustre client to flush the client cache
7972         cancel_lru_locks osc
7973
7974         echo Disable read-ahead
7975         local old_READAHEAD=$(set_read_ahead 0)
7976
7977         echo Reading the test file $file with read-ahead disabled
7978         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7979
7980         echo Cancel LRU locks on lustre client to flush the client cache
7981         cancel_lru_locks osc
7982         echo Enable read-ahead with ${ra_MB}MB
7983         set_read_ahead $ra_MB
7984
7985         echo Reading the test file $file with read-ahead enabled
7986         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7987
7988         echo "read-ahead disabled time read $raOFF"
7989         echo "read-ahead enabled  time read $raON"
7990
7991         set_read_ahead $old_READAHEAD
7992         rm -f $file
7993         wait_delete_completed
7994
7995         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
7996                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7997 }
7998 run_test 101d "file read with and without read-ahead enabled"
7999
8000 test_101e() {
8001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8002
8003         local file=$DIR/$tfile
8004         local size_KB=500  #KB
8005         local count=100
8006         local bsize=1024
8007
8008         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8009         local need_KB=$((count * size_KB))
8010         [[ $free_KB -le $need_KB ]] &&
8011                 skip_env "Need free space $need_KB, have $free_KB"
8012
8013         echo "Creating $count ${size_KB}K test files"
8014         for ((i = 0; i < $count; i++)); do
8015                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8016         done
8017
8018         echo "Cancel LRU locks on lustre client to flush the client cache"
8019         cancel_lru_locks $OSC
8020
8021         echo "Reset readahead stats"
8022         $LCTL set_param -n llite.*.read_ahead_stats 0
8023
8024         for ((i = 0; i < $count; i++)); do
8025                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8026         done
8027
8028         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8029                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8030
8031         for ((i = 0; i < $count; i++)); do
8032                 rm -rf $file.$i 2>/dev/null
8033         done
8034
8035         #10000 means 20% reads are missing in readahead
8036         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8037 }
8038 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8039
8040 test_101f() {
8041         which iozone || skip_env "no iozone installed"
8042
8043         local old_debug=$($LCTL get_param debug)
8044         old_debug=${old_debug#*=}
8045         $LCTL set_param debug="reada mmap"
8046
8047         # create a test file
8048         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8049
8050         echo Cancel LRU locks on lustre client to flush the client cache
8051         cancel_lru_locks osc
8052
8053         echo Reset readahead stats
8054         $LCTL set_param -n llite.*.read_ahead_stats 0
8055
8056         echo mmap read the file with small block size
8057         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8058                 > /dev/null 2>&1
8059
8060         echo checking missing pages
8061         $LCTL get_param llite.*.read_ahead_stats
8062         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8063                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8064
8065         $LCTL set_param debug="$old_debug"
8066         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8067         rm -f $DIR/$tfile
8068 }
8069 run_test 101f "check mmap read performance"
8070
8071 test_101g_brw_size_test() {
8072         local mb=$1
8073         local pages=$((mb * 1048576 / PAGE_SIZE))
8074         local file=$DIR/$tfile
8075
8076         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8077                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8078         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8079                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8080                         return 2
8081         done
8082
8083         stack_trap "rm -f $file" EXIT
8084         $LCTL set_param -n osc.*.rpc_stats=0
8085
8086         # 10 RPCs should be enough for the test
8087         local count=10
8088         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8089                 { error "dd write ${mb} MB blocks failed"; return 3; }
8090         cancel_lru_locks osc
8091         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8092                 { error "dd write ${mb} MB blocks failed"; return 4; }
8093
8094         # calculate number of full-sized read and write RPCs
8095         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8096                 sed -n '/pages per rpc/,/^$/p' |
8097                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8098                 END { print reads,writes }'))
8099         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8100                 return 5
8101         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8102                 return 6
8103
8104         return 0
8105 }
8106
8107 test_101g() {
8108         remote_ost_nodsh && skip "remote OST with nodsh"
8109
8110         local rpcs
8111         local osts=$(get_facets OST)
8112         local list=$(comma_list $(osts_nodes))
8113         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8114         local brw_size="obdfilter.*.brw_size"
8115
8116         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8117
8118         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8119
8120         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8121                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8122                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8123            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8124                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8125                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8126
8127                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8128                         suffix="M"
8129
8130                 if [[ $orig_mb -lt 16 ]]; then
8131                         save_lustre_params $osts "$brw_size" > $p
8132                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8133                                 error "set 16MB RPC size failed"
8134
8135                         echo "remount client to enable new RPC size"
8136                         remount_client $MOUNT || error "remount_client failed"
8137                 fi
8138
8139                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8140                 # should be able to set brw_size=12, but no rpc_stats for that
8141                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8142         fi
8143
8144         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8145
8146         if [[ $orig_mb -lt 16 ]]; then
8147                 restore_lustre_params < $p
8148                 remount_client $MOUNT || error "remount_client restore failed"
8149         fi
8150
8151         rm -f $p $DIR/$tfile
8152 }
8153 run_test 101g "Big bulk(4/16 MiB) readahead"
8154
8155 setup_test102() {
8156         test_mkdir $DIR/$tdir
8157         chown $RUNAS_ID $DIR/$tdir
8158         STRIPE_SIZE=65536
8159         STRIPE_OFFSET=1
8160         STRIPE_COUNT=$OSTCOUNT
8161         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8162
8163         trap cleanup_test102 EXIT
8164         cd $DIR
8165         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8166         cd $DIR/$tdir
8167         for num in 1 2 3 4; do
8168                 for count in $(seq 1 $STRIPE_COUNT); do
8169                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8170                                 local size=`expr $STRIPE_SIZE \* $num`
8171                                 local file=file"$num-$idx-$count"
8172                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8173                         done
8174                 done
8175         done
8176
8177         cd $DIR
8178         $1 tar cf $TMP/f102.tar $tdir --xattrs
8179 }
8180
8181 cleanup_test102() {
8182         trap 0
8183         rm -f $TMP/f102.tar
8184         rm -rf $DIR/d0.sanity/d102
8185 }
8186
8187 test_102a() {
8188         [ "$UID" != 0 ] && skip "must run as root"
8189         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8190                 skip_env "must have user_xattr"
8191
8192         [ -z "$(which setfattr 2>/dev/null)" ] &&
8193                 skip_env "could not find setfattr"
8194
8195         local testfile=$DIR/$tfile
8196
8197         touch $testfile
8198         echo "set/get xattr..."
8199         setfattr -n trusted.name1 -v value1 $testfile ||
8200                 error "setfattr -n trusted.name1=value1 $testfile failed"
8201         getfattr -n trusted.name1 $testfile 2> /dev/null |
8202           grep "trusted.name1=.value1" ||
8203                 error "$testfile missing trusted.name1=value1"
8204
8205         setfattr -n user.author1 -v author1 $testfile ||
8206                 error "setfattr -n user.author1=author1 $testfile failed"
8207         getfattr -n user.author1 $testfile 2> /dev/null |
8208           grep "user.author1=.author1" ||
8209                 error "$testfile missing trusted.author1=author1"
8210
8211         echo "listxattr..."
8212         setfattr -n trusted.name2 -v value2 $testfile ||
8213                 error "$testfile unable to set trusted.name2"
8214         setfattr -n trusted.name3 -v value3 $testfile ||
8215                 error "$testfile unable to set trusted.name3"
8216         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8217             grep "trusted.name" | wc -l) -eq 3 ] ||
8218                 error "$testfile missing 3 trusted.name xattrs"
8219
8220         setfattr -n user.author2 -v author2 $testfile ||
8221                 error "$testfile unable to set user.author2"
8222         setfattr -n user.author3 -v author3 $testfile ||
8223                 error "$testfile unable to set user.author3"
8224         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8225             grep "user.author" | wc -l) -eq 3 ] ||
8226                 error "$testfile missing 3 user.author xattrs"
8227
8228         echo "remove xattr..."
8229         setfattr -x trusted.name1 $testfile ||
8230                 error "$testfile error deleting trusted.name1"
8231         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8232                 error "$testfile did not delete trusted.name1 xattr"
8233
8234         setfattr -x user.author1 $testfile ||
8235                 error "$testfile error deleting user.author1"
8236         echo "set lustre special xattr ..."
8237         $LFS setstripe -c1 $testfile
8238         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8239                 awk -F "=" '/trusted.lov/ { print $2 }' )
8240         setfattr -n "trusted.lov" -v $lovea $testfile ||
8241                 error "$testfile doesn't ignore setting trusted.lov again"
8242         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8243                 error "$testfile allow setting invalid trusted.lov"
8244         rm -f $testfile
8245 }
8246 run_test 102a "user xattr test =================================="
8247
8248 test_102b() {
8249         [ -z "$(which setfattr 2>/dev/null)" ] &&
8250                 skip_env "could not find setfattr"
8251         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8252
8253         # b10930: get/set/list trusted.lov xattr
8254         echo "get/set/list trusted.lov xattr ..."
8255         local testfile=$DIR/$tfile
8256         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8257                 error "setstripe failed"
8258         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8259                 error "getstripe failed"
8260         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8261                 error "can't get trusted.lov from $testfile"
8262
8263         local testfile2=${testfile}2
8264         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8265                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8266
8267         $MCREATE $testfile2
8268         setfattr -n trusted.lov -v $value $testfile2
8269         local stripe_size=$($LFS getstripe -S $testfile2)
8270         local stripe_count=$($LFS getstripe -c $testfile2)
8271         [[ $stripe_size -eq 65536 ]] ||
8272                 error "stripe size $stripe_size != 65536"
8273         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8274                 error "stripe count $stripe_count != $STRIPECOUNT"
8275         rm -f $DIR/$tfile
8276 }
8277 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8278
8279 test_102c() {
8280         [ -z "$(which setfattr 2>/dev/null)" ] &&
8281                 skip_env "could not find setfattr"
8282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8283
8284         # b10930: get/set/list lustre.lov xattr
8285         echo "get/set/list lustre.lov xattr ..."
8286         test_mkdir $DIR/$tdir
8287         chown $RUNAS_ID $DIR/$tdir
8288         local testfile=$DIR/$tdir/$tfile
8289         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8290                 error "setstripe failed"
8291         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8292                 error "getstripe failed"
8293         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8294         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8295
8296         local testfile2=${testfile}2
8297         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8298                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8299
8300         $RUNAS $MCREATE $testfile2
8301         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8302         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8303         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8304         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8305         [ $stripe_count -eq $STRIPECOUNT ] ||
8306                 error "stripe count $stripe_count != $STRIPECOUNT"
8307 }
8308 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8309
8310 compare_stripe_info1() {
8311         local stripe_index_all_zero=true
8312
8313         for num in 1 2 3 4; do
8314                 for count in $(seq 1 $STRIPE_COUNT); do
8315                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8316                                 local size=$((STRIPE_SIZE * num))
8317                                 local file=file"$num-$offset-$count"
8318                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8319                                 [[ $stripe_size -ne $size ]] &&
8320                                     error "$file: size $stripe_size != $size"
8321                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8322                                 # allow fewer stripes to be created, ORI-601
8323                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8324                                     error "$file: count $stripe_count != $count"
8325                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8326                                 [[ $stripe_index -ne 0 ]] &&
8327                                         stripe_index_all_zero=false
8328                         done
8329                 done
8330         done
8331         $stripe_index_all_zero &&
8332                 error "all files are being extracted starting from OST index 0"
8333         return 0
8334 }
8335
8336 have_xattrs_include() {
8337         tar --help | grep -q xattrs-include &&
8338                 echo --xattrs-include="lustre.*"
8339 }
8340
8341 test_102d() {
8342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8343         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8344
8345         XINC=$(have_xattrs_include)
8346         setup_test102
8347         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8348         cd $DIR/$tdir/$tdir
8349         compare_stripe_info1
8350 }
8351 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8352
8353 test_102f() {
8354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8356
8357         XINC=$(have_xattrs_include)
8358         setup_test102
8359         test_mkdir $DIR/$tdir.restore
8360         cd $DIR
8361         tar cf - --xattrs $tdir | tar xf - \
8362                 -C $DIR/$tdir.restore --xattrs $XINC
8363         cd $DIR/$tdir.restore/$tdir
8364         compare_stripe_info1
8365 }
8366 run_test 102f "tar copy files, not keep osts"
8367
8368 grow_xattr() {
8369         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8370                 skip "must have user_xattr"
8371         [ -z "$(which setfattr 2>/dev/null)" ] &&
8372                 skip_env "could not find setfattr"
8373         [ -z "$(which getfattr 2>/dev/null)" ] &&
8374                 skip_env "could not find getfattr"
8375
8376         local xsize=${1:-1024}  # in bytes
8377         local file=$DIR/$tfile
8378         local value="$(generate_string $xsize)"
8379         local xbig=trusted.big
8380         local toobig=$2
8381
8382         touch $file
8383         log "save $xbig on $file"
8384         if [ -z "$toobig" ]
8385         then
8386                 setfattr -n $xbig -v $value $file ||
8387                         error "saving $xbig on $file failed"
8388         else
8389                 setfattr -n $xbig -v $value $file &&
8390                         error "saving $xbig on $file succeeded"
8391                 return 0
8392         fi
8393
8394         local orig=$(get_xattr_value $xbig $file)
8395         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8396
8397         local xsml=trusted.sml
8398         log "save $xsml on $file"
8399         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8400
8401         local new=$(get_xattr_value $xbig $file)
8402         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8403
8404         log "grow $xsml on $file"
8405         setfattr -n $xsml -v "$value" $file ||
8406                 error "growing $xsml on $file failed"
8407
8408         new=$(get_xattr_value $xbig $file)
8409         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8410         log "$xbig still valid after growing $xsml"
8411
8412         rm -f $file
8413 }
8414
8415 test_102h() { # bug 15777
8416         grow_xattr 1024
8417 }
8418 run_test 102h "grow xattr from inside inode to external block"
8419
8420 test_102ha() {
8421         large_xattr_enabled || skip_env "ea_inode feature disabled"
8422
8423         echo "setting xattr of max xattr size: $(max_xattr_size)"
8424         grow_xattr $(max_xattr_size)
8425
8426         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8427         echo "This should fail:"
8428         grow_xattr $(($(max_xattr_size) + 10)) 1
8429 }
8430 run_test 102ha "grow xattr from inside inode to external inode"
8431
8432 test_102i() { # bug 17038
8433         [ -z "$(which getfattr 2>/dev/null)" ] &&
8434                 skip "could not find getfattr"
8435
8436         touch $DIR/$tfile
8437         ln -s $DIR/$tfile $DIR/${tfile}link
8438         getfattr -n trusted.lov $DIR/$tfile ||
8439                 error "lgetxattr on $DIR/$tfile failed"
8440         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8441                 grep -i "no such attr" ||
8442                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8443         rm -f $DIR/$tfile $DIR/${tfile}link
8444 }
8445 run_test 102i "lgetxattr test on symbolic link ============"
8446
8447 test_102j() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8450
8451         XINC=$(have_xattrs_include)
8452         setup_test102 "$RUNAS"
8453         chown $RUNAS_ID $DIR/$tdir
8454         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8455         cd $DIR/$tdir/$tdir
8456         compare_stripe_info1 "$RUNAS"
8457 }
8458 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8459
8460 test_102k() {
8461         [ -z "$(which setfattr 2>/dev/null)" ] &&
8462                 skip "could not find setfattr"
8463
8464         touch $DIR/$tfile
8465         # b22187 just check that does not crash for regular file.
8466         setfattr -n trusted.lov $DIR/$tfile
8467         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8468         local test_kdir=$DIR/$tdir
8469         test_mkdir $test_kdir
8470         local default_size=$($LFS getstripe -S $test_kdir)
8471         local default_count=$($LFS getstripe -c $test_kdir)
8472         local default_offset=$($LFS getstripe -i $test_kdir)
8473         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8474                 error 'dir setstripe failed'
8475         setfattr -n trusted.lov $test_kdir
8476         local stripe_size=$($LFS getstripe -S $test_kdir)
8477         local stripe_count=$($LFS getstripe -c $test_kdir)
8478         local stripe_offset=$($LFS getstripe -i $test_kdir)
8479         [ $stripe_size -eq $default_size ] ||
8480                 error "stripe size $stripe_size != $default_size"
8481         [ $stripe_count -eq $default_count ] ||
8482                 error "stripe count $stripe_count != $default_count"
8483         [ $stripe_offset -eq $default_offset ] ||
8484                 error "stripe offset $stripe_offset != $default_offset"
8485         rm -rf $DIR/$tfile $test_kdir
8486 }
8487 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8488
8489 test_102l() {
8490         [ -z "$(which getfattr 2>/dev/null)" ] &&
8491                 skip "could not find getfattr"
8492
8493         # LU-532 trusted. xattr is invisible to non-root
8494         local testfile=$DIR/$tfile
8495
8496         touch $testfile
8497
8498         echo "listxattr as user..."
8499         chown $RUNAS_ID $testfile
8500         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8501             grep -q "trusted" &&
8502                 error "$testfile trusted xattrs are user visible"
8503
8504         return 0;
8505 }
8506 run_test 102l "listxattr size test =================================="
8507
8508 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8509         local path=$DIR/$tfile
8510         touch $path
8511
8512         listxattr_size_check $path || error "listattr_size_check $path failed"
8513 }
8514 run_test 102m "Ensure listxattr fails on small bufffer ========"
8515
8516 cleanup_test102
8517
8518 getxattr() { # getxattr path name
8519         # Return the base64 encoding of the value of xattr name on path.
8520         local path=$1
8521         local name=$2
8522
8523         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8524         # file: $path
8525         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8526         #
8527         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8528
8529         getfattr --absolute-names --encoding=base64 --name=$name $path |
8530                 awk -F= -v name=$name '$1 == name {
8531                         print substr($0, index($0, "=") + 1);
8532         }'
8533 }
8534
8535 test_102n() { # LU-4101 mdt: protect internal xattrs
8536         [ -z "$(which setfattr 2>/dev/null)" ] &&
8537                 skip "could not find setfattr"
8538         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8539         then
8540                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8541         fi
8542
8543         local file0=$DIR/$tfile.0
8544         local file1=$DIR/$tfile.1
8545         local xattr0=$TMP/$tfile.0
8546         local xattr1=$TMP/$tfile.1
8547         local namelist="lov lma lmv link fid version som hsm"
8548         local name
8549         local value
8550
8551         rm -rf $file0 $file1 $xattr0 $xattr1
8552         touch $file0 $file1
8553
8554         # Get 'before' xattrs of $file1.
8555         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8556
8557         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8558                 namelist+=" lfsck_namespace"
8559         for name in $namelist; do
8560                 # Try to copy xattr from $file0 to $file1.
8561                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8562
8563                 setfattr --name=trusted.$name --value="$value" $file1 ||
8564                         error "setxattr 'trusted.$name' failed"
8565
8566                 # Try to set a garbage xattr.
8567                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8568
8569                 if [[ x$name == "xlov" ]]; then
8570                         setfattr --name=trusted.lov --value="$value" $file1 &&
8571                         error "setxattr invalid 'trusted.lov' success"
8572                 else
8573                         setfattr --name=trusted.$name --value="$value" $file1 ||
8574                                 error "setxattr invalid 'trusted.$name' failed"
8575                 fi
8576
8577                 # Try to remove the xattr from $file1. We don't care if this
8578                 # appears to succeed or fail, we just don't want there to be
8579                 # any changes or crashes.
8580                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8581         done
8582
8583         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8584         then
8585                 name="lfsck_ns"
8586                 # Try to copy xattr from $file0 to $file1.
8587                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8588
8589                 setfattr --name=trusted.$name --value="$value" $file1 ||
8590                         error "setxattr 'trusted.$name' failed"
8591
8592                 # Try to set a garbage xattr.
8593                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8594
8595                 setfattr --name=trusted.$name --value="$value" $file1 ||
8596                         error "setxattr 'trusted.$name' failed"
8597
8598                 # Try to remove the xattr from $file1. We don't care if this
8599                 # appears to succeed or fail, we just don't want there to be
8600                 # any changes or crashes.
8601                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8602         fi
8603
8604         # Get 'after' xattrs of file1.
8605         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8606
8607         if ! diff $xattr0 $xattr1; then
8608                 error "before and after xattrs of '$file1' differ"
8609         fi
8610
8611         rm -rf $file0 $file1 $xattr0 $xattr1
8612
8613         return 0
8614 }
8615 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8616
8617 test_102p() { # LU-4703 setxattr did not check ownership
8618         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8619                 skip "MDS needs to be at least 2.5.56"
8620
8621         local testfile=$DIR/$tfile
8622
8623         touch $testfile
8624
8625         echo "setfacl as user..."
8626         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8627         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8628
8629         echo "setfattr as user..."
8630         setfacl -m "u:$RUNAS_ID:---" $testfile
8631         $RUNAS setfattr -x system.posix_acl_access $testfile
8632         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8633 }
8634 run_test 102p "check setxattr(2) correctly fails without permission"
8635
8636 test_102q() {
8637         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8638                 skip "MDS needs to be at least 2.6.92"
8639
8640         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8641 }
8642 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8643
8644 test_102r() {
8645         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8646                 skip "MDS needs to be at least 2.6.93"
8647
8648         touch $DIR/$tfile || error "touch"
8649         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8650         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8651         rm $DIR/$tfile || error "rm"
8652
8653         #normal directory
8654         mkdir -p $DIR/$tdir || error "mkdir"
8655         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8656         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8657         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8658                 error "$testfile error deleting user.author1"
8659         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8660                 grep "user.$(basename $tdir)" &&
8661                 error "$tdir did not delete user.$(basename $tdir)"
8662         rmdir $DIR/$tdir || error "rmdir"
8663
8664         #striped directory
8665         test_mkdir $DIR/$tdir
8666         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8667         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8668         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8669                 error "$testfile error deleting user.author1"
8670         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8671                 grep "user.$(basename $tdir)" &&
8672                 error "$tdir did not delete user.$(basename $tdir)"
8673         rmdir $DIR/$tdir || error "rm striped dir"
8674 }
8675 run_test 102r "set EAs with empty values"
8676
8677 test_102s() {
8678         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8679                 skip "MDS needs to be at least 2.11.52"
8680
8681         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8682
8683         save_lustre_params client "llite.*.xattr_cache" > $save
8684
8685         for cache in 0 1; do
8686                 lctl set_param llite.*.xattr_cache=$cache
8687
8688                 rm -f $DIR/$tfile
8689                 touch $DIR/$tfile || error "touch"
8690                 for prefix in lustre security system trusted user; do
8691                         # Note getxattr() may fail with 'Operation not
8692                         # supported' or 'No such attribute' depending
8693                         # on prefix and cache.
8694                         getfattr -n $prefix.n102s $DIR/$tfile &&
8695                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8696                 done
8697         done
8698
8699         restore_lustre_params < $save
8700 }
8701 run_test 102s "getting nonexistent xattrs should fail"
8702
8703 test_102t() {
8704         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8705                 skip "MDS needs to be at least 2.11.52"
8706
8707         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8708
8709         save_lustre_params client "llite.*.xattr_cache" > $save
8710
8711         for cache in 0 1; do
8712                 lctl set_param llite.*.xattr_cache=$cache
8713
8714                 for buf_size in 0 256; do
8715                         rm -f $DIR/$tfile
8716                         touch $DIR/$tfile || error "touch"
8717                         setfattr -n user.multiop $DIR/$tfile
8718                         $MULTIOP $DIR/$tfile oa$buf_size ||
8719                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8720                 done
8721         done
8722
8723         restore_lustre_params < $save
8724 }
8725 run_test 102t "zero length xattr values handled correctly"
8726
8727 run_acl_subtest()
8728 {
8729     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8730     return $?
8731 }
8732
8733 test_103a() {
8734         [ "$UID" != 0 ] && skip "must run as root"
8735         $GSS && skip_env "could not run under gss"
8736         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8737                 skip_env "must have acl enabled"
8738         [ -z "$(which setfacl 2>/dev/null)" ] &&
8739                 skip_env "could not find setfacl"
8740         remote_mds_nodsh && skip "remote MDS with nodsh"
8741
8742         gpasswd -a daemon bin                           # LU-5641
8743         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8744
8745         declare -a identity_old
8746
8747         for num in $(seq $MDSCOUNT); do
8748                 switch_identity $num true || identity_old[$num]=$?
8749         done
8750
8751         SAVE_UMASK=$(umask)
8752         umask 0022
8753         mkdir -p $DIR/$tdir
8754         cd $DIR/$tdir
8755
8756         echo "performing cp ..."
8757         run_acl_subtest cp || error "run_acl_subtest cp failed"
8758         echo "performing getfacl-noacl..."
8759         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8760         echo "performing misc..."
8761         run_acl_subtest misc || error  "misc test failed"
8762         echo "performing permissions..."
8763         run_acl_subtest permissions || error "permissions failed"
8764         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8765         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8766                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8767                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8768         then
8769                 echo "performing permissions xattr..."
8770                 run_acl_subtest permissions_xattr ||
8771                         error "permissions_xattr failed"
8772         fi
8773         echo "performing setfacl..."
8774         run_acl_subtest setfacl || error  "setfacl test failed"
8775
8776         # inheritance test got from HP
8777         echo "performing inheritance..."
8778         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8779         chmod +x make-tree || error "chmod +x failed"
8780         run_acl_subtest inheritance || error "inheritance test failed"
8781         rm -f make-tree
8782
8783         echo "LU-974 ignore umask when acl is enabled..."
8784         run_acl_subtest 974 || error "LU-974 umask test failed"
8785         if [ $MDSCOUNT -ge 2 ]; then
8786                 run_acl_subtest 974_remote ||
8787                         error "LU-974 umask test failed under remote dir"
8788         fi
8789
8790         echo "LU-2561 newly created file is same size as directory..."
8791         if [ "$mds1_FSTYPE" != "zfs" ]; then
8792                 run_acl_subtest 2561 || error "LU-2561 test failed"
8793         else
8794                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8795         fi
8796
8797         run_acl_subtest 4924 || error "LU-4924 test failed"
8798
8799         cd $SAVE_PWD
8800         umask $SAVE_UMASK
8801
8802         for num in $(seq $MDSCOUNT); do
8803                 if [ "${identity_old[$num]}" = 1 ]; then
8804                         switch_identity $num false || identity_old[$num]=$?
8805                 fi
8806         done
8807 }
8808 run_test 103a "acl test"
8809
8810 test_103b() {
8811         declare -a pids
8812         local U
8813
8814         for U in {0..511}; do
8815                 {
8816                 local O=$(printf "%04o" $U)
8817
8818                 umask $(printf "%04o" $((511 ^ $O)))
8819                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8820                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8821
8822                 (( $S == ($O & 0666) )) ||
8823                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8824
8825                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8826                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8827                 (( $S == ($O & 0666) )) ||
8828                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8829
8830                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8831                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8832                 (( $S == ($O & 0666) )) ||
8833                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8834                 rm -f $DIR/$tfile.[smp]$0
8835                 } &
8836                 local pid=$!
8837
8838                 # limit the concurrently running threads to 64. LU-11878
8839                 local idx=$((U % 64))
8840                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8841                 pids[idx]=$pid
8842         done
8843         wait
8844 }
8845 run_test 103b "umask lfs setstripe"
8846
8847 test_103c() {
8848         mkdir -p $DIR/$tdir
8849         cp -rp $DIR/$tdir $DIR/$tdir.bak
8850
8851         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8852                 error "$DIR/$tdir shouldn't contain default ACL"
8853         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8854                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8855         true
8856 }
8857 run_test 103c "'cp -rp' won't set empty acl"
8858
8859 test_104a() {
8860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8861
8862         touch $DIR/$tfile
8863         lfs df || error "lfs df failed"
8864         lfs df -ih || error "lfs df -ih failed"
8865         lfs df -h $DIR || error "lfs df -h $DIR failed"
8866         lfs df -i $DIR || error "lfs df -i $DIR failed"
8867         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8868         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8869
8870         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8871         lctl --device %$OSC deactivate
8872         lfs df || error "lfs df with deactivated OSC failed"
8873         lctl --device %$OSC activate
8874         # wait the osc back to normal
8875         wait_osc_import_ready client ost
8876
8877         lfs df || error "lfs df with reactivated OSC failed"
8878         rm -f $DIR/$tfile
8879 }
8880 run_test 104a "lfs df [-ih] [path] test ========================="
8881
8882 test_104b() {
8883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8884         [ $RUNAS_ID -eq $UID ] &&
8885                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8886
8887         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8888                         grep "Permission denied" | wc -l)))
8889         if [ $denied_cnt -ne 0 ]; then
8890                 error "lfs check servers test failed"
8891         fi
8892 }
8893 run_test 104b "$RUNAS lfs check servers test ===================="
8894
8895 test_105a() {
8896         # doesn't work on 2.4 kernels
8897         touch $DIR/$tfile
8898         if $(flock_is_enabled); then
8899                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8900         else
8901                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8902         fi
8903         rm -f $DIR/$tfile
8904 }
8905 run_test 105a "flock when mounted without -o flock test ========"
8906
8907 test_105b() {
8908         touch $DIR/$tfile
8909         if $(flock_is_enabled); then
8910                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8911         else
8912                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8913         fi
8914         rm -f $DIR/$tfile
8915 }
8916 run_test 105b "fcntl when mounted without -o flock test ========"
8917
8918 test_105c() {
8919         touch $DIR/$tfile
8920         if $(flock_is_enabled); then
8921                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8922         else
8923                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8924         fi
8925         rm -f $DIR/$tfile
8926 }
8927 run_test 105c "lockf when mounted without -o flock test"
8928
8929 test_105d() { # bug 15924
8930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8931
8932         test_mkdir $DIR/$tdir
8933         flock_is_enabled || skip_env "mount w/o flock enabled"
8934         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8935         $LCTL set_param fail_loc=0x80000315
8936         flocks_test 2 $DIR/$tdir
8937 }
8938 run_test 105d "flock race (should not freeze) ========"
8939
8940 test_105e() { # bug 22660 && 22040
8941         flock_is_enabled || skip_env "mount w/o flock enabled"
8942
8943         touch $DIR/$tfile
8944         flocks_test 3 $DIR/$tfile
8945 }
8946 run_test 105e "Two conflicting flocks from same process"
8947
8948 test_106() { #bug 10921
8949         test_mkdir $DIR/$tdir
8950         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8951         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8952 }
8953 run_test 106 "attempt exec of dir followed by chown of that dir"
8954
8955 test_107() {
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957
8958         CDIR=`pwd`
8959         local file=core
8960
8961         cd $DIR
8962         rm -f $file
8963
8964         local save_pattern=$(sysctl -n kernel.core_pattern)
8965         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8966         sysctl -w kernel.core_pattern=$file
8967         sysctl -w kernel.core_uses_pid=0
8968
8969         ulimit -c unlimited
8970         sleep 60 &
8971         SLEEPPID=$!
8972
8973         sleep 1
8974
8975         kill -s 11 $SLEEPPID
8976         wait $SLEEPPID
8977         if [ -e $file ]; then
8978                 size=`stat -c%s $file`
8979                 [ $size -eq 0 ] && error "Fail to create core file $file"
8980         else
8981                 error "Fail to create core file $file"
8982         fi
8983         rm -f $file
8984         sysctl -w kernel.core_pattern=$save_pattern
8985         sysctl -w kernel.core_uses_pid=$save_uses_pid
8986         cd $CDIR
8987 }
8988 run_test 107 "Coredump on SIG"
8989
8990 test_110() {
8991         test_mkdir $DIR/$tdir
8992         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8993         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8994                 error "mkdir with 256 char should fail, but did not"
8995         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8996                 error "create with 255 char failed"
8997         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8998                 error "create with 256 char should fail, but did not"
8999
9000         ls -l $DIR/$tdir
9001         rm -rf $DIR/$tdir
9002 }
9003 run_test 110 "filename length checking"
9004
9005 #
9006 # Purpose: To verify dynamic thread (OSS) creation.
9007 #
9008 test_115() {
9009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9010         remote_ost_nodsh && skip "remote OST with nodsh"
9011
9012         # Lustre does not stop service threads once they are started.
9013         # Reset number of running threads to default.
9014         stopall
9015         setupall
9016
9017         local OSTIO_pre
9018         local save_params="$TMP/sanity-$TESTNAME.parameters"
9019
9020         # Get ll_ost_io count before I/O
9021         OSTIO_pre=$(do_facet ost1 \
9022                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9023         # Exit if lustre is not running (ll_ost_io not running).
9024         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9025
9026         echo "Starting with $OSTIO_pre threads"
9027         local thread_max=$((OSTIO_pre * 2))
9028         local rpc_in_flight=$((thread_max * 2))
9029         # Number of I/O Process proposed to be started.
9030         local nfiles
9031         local facets=$(get_facets OST)
9032
9033         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9034         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9035
9036         # Set in_flight to $rpc_in_flight
9037         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9038                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9039         nfiles=${rpc_in_flight}
9040         # Set ost thread_max to $thread_max
9041         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9042
9043         # 5 Minutes should be sufficient for max number of OSS
9044         # threads(thread_max) to be created.
9045         local timeout=300
9046
9047         # Start I/O.
9048         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9049         test_mkdir $DIR/$tdir
9050         for i in $(seq $nfiles); do
9051                 local file=$DIR/$tdir/${tfile}-$i
9052                 $LFS setstripe -c -1 -i 0 $file
9053                 ($WTL $file $timeout)&
9054         done
9055
9056         # I/O Started - Wait for thread_started to reach thread_max or report
9057         # error if thread_started is more than thread_max.
9058         echo "Waiting for thread_started to reach thread_max"
9059         local thread_started=0
9060         local end_time=$((SECONDS + timeout))
9061
9062         while [ $SECONDS -le $end_time ] ; do
9063                 echo -n "."
9064                 # Get ost i/o thread_started count.
9065                 thread_started=$(do_facet ost1 \
9066                         "$LCTL get_param \
9067                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9068                 # Break out if thread_started is equal/greater than thread_max
9069                 if [[ $thread_started -ge $thread_max ]]; then
9070                         echo ll_ost_io thread_started $thread_started, \
9071                                 equal/greater than thread_max $thread_max
9072                         break
9073                 fi
9074                 sleep 1
9075         done
9076
9077         # Cleanup - We have the numbers, Kill i/o jobs if running.
9078         jobcount=($(jobs -p))
9079         for i in $(seq 0 $((${#jobcount[@]}-1)))
9080         do
9081                 kill -9 ${jobcount[$i]}
9082                 if [ $? -ne 0 ] ; then
9083                         echo Warning: \
9084                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9085                 fi
9086         done
9087
9088         # Cleanup files left by WTL binary.
9089         for i in $(seq $nfiles); do
9090                 local file=$DIR/$tdir/${tfile}-$i
9091                 rm -rf $file
9092                 if [ $? -ne 0 ] ; then
9093                         echo "Warning: Failed to delete file $file"
9094                 fi
9095         done
9096
9097         restore_lustre_params <$save_params
9098         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9099
9100         # Error out if no new thread has started or Thread started is greater
9101         # than thread max.
9102         if [[ $thread_started -le $OSTIO_pre ||
9103                         $thread_started -gt $thread_max ]]; then
9104                 error "ll_ost_io: thread_started $thread_started" \
9105                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9106                       "No new thread started or thread started greater " \
9107                       "than thread_max."
9108         fi
9109 }
9110 run_test 115 "verify dynamic thread creation===================="
9111
9112 free_min_max () {
9113         wait_delete_completed
9114         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9115         echo "OST kbytes available: ${AVAIL[@]}"
9116         MAXV=${AVAIL[0]}
9117         MAXI=0
9118         MINV=${AVAIL[0]}
9119         MINI=0
9120         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9121                 #echo OST $i: ${AVAIL[i]}kb
9122                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9123                         MAXV=${AVAIL[i]}
9124                         MAXI=$i
9125                 fi
9126                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9127                         MINV=${AVAIL[i]}
9128                         MINI=$i
9129                 fi
9130         done
9131         echo "Min free space: OST $MINI: $MINV"
9132         echo "Max free space: OST $MAXI: $MAXV"
9133 }
9134
9135 test_116a() { # was previously test_116()
9136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9137         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9138         remote_mds_nodsh && skip "remote MDS with nodsh"
9139
9140         echo -n "Free space priority "
9141         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9142                 head -n1
9143         declare -a AVAIL
9144         free_min_max
9145
9146         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9147         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9148         trap simple_cleanup_common EXIT
9149
9150         # Check if we need to generate uneven OSTs
9151         test_mkdir -p $DIR/$tdir/OST${MINI}
9152         local FILL=$((MINV / 4))
9153         local DIFF=$((MAXV - MINV))
9154         local DIFF2=$((DIFF * 100 / MINV))
9155
9156         local threshold=$(do_facet $SINGLEMDS \
9157                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9158         threshold=${threshold%%%}
9159         echo -n "Check for uneven OSTs: "
9160         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9161
9162         if [[ $DIFF2 -gt $threshold ]]; then
9163                 echo "ok"
9164                 echo "Don't need to fill OST$MINI"
9165         else
9166                 # generate uneven OSTs. Write 2% over the QOS threshold value
9167                 echo "no"
9168                 DIFF=$((threshold - DIFF2 + 2))
9169                 DIFF2=$((MINV * DIFF / 100))
9170                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9171                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9172                         error "setstripe failed"
9173                 DIFF=$((DIFF2 / 2048))
9174                 i=0
9175                 while [ $i -lt $DIFF ]; do
9176                         i=$((i + 1))
9177                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9178                                 bs=2M count=1 2>/dev/null
9179                         echo -n .
9180                 done
9181                 echo .
9182                 sync
9183                 sleep_maxage
9184                 free_min_max
9185         fi
9186
9187         DIFF=$((MAXV - MINV))
9188         DIFF2=$((DIFF * 100 / MINV))
9189         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9190         if [ $DIFF2 -gt $threshold ]; then
9191                 echo "ok"
9192         else
9193                 echo "failed - QOS mode won't be used"
9194                 simple_cleanup_common
9195                 skip "QOS imbalance criteria not met"
9196         fi
9197
9198         MINI1=$MINI
9199         MINV1=$MINV
9200         MAXI1=$MAXI
9201         MAXV1=$MAXV
9202
9203         # now fill using QOS
9204         $LFS setstripe -c 1 $DIR/$tdir
9205         FILL=$((FILL / 200))
9206         if [ $FILL -gt 600 ]; then
9207                 FILL=600
9208         fi
9209         echo "writing $FILL files to QOS-assigned OSTs"
9210         i=0
9211         while [ $i -lt $FILL ]; do
9212                 i=$((i + 1))
9213                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9214                         count=1 2>/dev/null
9215                 echo -n .
9216         done
9217         echo "wrote $i 200k files"
9218         sync
9219         sleep_maxage
9220
9221         echo "Note: free space may not be updated, so measurements might be off"
9222         free_min_max
9223         DIFF2=$((MAXV - MINV))
9224         echo "free space delta: orig $DIFF final $DIFF2"
9225         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9226         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9227         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9228         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9229         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9230         if [[ $DIFF -gt 0 ]]; then
9231                 FILL=$((DIFF2 * 100 / DIFF - 100))
9232                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9233         fi
9234
9235         # Figure out which files were written where
9236         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9237                awk '/'$MINI1': / {print $2; exit}')
9238         echo $UUID
9239         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9240         echo "$MINC files created on smaller OST $MINI1"
9241         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9242                awk '/'$MAXI1': / {print $2; exit}')
9243         echo $UUID
9244         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9245         echo "$MAXC files created on larger OST $MAXI1"
9246         if [[ $MINC -gt 0 ]]; then
9247                 FILL=$((MAXC * 100 / MINC - 100))
9248                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9249         fi
9250         [[ $MAXC -gt $MINC ]] ||
9251                 error_ignore LU-9 "stripe QOS didn't balance free space"
9252         simple_cleanup_common
9253 }
9254 run_test 116a "stripe QOS: free space balance ==================="
9255
9256 test_116b() { # LU-2093
9257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9258         remote_mds_nodsh && skip "remote MDS with nodsh"
9259
9260 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9261         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9262                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9263         [ -z "$old_rr" ] && skip "no QOS"
9264         do_facet $SINGLEMDS lctl set_param \
9265                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9266         mkdir -p $DIR/$tdir
9267         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9268         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9269         do_facet $SINGLEMDS lctl set_param fail_loc=0
9270         rm -rf $DIR/$tdir
9271         do_facet $SINGLEMDS lctl set_param \
9272                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9273 }
9274 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9275
9276 test_117() # bug 10891
9277 {
9278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9279
9280         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9281         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9282         lctl set_param fail_loc=0x21e
9283         > $DIR/$tfile || error "truncate failed"
9284         lctl set_param fail_loc=0
9285         echo "Truncate succeeded."
9286         rm -f $DIR/$tfile
9287 }
9288 run_test 117 "verify osd extend =========="
9289
9290 NO_SLOW_RESENDCOUNT=4
9291 export OLD_RESENDCOUNT=""
9292 set_resend_count () {
9293         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9294         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9295         lctl set_param -n $PROC_RESENDCOUNT $1
9296         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9297 }
9298
9299 # for reduce test_118* time (b=14842)
9300 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9301
9302 # Reset async IO behavior after error case
9303 reset_async() {
9304         FILE=$DIR/reset_async
9305
9306         # Ensure all OSCs are cleared
9307         $LFS setstripe -c -1 $FILE
9308         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9309         sync
9310         rm $FILE
9311 }
9312
9313 test_118a() #bug 11710
9314 {
9315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9316
9317         reset_async
9318
9319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9320         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9321         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9322
9323         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9324                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9325                 return 1;
9326         fi
9327         rm -f $DIR/$tfile
9328 }
9329 run_test 118a "verify O_SYNC works =========="
9330
9331 test_118b()
9332 {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334         remote_ost_nodsh && skip "remote OST with nodsh"
9335
9336         reset_async
9337
9338         #define OBD_FAIL_SRV_ENOENT 0x217
9339         set_nodes_failloc "$(osts_nodes)" 0x217
9340         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9341         RC=$?
9342         set_nodes_failloc "$(osts_nodes)" 0
9343         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9344         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9345                     grep -c writeback)
9346
9347         if [[ $RC -eq 0 ]]; then
9348                 error "Must return error due to dropped pages, rc=$RC"
9349                 return 1;
9350         fi
9351
9352         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9353                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9354                 return 1;
9355         fi
9356
9357         echo "Dirty pages not leaked on ENOENT"
9358
9359         # Due to the above error the OSC will issue all RPCs syncronously
9360         # until a subsequent RPC completes successfully without error.
9361         $MULTIOP $DIR/$tfile Ow4096yc
9362         rm -f $DIR/$tfile
9363
9364         return 0
9365 }
9366 run_test 118b "Reclaim dirty pages on fatal error =========="
9367
9368 test_118c()
9369 {
9370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9371
9372         # for 118c, restore the original resend count, LU-1940
9373         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9374                                 set_resend_count $OLD_RESENDCOUNT
9375         remote_ost_nodsh && skip "remote OST with nodsh"
9376
9377         reset_async
9378
9379         #define OBD_FAIL_OST_EROFS               0x216
9380         set_nodes_failloc "$(osts_nodes)" 0x216
9381
9382         # multiop should block due to fsync until pages are written
9383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9384         MULTIPID=$!
9385         sleep 1
9386
9387         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9388                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9389         fi
9390
9391         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9392                     grep -c writeback)
9393         if [[ $WRITEBACK -eq 0 ]]; then
9394                 error "No page in writeback, writeback=$WRITEBACK"
9395         fi
9396
9397         set_nodes_failloc "$(osts_nodes)" 0
9398         wait $MULTIPID
9399         RC=$?
9400         if [[ $RC -ne 0 ]]; then
9401                 error "Multiop fsync failed, rc=$RC"
9402         fi
9403
9404         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9405         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9406                     grep -c writeback)
9407         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9408                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9409         fi
9410
9411         rm -f $DIR/$tfile
9412         echo "Dirty pages flushed via fsync on EROFS"
9413         return 0
9414 }
9415 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9416
9417 # continue to use small resend count to reduce test_118* time (b=14842)
9418 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9419
9420 test_118d()
9421 {
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423         remote_ost_nodsh && skip "remote OST with nodsh"
9424
9425         reset_async
9426
9427         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9428         set_nodes_failloc "$(osts_nodes)" 0x214
9429         # multiop should block due to fsync until pages are written
9430         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9431         MULTIPID=$!
9432         sleep 1
9433
9434         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9435                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9436         fi
9437
9438         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9439                     grep -c writeback)
9440         if [[ $WRITEBACK -eq 0 ]]; then
9441                 error "No page in writeback, writeback=$WRITEBACK"
9442         fi
9443
9444         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9445         set_nodes_failloc "$(osts_nodes)" 0
9446
9447         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9448         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9449                     grep -c writeback)
9450         if [[ $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 "Dirty pages gaurenteed flushed via fsync"
9456         return 0
9457 }
9458 run_test 118d "Fsync validation inject a delay of the bulk =========="
9459
9460 test_118f() {
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462
9463         reset_async
9464
9465         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9466         lctl set_param fail_loc=0x8000040a
9467
9468         # Should simulate EINVAL error which is fatal
9469         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9470         RC=$?
9471         if [[ $RC -eq 0 ]]; then
9472                 error "Must return error due to dropped pages, rc=$RC"
9473         fi
9474
9475         lctl set_param fail_loc=0x0
9476
9477         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9480                     grep -c writeback)
9481         if [[ $LOCKED -ne 0 ]]; then
9482                 error "Locked pages remain in cache, locked=$LOCKED"
9483         fi
9484
9485         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9486                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9487         fi
9488
9489         rm -f $DIR/$tfile
9490         echo "No pages locked after fsync"
9491
9492         reset_async
9493         return 0
9494 }
9495 run_test 118f "Simulate unrecoverable OSC side error =========="
9496
9497 test_118g() {
9498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9499
9500         reset_async
9501
9502         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9503         lctl set_param fail_loc=0x406
9504
9505         # simulate local -ENOMEM
9506         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9507         RC=$?
9508
9509         lctl set_param fail_loc=0
9510         if [[ $RC -eq 0 ]]; then
9511                 error "Must return error due to dropped pages, rc=$RC"
9512         fi
9513
9514         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9515         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9516         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9517                         grep -c writeback)
9518         if [[ $LOCKED -ne 0 ]]; then
9519                 error "Locked pages remain in cache, locked=$LOCKED"
9520         fi
9521
9522         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9523                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9524         fi
9525
9526         rm -f $DIR/$tfile
9527         echo "No pages locked after fsync"
9528
9529         reset_async
9530         return 0
9531 }
9532 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9533
9534 test_118h() {
9535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9536         remote_ost_nodsh && skip "remote OST with nodsh"
9537
9538         reset_async
9539
9540         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9541         set_nodes_failloc "$(osts_nodes)" 0x20e
9542         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9543         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9544         RC=$?
9545
9546         set_nodes_failloc "$(osts_nodes)" 0
9547         if [[ $RC -eq 0 ]]; then
9548                 error "Must return error due to dropped pages, rc=$RC"
9549         fi
9550
9551         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9552         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9553         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9554                     grep -c writeback)
9555         if [[ $LOCKED -ne 0 ]]; then
9556                 error "Locked pages remain in cache, locked=$LOCKED"
9557         fi
9558
9559         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9560                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9561         fi
9562
9563         rm -f $DIR/$tfile
9564         echo "No pages locked after fsync"
9565
9566         return 0
9567 }
9568 run_test 118h "Verify timeout in handling recoverables errors  =========="
9569
9570 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9571
9572 test_118i() {
9573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9574         remote_ost_nodsh && skip "remote OST with nodsh"
9575
9576         reset_async
9577
9578         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9579         set_nodes_failloc "$(osts_nodes)" 0x20e
9580
9581         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9582         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9583         PID=$!
9584         sleep 5
9585         set_nodes_failloc "$(osts_nodes)" 0
9586
9587         wait $PID
9588         RC=$?
9589         if [[ $RC -ne 0 ]]; then
9590                 error "got error, but should be not, rc=$RC"
9591         fi
9592
9593         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9594         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9595         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9596         if [[ $LOCKED -ne 0 ]]; then
9597                 error "Locked pages remain in cache, locked=$LOCKED"
9598         fi
9599
9600         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9601                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9602         fi
9603
9604         rm -f $DIR/$tfile
9605         echo "No pages locked after fsync"
9606
9607         return 0
9608 }
9609 run_test 118i "Fix error before timeout in recoverable error  =========="
9610
9611 [ "$SLOW" = "no" ] && set_resend_count 4
9612
9613 test_118j() {
9614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9615         remote_ost_nodsh && skip "remote OST with nodsh"
9616
9617         reset_async
9618
9619         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9620         set_nodes_failloc "$(osts_nodes)" 0x220
9621
9622         # return -EIO from OST
9623         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9624         RC=$?
9625         set_nodes_failloc "$(osts_nodes)" 0x0
9626         if [[ $RC -eq 0 ]]; then
9627                 error "Must return error due to dropped pages, rc=$RC"
9628         fi
9629
9630         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9631         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9632         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9633         if [[ $LOCKED -ne 0 ]]; then
9634                 error "Locked pages remain in cache, locked=$LOCKED"
9635         fi
9636
9637         # in recoverable error on OST we want resend and stay until it finished
9638         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9639                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9640         fi
9641
9642         rm -f $DIR/$tfile
9643         echo "No pages locked after fsync"
9644
9645         return 0
9646 }
9647 run_test 118j "Simulate unrecoverable OST side error =========="
9648
9649 test_118k()
9650 {
9651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9652         remote_ost_nodsh && skip "remote OSTs with nodsh"
9653
9654         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9655         set_nodes_failloc "$(osts_nodes)" 0x20e
9656         test_mkdir $DIR/$tdir
9657
9658         for ((i=0;i<10;i++)); do
9659                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9660                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9661                 SLEEPPID=$!
9662                 sleep 0.500s
9663                 kill $SLEEPPID
9664                 wait $SLEEPPID
9665         done
9666
9667         set_nodes_failloc "$(osts_nodes)" 0
9668         rm -rf $DIR/$tdir
9669 }
9670 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9671
9672 test_118l() # LU-646
9673 {
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675
9676         test_mkdir $DIR/$tdir
9677         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9678         rm -rf $DIR/$tdir
9679 }
9680 run_test 118l "fsync dir"
9681
9682 test_118m() # LU-3066
9683 {
9684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9685
9686         test_mkdir $DIR/$tdir
9687         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9688         rm -rf $DIR/$tdir
9689 }
9690 run_test 118m "fdatasync dir ========="
9691
9692 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9693
9694 test_118n()
9695 {
9696         local begin
9697         local end
9698
9699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9700         remote_ost_nodsh && skip "remote OSTs with nodsh"
9701
9702         # Sleep to avoid a cached response.
9703         #define OBD_STATFS_CACHE_SECONDS 1
9704         sleep 2
9705
9706         # Inject a 10 second delay in the OST_STATFS handler.
9707         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9708         set_nodes_failloc "$(osts_nodes)" 0x242
9709
9710         begin=$SECONDS
9711         stat --file-system $MOUNT > /dev/null
9712         end=$SECONDS
9713
9714         set_nodes_failloc "$(osts_nodes)" 0
9715
9716         if ((end - begin > 20)); then
9717             error "statfs took $((end - begin)) seconds, expected 10"
9718         fi
9719 }
9720 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9721
9722 test_119a() # bug 11737
9723 {
9724         BSIZE=$((512 * 1024))
9725         directio write $DIR/$tfile 0 1 $BSIZE
9726         # We ask to read two blocks, which is more than a file size.
9727         # directio will indicate an error when requested and actual
9728         # sizes aren't equeal (a normal situation in this case) and
9729         # print actual read amount.
9730         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9731         if [ "$NOB" != "$BSIZE" ]; then
9732                 error "read $NOB bytes instead of $BSIZE"
9733         fi
9734         rm -f $DIR/$tfile
9735 }
9736 run_test 119a "Short directIO read must return actual read amount"
9737
9738 test_119b() # bug 11737
9739 {
9740         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9741
9742         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9744         sync
9745         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9746                 error "direct read failed"
9747         rm -f $DIR/$tfile
9748 }
9749 run_test 119b "Sparse directIO read must return actual read amount"
9750
9751 test_119c() # bug 13099
9752 {
9753         BSIZE=1048576
9754         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9755         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9756         rm -f $DIR/$tfile
9757 }
9758 run_test 119c "Testing for direct read hitting hole"
9759
9760 test_119d() # bug 15950
9761 {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763
9764         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9765         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9766         BSIZE=1048576
9767         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9768         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9769         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9770         lctl set_param fail_loc=0x40d
9771         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9772         pid_dio=$!
9773         sleep 1
9774         cat $DIR/$tfile > /dev/null &
9775         lctl set_param fail_loc=0
9776         pid_reads=$!
9777         wait $pid_dio
9778         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9779         sleep 2
9780         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9781         error "the read rpcs have not completed in 2s"
9782         rm -f $DIR/$tfile
9783         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9784 }
9785 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9786
9787 test_120a() {
9788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9789         remote_mds_nodsh && skip "remote MDS with nodsh"
9790         test_mkdir -i0 -c1 $DIR/$tdir
9791         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9792                 skip_env "no early lock cancel on server"
9793
9794         lru_resize_disable mdc
9795         lru_resize_disable osc
9796         cancel_lru_locks mdc
9797         # asynchronous object destroy at MDT could cause bl ast to client
9798         cancel_lru_locks osc
9799
9800         stat $DIR/$tdir > /dev/null
9801         can1=$(do_facet mds1 \
9802                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9803                awk '/ldlm_cancel/ {print $2}')
9804         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9805                awk '/ldlm_bl_callback/ {print $2}')
9806         test_mkdir -i0 -c1 $DIR/$tdir/d1
9807         can2=$(do_facet mds1 \
9808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9809                awk '/ldlm_cancel/ {print $2}')
9810         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9811                awk '/ldlm_bl_callback/ {print $2}')
9812         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9813         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9814         lru_resize_enable mdc
9815         lru_resize_enable osc
9816 }
9817 run_test 120a "Early Lock Cancel: mkdir test"
9818
9819 test_120b() {
9820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9821         remote_mds_nodsh && skip "remote MDS with nodsh"
9822         test_mkdir $DIR/$tdir
9823         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9824                 skip_env "no early lock cancel on server"
9825
9826         lru_resize_disable mdc
9827         lru_resize_disable osc
9828         cancel_lru_locks mdc
9829         stat $DIR/$tdir > /dev/null
9830         can1=$(do_facet $SINGLEMDS \
9831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9832                awk '/ldlm_cancel/ {print $2}')
9833         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9834                awk '/ldlm_bl_callback/ {print $2}')
9835         touch $DIR/$tdir/f1
9836         can2=$(do_facet $SINGLEMDS \
9837                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9838                awk '/ldlm_cancel/ {print $2}')
9839         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9840                awk '/ldlm_bl_callback/ {print $2}')
9841         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9842         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9843         lru_resize_enable mdc
9844         lru_resize_enable osc
9845 }
9846 run_test 120b "Early Lock Cancel: create test"
9847
9848 test_120c() {
9849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9850         remote_mds_nodsh && skip "remote MDS with nodsh"
9851         test_mkdir -i0 -c1 $DIR/$tdir
9852         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9853                 skip "no early lock cancel on server"
9854
9855         lru_resize_disable mdc
9856         lru_resize_disable osc
9857         test_mkdir -i0 -c1 $DIR/$tdir/d1
9858         test_mkdir -i0 -c1 $DIR/$tdir/d2
9859         touch $DIR/$tdir/d1/f1
9860         cancel_lru_locks mdc
9861         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9862         can1=$(do_facet mds1 \
9863                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9864                awk '/ldlm_cancel/ {print $2}')
9865         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9866                awk '/ldlm_bl_callback/ {print $2}')
9867         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9868         can2=$(do_facet mds1 \
9869                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9870                awk '/ldlm_cancel/ {print $2}')
9871         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9872                awk '/ldlm_bl_callback/ {print $2}')
9873         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9874         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9875         lru_resize_enable mdc
9876         lru_resize_enable osc
9877 }
9878 run_test 120c "Early Lock Cancel: link test"
9879
9880 test_120d() {
9881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9882         remote_mds_nodsh && skip "remote MDS with nodsh"
9883         test_mkdir -i0 -c1 $DIR/$tdir
9884         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9885                 skip_env "no early lock cancel on server"
9886
9887         lru_resize_disable mdc
9888         lru_resize_disable osc
9889         touch $DIR/$tdir
9890         cancel_lru_locks mdc
9891         stat $DIR/$tdir > /dev/null
9892         can1=$(do_facet mds1 \
9893                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9894                awk '/ldlm_cancel/ {print $2}')
9895         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9896                awk '/ldlm_bl_callback/ {print $2}')
9897         chmod a+x $DIR/$tdir
9898         can2=$(do_facet mds1 \
9899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9900                awk '/ldlm_cancel/ {print $2}')
9901         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9902                awk '/ldlm_bl_callback/ {print $2}')
9903         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9904         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9905         lru_resize_enable mdc
9906         lru_resize_enable osc
9907 }
9908 run_test 120d "Early Lock Cancel: setattr test"
9909
9910 test_120e() {
9911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9912         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9913                 skip_env "no early lock cancel on server"
9914         remote_mds_nodsh && skip "remote MDS with nodsh"
9915
9916         local dlmtrace_set=false
9917
9918         test_mkdir -i0 -c1 $DIR/$tdir
9919         lru_resize_disable mdc
9920         lru_resize_disable osc
9921         ! $LCTL get_param debug | grep -q dlmtrace &&
9922                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9923         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9924         cancel_lru_locks mdc
9925         cancel_lru_locks osc
9926         dd if=$DIR/$tdir/f1 of=/dev/null
9927         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9928         # XXX client can not do early lock cancel of OST lock
9929         # during unlink (LU-4206), so cancel osc lock now.
9930         sleep 2
9931         cancel_lru_locks osc
9932         can1=$(do_facet mds1 \
9933                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9934                awk '/ldlm_cancel/ {print $2}')
9935         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9936                awk '/ldlm_bl_callback/ {print $2}')
9937         unlink $DIR/$tdir/f1
9938         sleep 5
9939         can2=$(do_facet mds1 \
9940                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9941                awk '/ldlm_cancel/ {print $2}')
9942         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9943                awk '/ldlm_bl_callback/ {print $2}')
9944         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9945                 $LCTL dk $TMP/cancel.debug.txt
9946         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9947                 $LCTL dk $TMP/blocking.debug.txt
9948         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9949         lru_resize_enable mdc
9950         lru_resize_enable osc
9951 }
9952 run_test 120e "Early Lock Cancel: unlink test"
9953
9954 test_120f() {
9955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9956         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9957                 skip_env "no early lock cancel on server"
9958         remote_mds_nodsh && skip "remote MDS with nodsh"
9959
9960         test_mkdir -i0 -c1 $DIR/$tdir
9961         lru_resize_disable mdc
9962         lru_resize_disable osc
9963         test_mkdir -i0 -c1 $DIR/$tdir/d1
9964         test_mkdir -i0 -c1 $DIR/$tdir/d2
9965         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9966         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9967         cancel_lru_locks mdc
9968         cancel_lru_locks osc
9969         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9970         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9971         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9972         # XXX client can not do early lock cancel of OST lock
9973         # during rename (LU-4206), so cancel osc lock now.
9974         sleep 2
9975         cancel_lru_locks osc
9976         can1=$(do_facet mds1 \
9977                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9978                awk '/ldlm_cancel/ {print $2}')
9979         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9980                awk '/ldlm_bl_callback/ {print $2}')
9981         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9982         sleep 5
9983         can2=$(do_facet mds1 \
9984                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9985                awk '/ldlm_cancel/ {print $2}')
9986         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9987                awk '/ldlm_bl_callback/ {print $2}')
9988         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9989         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9990         lru_resize_enable mdc
9991         lru_resize_enable osc
9992 }
9993 run_test 120f "Early Lock Cancel: rename test"
9994
9995 test_120g() {
9996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9997         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9998                 skip_env "no early lock cancel on server"
9999         remote_mds_nodsh && skip "remote MDS with nodsh"
10000
10001         lru_resize_disable mdc
10002         lru_resize_disable osc
10003         count=10000
10004         echo create $count files
10005         test_mkdir $DIR/$tdir
10006         cancel_lru_locks mdc
10007         cancel_lru_locks osc
10008         t0=$(date +%s)
10009
10010         can0=$(do_facet $SINGLEMDS \
10011                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10012                awk '/ldlm_cancel/ {print $2}')
10013         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10014                awk '/ldlm_bl_callback/ {print $2}')
10015         createmany -o $DIR/$tdir/f $count
10016         sync
10017         can1=$(do_facet $SINGLEMDS \
10018                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10019                awk '/ldlm_cancel/ {print $2}')
10020         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10021                awk '/ldlm_bl_callback/ {print $2}')
10022         t1=$(date +%s)
10023         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10024         echo rm $count files
10025         rm -r $DIR/$tdir
10026         sync
10027         can2=$(do_facet $SINGLEMDS \
10028                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10029                awk '/ldlm_cancel/ {print $2}')
10030         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10031                awk '/ldlm_bl_callback/ {print $2}')
10032         t2=$(date +%s)
10033         echo total: $count removes in $((t2-t1))
10034         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10035         sleep 2
10036         # wait for commitment of removal
10037         lru_resize_enable mdc
10038         lru_resize_enable osc
10039 }
10040 run_test 120g "Early Lock Cancel: performance test"
10041
10042 test_121() { #bug #10589
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044
10045         rm -rf $DIR/$tfile
10046         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10047 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10048         lctl set_param fail_loc=0x310
10049         cancel_lru_locks osc > /dev/null
10050         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10051         lctl set_param fail_loc=0
10052         [[ $reads -eq $writes ]] ||
10053                 error "read $reads blocks, must be $writes blocks"
10054 }
10055 run_test 121 "read cancel race ========="
10056
10057 test_123a() { # was test 123, statahead(bug 11401)
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059
10060         SLOWOK=0
10061         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10062                 log "testing UP system. Performance may be lower than expected."
10063                 SLOWOK=1
10064         fi
10065
10066         rm -rf $DIR/$tdir
10067         test_mkdir $DIR/$tdir
10068         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10069         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10070         MULT=10
10071         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10072                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10073
10074                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10075                 lctl set_param -n llite.*.statahead_max 0
10076                 lctl get_param llite.*.statahead_max
10077                 cancel_lru_locks mdc
10078                 cancel_lru_locks osc
10079                 stime=`date +%s`
10080                 time ls -l $DIR/$tdir | wc -l
10081                 etime=`date +%s`
10082                 delta=$((etime - stime))
10083                 log "ls $i files without statahead: $delta sec"
10084                 lctl set_param llite.*.statahead_max=$max
10085
10086                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10087                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10088                 cancel_lru_locks mdc
10089                 cancel_lru_locks osc
10090                 stime=`date +%s`
10091                 time ls -l $DIR/$tdir | wc -l
10092                 etime=`date +%s`
10093                 delta_sa=$((etime - stime))
10094                 log "ls $i files with statahead: $delta_sa sec"
10095                 lctl get_param -n llite.*.statahead_stats
10096                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10097
10098                 [[ $swrong -lt $ewrong ]] &&
10099                         log "statahead was stopped, maybe too many locks held!"
10100                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10101
10102                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10103                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10104                     lctl set_param -n llite.*.statahead_max 0
10105                     lctl get_param llite.*.statahead_max
10106                     cancel_lru_locks mdc
10107                     cancel_lru_locks osc
10108                     stime=`date +%s`
10109                     time ls -l $DIR/$tdir | wc -l
10110                     etime=`date +%s`
10111                     delta=$((etime - stime))
10112                     log "ls $i files again without statahead: $delta sec"
10113                     lctl set_param llite.*.statahead_max=$max
10114                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10115                         if [  $SLOWOK -eq 0 ]; then
10116                                 error "ls $i files is slower with statahead!"
10117                         else
10118                                 log "ls $i files is slower with statahead!"
10119                         fi
10120                         break
10121                     fi
10122                 fi
10123
10124                 [ $delta -gt 20 ] && break
10125                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10126                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10127         done
10128         log "ls done"
10129
10130         stime=`date +%s`
10131         rm -r $DIR/$tdir
10132         sync
10133         etime=`date +%s`
10134         delta=$((etime - stime))
10135         log "rm -r $DIR/$tdir/: $delta seconds"
10136         log "rm done"
10137         lctl get_param -n llite.*.statahead_stats
10138 }
10139 run_test 123a "verify statahead work"
10140
10141 test_123b () { # statahead(bug 15027)
10142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10143
10144         test_mkdir $DIR/$tdir
10145         createmany -o $DIR/$tdir/$tfile-%d 1000
10146
10147         cancel_lru_locks mdc
10148         cancel_lru_locks osc
10149
10150 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10151         lctl set_param fail_loc=0x80000803
10152         ls -lR $DIR/$tdir > /dev/null
10153         log "ls done"
10154         lctl set_param fail_loc=0x0
10155         lctl get_param -n llite.*.statahead_stats
10156         rm -r $DIR/$tdir
10157         sync
10158
10159 }
10160 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10161
10162 test_124a() {
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10165                 skip_env "no lru resize on server"
10166
10167         local NR=2000
10168
10169         test_mkdir $DIR/$tdir
10170
10171         log "create $NR files at $DIR/$tdir"
10172         createmany -o $DIR/$tdir/f $NR ||
10173                 error "failed to create $NR files in $DIR/$tdir"
10174
10175         cancel_lru_locks mdc
10176         ls -l $DIR/$tdir > /dev/null
10177
10178         local NSDIR=""
10179         local LRU_SIZE=0
10180         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10181                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10182                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10183                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10184                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10185                         log "NSDIR=$NSDIR"
10186                         log "NS=$(basename $NSDIR)"
10187                         break
10188                 fi
10189         done
10190
10191         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10192                 skip "Not enough cached locks created!"
10193         fi
10194         log "LRU=$LRU_SIZE"
10195
10196         local SLEEP=30
10197
10198         # We know that lru resize allows one client to hold $LIMIT locks
10199         # for 10h. After that locks begin to be killed by client.
10200         local MAX_HRS=10
10201         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10202         log "LIMIT=$LIMIT"
10203         if [ $LIMIT -lt $LRU_SIZE ]; then
10204                 skip "Limit is too small $LIMIT"
10205         fi
10206
10207         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10208         # killing locks. Some time was spent for creating locks. This means
10209         # that up to the moment of sleep finish we must have killed some of
10210         # them (10-100 locks). This depends on how fast ther were created.
10211         # Many of them were touched in almost the same moment and thus will
10212         # be killed in groups.
10213         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10214
10215         # Use $LRU_SIZE_B here to take into account real number of locks
10216         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10217         local LRU_SIZE_B=$LRU_SIZE
10218         log "LVF=$LVF"
10219         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10220         log "OLD_LVF=$OLD_LVF"
10221         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10222
10223         # Let's make sure that we really have some margin. Client checks
10224         # cached locks every 10 sec.
10225         SLEEP=$((SLEEP+20))
10226         log "Sleep ${SLEEP} sec"
10227         local SEC=0
10228         while ((SEC<$SLEEP)); do
10229                 echo -n "..."
10230                 sleep 5
10231                 SEC=$((SEC+5))
10232                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10233                 echo -n "$LRU_SIZE"
10234         done
10235         echo ""
10236         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10237         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10238
10239         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10240                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10241                 unlinkmany $DIR/$tdir/f $NR
10242                 return
10243         }
10244
10245         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10246         log "unlink $NR files at $DIR/$tdir"
10247         unlinkmany $DIR/$tdir/f $NR
10248 }
10249 run_test 124a "lru resize ======================================="
10250
10251 get_max_pool_limit()
10252 {
10253         local limit=$($LCTL get_param \
10254                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10255         local max=0
10256         for l in $limit; do
10257                 if [[ $l -gt $max ]]; then
10258                         max=$l
10259                 fi
10260         done
10261         echo $max
10262 }
10263
10264 test_124b() {
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10267                 skip_env "no lru resize on server"
10268
10269         LIMIT=$(get_max_pool_limit)
10270
10271         NR=$(($(default_lru_size)*20))
10272         if [[ $NR -gt $LIMIT ]]; then
10273                 log "Limit lock number by $LIMIT locks"
10274                 NR=$LIMIT
10275         fi
10276
10277         IFree=$(mdsrate_inodes_available)
10278         if [ $IFree -lt $NR ]; then
10279                 log "Limit lock number by $IFree inodes"
10280                 NR=$IFree
10281         fi
10282
10283         lru_resize_disable mdc
10284         test_mkdir -p $DIR/$tdir/disable_lru_resize
10285
10286         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10287         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10288         cancel_lru_locks mdc
10289         stime=`date +%s`
10290         PID=""
10291         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10292         PID="$PID $!"
10293         sleep 2
10294         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10295         PID="$PID $!"
10296         sleep 2
10297         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10298         PID="$PID $!"
10299         wait $PID
10300         etime=`date +%s`
10301         nolruresize_delta=$((etime-stime))
10302         log "ls -la time: $nolruresize_delta seconds"
10303         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10304         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10305
10306         lru_resize_enable mdc
10307         test_mkdir -p $DIR/$tdir/enable_lru_resize
10308
10309         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10310         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10311         cancel_lru_locks mdc
10312         stime=`date +%s`
10313         PID=""
10314         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10315         PID="$PID $!"
10316         sleep 2
10317         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10318         PID="$PID $!"
10319         sleep 2
10320         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10321         PID="$PID $!"
10322         wait $PID
10323         etime=`date +%s`
10324         lruresize_delta=$((etime-stime))
10325         log "ls -la time: $lruresize_delta seconds"
10326         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10327
10328         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10329                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10330         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10331                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10332         else
10333                 log "lru resize performs the same with no lru resize"
10334         fi
10335         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10336 }
10337 run_test 124b "lru resize (performance test) ======================="
10338
10339 test_124c() {
10340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10341         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10342                 skip_env "no lru resize on server"
10343
10344         # cache ununsed locks on client
10345         local nr=100
10346         cancel_lru_locks mdc
10347         test_mkdir $DIR/$tdir
10348         createmany -o $DIR/$tdir/f $nr ||
10349                 error "failed to create $nr files in $DIR/$tdir"
10350         ls -l $DIR/$tdir > /dev/null
10351
10352         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10353         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10354         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10355         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10356         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10357
10358         # set lru_max_age to 1 sec
10359         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10360         echo "sleep $((recalc_p * 2)) seconds..."
10361         sleep $((recalc_p * 2))
10362
10363         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10364         # restore lru_max_age
10365         $LCTL set_param -n $nsdir.lru_max_age $max_age
10366         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10367         unlinkmany $DIR/$tdir/f $nr
10368 }
10369 run_test 124c "LRUR cancel very aged locks"
10370
10371 test_125() { # 13358
10372         $LCTL get_param -n llite.*.client_type | grep -q local ||
10373                 skip "must run as local client"
10374         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10375                 skip_env "must have acl enabled"
10376         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10377
10378         test_mkdir $DIR/$tdir
10379         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10380         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10381         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10382 }
10383 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10384
10385 test_126() { # bug 12829/13455
10386         $GSS && skip_env "must run as gss disabled"
10387         $LCTL get_param -n llite.*.client_type | grep -q local ||
10388                 skip "must run as local client"
10389         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10390
10391         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10392         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10393         rm -f $DIR/$tfile
10394         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10395 }
10396 run_test 126 "check that the fsgid provided by the client is taken into account"
10397
10398 test_127a() { # bug 15521
10399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10400
10401         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10402         $LCTL set_param osc.*.stats=0
10403         FSIZE=$((2048 * 1024))
10404         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10405         cancel_lru_locks osc
10406         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10407
10408         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10409         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10410                 echo "got $COUNT $NAME"
10411                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10412                 eval $NAME=$COUNT || error "Wrong proc format"
10413
10414                 case $NAME in
10415                         read_bytes|write_bytes)
10416                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10417                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10418                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10419                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10420                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10421                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10422                                 error "sumsquare is too small: $SUMSQ"
10423                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10424                                 error "sumsquare is too big: $SUMSQ"
10425                         ;;
10426                         *) ;;
10427                 esac
10428         done < $DIR/${tfile}.tmp
10429
10430         #check that we actually got some stats
10431         [ "$read_bytes" ] || error "Missing read_bytes stats"
10432         [ "$write_bytes" ] || error "Missing write_bytes stats"
10433         [ "$read_bytes" != 0 ] || error "no read done"
10434         [ "$write_bytes" != 0 ] || error "no write done"
10435 }
10436 run_test 127a "verify the client stats are sane"
10437
10438 test_127b() { # bug LU-333
10439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10440         local name count samp unit min max sum sumsq
10441
10442         $LCTL set_param llite.*.stats=0
10443
10444         # perform 2 reads and writes so MAX is different from SUM.
10445         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10446         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10447         cancel_lru_locks osc
10448         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10449         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10450
10451         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10452         while read name count samp unit min max sum sumsq; do
10453                 echo "got $count $name"
10454                 eval $name=$count || error "Wrong proc format"
10455
10456                 case $name in
10457                 read_bytes)
10458                         [ $count -ne 2 ] && error "count is not 2: $count"
10459                         [ $min -ne $PAGE_SIZE ] &&
10460                                 error "min is not $PAGE_SIZE: $min"
10461                         [ $max -ne $PAGE_SIZE ] &&
10462                                 error "max is incorrect: $max"
10463                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10464                                 error "sum is wrong: $sum"
10465                         ;;
10466                 write_bytes)
10467                         [ $count -ne 2 ] && error "count is not 2: $count"
10468                         [ $min -ne $PAGE_SIZE ] &&
10469                                 error "min is not $PAGE_SIZE: $min"
10470                         [ $max -ne $PAGE_SIZE ] &&
10471                                 error "max is incorrect: $max"
10472                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10473                                 error "sum is wrong: $sum"
10474                         ;;
10475                 *) ;;
10476                 esac
10477         done < $TMP/$tfile.tmp
10478
10479         #check that we actually got some stats
10480         [ "$read_bytes" ] || error "Missing read_bytes stats"
10481         [ "$write_bytes" ] || error "Missing write_bytes stats"
10482         [ "$read_bytes" != 0 ] || error "no read done"
10483         [ "$write_bytes" != 0 ] || error "no write done"
10484
10485         rm -f $TMP/${tfile}.tmp
10486 }
10487 run_test 127b "verify the llite client stats are sane"
10488
10489 test_128() { # bug 15212
10490         touch $DIR/$tfile
10491         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10492                 find $DIR/$tfile
10493                 find $DIR/$tfile
10494         EOF
10495
10496         result=$(grep error $TMP/$tfile.log)
10497         rm -f $DIR/$tfile $TMP/$tfile.log
10498         [ -z "$result" ] ||
10499                 error "consecutive find's under interactive lfs failed"
10500 }
10501 run_test 128 "interactive lfs for 2 consecutive find's"
10502
10503 set_dir_limits () {
10504         local mntdev
10505         local canondev
10506         local node
10507
10508         local ldproc=/proc/fs/ldiskfs
10509         local facets=$(get_facets MDS)
10510
10511         for facet in ${facets//,/ }; do
10512                 canondev=$(ldiskfs_canon \
10513                            *.$(convert_facet2label $facet).mntdev $facet)
10514                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10515                         ldproc=/sys/fs/ldiskfs
10516                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10517                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10518         done
10519 }
10520
10521 check_mds_dmesg() {
10522         local facets=$(get_facets MDS)
10523         for facet in ${facets//,/ }; do
10524                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10525         done
10526         return 1
10527 }
10528
10529 test_129() {
10530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10531         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10532                 skip "Need MDS version with at least 2.5.56"
10533         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10534                 skip_env "ldiskfs only test"
10535         fi
10536         remote_mds_nodsh && skip "remote MDS with nodsh"
10537
10538         local ENOSPC=28
10539         local EFBIG=27
10540         local has_warning=false
10541
10542         rm -rf $DIR/$tdir
10543         mkdir -p $DIR/$tdir
10544
10545         # block size of mds1
10546         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10547         set_dir_limits $maxsize $maxsize
10548         local dirsize=$(stat -c%s "$DIR/$tdir")
10549         local nfiles=0
10550         while [[ $dirsize -le $maxsize ]]; do
10551                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10552                 rc=$?
10553                 if ! $has_warning; then
10554                         check_mds_dmesg '"is approaching"' && has_warning=true
10555                 fi
10556                 # check two errors:
10557                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10558                 # EFBIG for previous versions included in ldiskfs series
10559                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10560                         set_dir_limits 0 0
10561                         echo "return code $rc received as expected"
10562
10563                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10564                                 error_exit "create failed w/o dir size limit"
10565
10566                         check_mds_dmesg '"has reached"' ||
10567                                 error_exit "reached message should be output"
10568
10569                         [ $has_warning = "false" ] &&
10570                                 error_exit "warning message should be output"
10571
10572                         dirsize=$(stat -c%s "$DIR/$tdir")
10573
10574                         [[ $dirsize -ge $maxsize ]] && return 0
10575                         error_exit "current dir size $dirsize, " \
10576                                    "previous limit $maxsize"
10577                 elif [ $rc -ne 0 ]; then
10578                         set_dir_limits 0 0
10579                         error_exit "return $rc received instead of expected " \
10580                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10581                 fi
10582                 nfiles=$((nfiles + 1))
10583                 dirsize=$(stat -c%s "$DIR/$tdir")
10584         done
10585
10586         set_dir_limits 0 0
10587         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10588 }
10589 run_test 129 "test directory size limit ========================"
10590
10591 OLDIFS="$IFS"
10592 cleanup_130() {
10593         trap 0
10594         IFS="$OLDIFS"
10595 }
10596
10597 test_130a() {
10598         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10599         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10600
10601         trap cleanup_130 EXIT RETURN
10602
10603         local fm_file=$DIR/$tfile
10604         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10605         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10606                 error "dd failed for $fm_file"
10607
10608         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10609         filefrag -ves $fm_file
10610         RC=$?
10611         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10612                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10613         [ $RC != 0 ] && error "filefrag $fm_file failed"
10614
10615         filefrag_op=$(filefrag -ve -k $fm_file |
10616                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10617         lun=$($LFS getstripe -i $fm_file)
10618
10619         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10620         IFS=$'\n'
10621         tot_len=0
10622         for line in $filefrag_op
10623         do
10624                 frag_lun=`echo $line | cut -d: -f5`
10625                 ext_len=`echo $line | cut -d: -f4`
10626                 if (( $frag_lun != $lun )); then
10627                         cleanup_130
10628                         error "FIEMAP on 1-stripe file($fm_file) failed"
10629                         return
10630                 fi
10631                 (( tot_len += ext_len ))
10632         done
10633
10634         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10635                 cleanup_130
10636                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10637                 return
10638         fi
10639
10640         cleanup_130
10641
10642         echo "FIEMAP on single striped file succeeded"
10643 }
10644 run_test 130a "FIEMAP (1-stripe file)"
10645
10646 test_130b() {
10647         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10648
10649         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10650         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10651
10652         trap cleanup_130 EXIT RETURN
10653
10654         local fm_file=$DIR/$tfile
10655         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10656                         error "setstripe on $fm_file"
10657         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10658                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10659
10660         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10661                 error "dd failed on $fm_file"
10662
10663         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10664         filefrag_op=$(filefrag -ve -k $fm_file |
10665                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10666
10667         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10668                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10669
10670         IFS=$'\n'
10671         tot_len=0
10672         num_luns=1
10673         for line in $filefrag_op
10674         do
10675                 frag_lun=$(echo $line | cut -d: -f5 |
10676                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10677                 ext_len=$(echo $line | cut -d: -f4)
10678                 if (( $frag_lun != $last_lun )); then
10679                         if (( tot_len != 1024 )); then
10680                                 cleanup_130
10681                                 error "FIEMAP on $fm_file failed; returned " \
10682                                 "len $tot_len for OST $last_lun instead of 1024"
10683                                 return
10684                         else
10685                                 (( num_luns += 1 ))
10686                                 tot_len=0
10687                         fi
10688                 fi
10689                 (( tot_len += ext_len ))
10690                 last_lun=$frag_lun
10691         done
10692         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10693                 cleanup_130
10694                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10695                         "luns or wrong len for OST $last_lun"
10696                 return
10697         fi
10698
10699         cleanup_130
10700
10701         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10702 }
10703 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10704
10705 test_130c() {
10706         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10707
10708         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10709         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10710
10711         trap cleanup_130 EXIT RETURN
10712
10713         local fm_file=$DIR/$tfile
10714         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10715         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10716                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10717
10718         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10719                         error "dd failed on $fm_file"
10720
10721         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10722         filefrag_op=$(filefrag -ve -k $fm_file |
10723                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10724
10725         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10726                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10727
10728         IFS=$'\n'
10729         tot_len=0
10730         num_luns=1
10731         for line in $filefrag_op
10732         do
10733                 frag_lun=$(echo $line | cut -d: -f5 |
10734                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10735                 ext_len=$(echo $line | cut -d: -f4)
10736                 if (( $frag_lun != $last_lun )); then
10737                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10738                         if (( logical != 512 )); then
10739                                 cleanup_130
10740                                 error "FIEMAP on $fm_file failed; returned " \
10741                                 "logical start for lun $logical instead of 512"
10742                                 return
10743                         fi
10744                         if (( tot_len != 512 )); then
10745                                 cleanup_130
10746                                 error "FIEMAP on $fm_file failed; returned " \
10747                                 "len $tot_len for OST $last_lun instead of 1024"
10748                                 return
10749                         else
10750                                 (( num_luns += 1 ))
10751                                 tot_len=0
10752                         fi
10753                 fi
10754                 (( tot_len += ext_len ))
10755                 last_lun=$frag_lun
10756         done
10757         if (( num_luns != 2 || tot_len != 512 )); then
10758                 cleanup_130
10759                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10760                         "luns or wrong len for OST $last_lun"
10761                 return
10762         fi
10763
10764         cleanup_130
10765
10766         echo "FIEMAP on 2-stripe file with hole succeeded"
10767 }
10768 run_test 130c "FIEMAP (2-stripe file with hole)"
10769
10770 test_130d() {
10771         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10772
10773         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10774         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10775
10776         trap cleanup_130 EXIT RETURN
10777
10778         local fm_file=$DIR/$tfile
10779         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10780                         error "setstripe on $fm_file"
10781         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10782                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10783
10784         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10785         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10786                 error "dd failed on $fm_file"
10787
10788         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10789         filefrag_op=$(filefrag -ve -k $fm_file |
10790                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10791
10792         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10793                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10794
10795         IFS=$'\n'
10796         tot_len=0
10797         num_luns=1
10798         for line in $filefrag_op
10799         do
10800                 frag_lun=$(echo $line | cut -d: -f5 |
10801                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10802                 ext_len=$(echo $line | cut -d: -f4)
10803                 if (( $frag_lun != $last_lun )); then
10804                         if (( tot_len != 1024 )); then
10805                                 cleanup_130
10806                                 error "FIEMAP on $fm_file failed; returned " \
10807                                 "len $tot_len for OST $last_lun instead of 1024"
10808                                 return
10809                         else
10810                                 (( num_luns += 1 ))
10811                                 tot_len=0
10812                         fi
10813                 fi
10814                 (( tot_len += ext_len ))
10815                 last_lun=$frag_lun
10816         done
10817         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10818                 cleanup_130
10819                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10820                         "luns or wrong len for OST $last_lun"
10821                 return
10822         fi
10823
10824         cleanup_130
10825
10826         echo "FIEMAP on N-stripe file succeeded"
10827 }
10828 run_test 130d "FIEMAP (N-stripe file)"
10829
10830 test_130e() {
10831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10832
10833         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10834         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10835
10836         trap cleanup_130 EXIT RETURN
10837
10838         local fm_file=$DIR/$tfile
10839         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10840         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10841                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10842
10843         NUM_BLKS=512
10844         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10845         for ((i = 0; i < $NUM_BLKS; i++))
10846         do
10847                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10848         done
10849
10850         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10851         filefrag_op=$(filefrag -ve -k $fm_file |
10852                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10853
10854         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10855                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10856
10857         IFS=$'\n'
10858         tot_len=0
10859         num_luns=1
10860         for line in $filefrag_op
10861         do
10862                 frag_lun=$(echo $line | cut -d: -f5 |
10863                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10864                 ext_len=$(echo $line | cut -d: -f4)
10865                 if (( $frag_lun != $last_lun )); then
10866                         if (( tot_len != $EXPECTED_LEN )); then
10867                                 cleanup_130
10868                                 error "FIEMAP on $fm_file failed; returned " \
10869                                 "len $tot_len for OST $last_lun instead " \
10870                                 "of $EXPECTED_LEN"
10871                                 return
10872                         else
10873                                 (( num_luns += 1 ))
10874                                 tot_len=0
10875                         fi
10876                 fi
10877                 (( tot_len += ext_len ))
10878                 last_lun=$frag_lun
10879         done
10880         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10881                 cleanup_130
10882                 error "FIEMAP on $fm_file failed; returned wrong number " \
10883                         "of luns or wrong len for OST $last_lun"
10884                 return
10885         fi
10886
10887         cleanup_130
10888
10889         echo "FIEMAP with continuation calls succeeded"
10890 }
10891 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10892
10893 test_130f() {
10894         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10895         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10896
10897         local fm_file=$DIR/$tfile
10898         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10899                 error "multiop create with lov_delay_create on $fm_file"
10900
10901         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10902         filefrag_extents=$(filefrag -vek $fm_file |
10903                            awk '/extents? found/ { print $2 }')
10904         if [[ "$filefrag_extents" != "0" ]]; then
10905                 error "FIEMAP on $fm_file failed; " \
10906                       "returned $filefrag_extents expected 0"
10907         fi
10908
10909         rm -f $fm_file
10910 }
10911 run_test 130f "FIEMAP (unstriped file)"
10912
10913 # Test for writev/readv
10914 test_131a() {
10915         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10916                 error "writev test failed"
10917         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10918                 error "readv failed"
10919         rm -f $DIR/$tfile
10920 }
10921 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10922
10923 test_131b() {
10924         local fsize=$((524288 + 1048576 + 1572864))
10925         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10926                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10927                         error "append writev test failed"
10928
10929         ((fsize += 1572864 + 1048576))
10930         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10931                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10932                         error "append writev test failed"
10933         rm -f $DIR/$tfile
10934 }
10935 run_test 131b "test append writev"
10936
10937 test_131c() {
10938         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10939         error "NOT PASS"
10940 }
10941 run_test 131c "test read/write on file w/o objects"
10942
10943 test_131d() {
10944         rwv -f $DIR/$tfile -w -n 1 1572864
10945         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10946         if [ "$NOB" != 1572864 ]; then
10947                 error "Short read filed: read $NOB bytes instead of 1572864"
10948         fi
10949         rm -f $DIR/$tfile
10950 }
10951 run_test 131d "test short read"
10952
10953 test_131e() {
10954         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10955         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10956         error "read hitting hole failed"
10957         rm -f $DIR/$tfile
10958 }
10959 run_test 131e "test read hitting hole"
10960
10961 check_stats() {
10962         local facet=$1
10963         local op=$2
10964         local want=${3:-0}
10965         local res
10966
10967         case $facet in
10968         mds*) res=$(do_facet $facet \
10969                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10970                  ;;
10971         ost*) res=$(do_facet $facet \
10972                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10973                  ;;
10974         *) error "Wrong facet '$facet'" ;;
10975         esac
10976         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10977         # if the argument $3 is zero, it means any stat increment is ok.
10978         if [[ $want -gt 0 ]]; then
10979                 local count=$(echo $res | awk '{ print $2 }')
10980                 [[ $count -ne $want ]] &&
10981                         error "The $op counter on $facet is $count, not $want"
10982         fi
10983 }
10984
10985 test_133a() {
10986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10987         remote_ost_nodsh && skip "remote OST with nodsh"
10988         remote_mds_nodsh && skip "remote MDS with nodsh"
10989         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10990                 skip_env "MDS doesn't support rename stats"
10991
10992         local testdir=$DIR/${tdir}/stats_testdir
10993
10994         mkdir -p $DIR/${tdir}
10995
10996         # clear stats.
10997         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10998         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10999
11000         # verify mdt stats first.
11001         mkdir ${testdir} || error "mkdir failed"
11002         check_stats $SINGLEMDS "mkdir" 1
11003         touch ${testdir}/${tfile} || error "touch failed"
11004         check_stats $SINGLEMDS "open" 1
11005         check_stats $SINGLEMDS "close" 1
11006         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11007                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11008                 check_stats $SINGLEMDS "mknod" 2
11009         }
11010         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11011         check_stats $SINGLEMDS "unlink" 1
11012         rm -f ${testdir}/${tfile} || error "file remove failed"
11013         check_stats $SINGLEMDS "unlink" 2
11014
11015         # remove working dir and check mdt stats again.
11016         rmdir ${testdir} || error "rmdir failed"
11017         check_stats $SINGLEMDS "rmdir" 1
11018
11019         local testdir1=$DIR/${tdir}/stats_testdir1
11020         mkdir -p ${testdir}
11021         mkdir -p ${testdir1}
11022         touch ${testdir1}/test1
11023         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11024         check_stats $SINGLEMDS "crossdir_rename" 1
11025
11026         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11027         check_stats $SINGLEMDS "samedir_rename" 1
11028
11029         rm -rf $DIR/${tdir}
11030 }
11031 run_test 133a "Verifying MDT stats ========================================"
11032
11033 test_133b() {
11034         local res
11035
11036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11037         remote_ost_nodsh && skip "remote OST with nodsh"
11038         remote_mds_nodsh && skip "remote MDS with nodsh"
11039
11040         local testdir=$DIR/${tdir}/stats_testdir
11041
11042         mkdir -p ${testdir} || error "mkdir failed"
11043         touch ${testdir}/${tfile} || error "touch failed"
11044         cancel_lru_locks mdc
11045
11046         # clear stats.
11047         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11048         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11049
11050         # extra mdt stats verification.
11051         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11052         check_stats $SINGLEMDS "setattr" 1
11053         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11054         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11055         then            # LU-1740
11056                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11057                 check_stats $SINGLEMDS "getattr" 1
11058         fi
11059         rm -rf $DIR/${tdir}
11060
11061         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11062         # so the check below is not reliable
11063         [ $MDSCOUNT -eq 1 ] || return 0
11064
11065         # Sleep to avoid a cached response.
11066         #define OBD_STATFS_CACHE_SECONDS 1
11067         sleep 2
11068         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11069         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11070         $LFS df || error "lfs failed"
11071         check_stats $SINGLEMDS "statfs" 1
11072
11073         # check aggregated statfs (LU-10018)
11074         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11075                 return 0
11076         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11077                 return 0
11078         sleep 2
11079         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11080         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11081         df $DIR
11082         check_stats $SINGLEMDS "statfs" 1
11083
11084         # We want to check that the client didn't send OST_STATFS to
11085         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11086         # extra care is needed here.
11087         if remote_mds; then
11088                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11089                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11090
11091                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11092                 [ "$res" ] && error "OST got STATFS"
11093         fi
11094
11095         return 0
11096 }
11097 run_test 133b "Verifying extra MDT stats =================================="
11098
11099 test_133c() {
11100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11101         remote_ost_nodsh && skip "remote OST with nodsh"
11102         remote_mds_nodsh && skip "remote MDS with nodsh"
11103
11104         local testdir=$DIR/$tdir/stats_testdir
11105
11106         test_mkdir -p $testdir
11107
11108         # verify obdfilter stats.
11109         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11110         sync
11111         cancel_lru_locks osc
11112         wait_delete_completed
11113
11114         # clear stats.
11115         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11116         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11117
11118         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11119                 error "dd failed"
11120         sync
11121         cancel_lru_locks osc
11122         check_stats ost1 "write" 1
11123
11124         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11125         check_stats ost1 "read" 1
11126
11127         > $testdir/$tfile || error "truncate failed"
11128         check_stats ost1 "punch" 1
11129
11130         rm -f $testdir/$tfile || error "file remove failed"
11131         wait_delete_completed
11132         check_stats ost1 "destroy" 1
11133
11134         rm -rf $DIR/$tdir
11135 }
11136 run_test 133c "Verifying OST stats ========================================"
11137
11138 order_2() {
11139         local value=$1
11140         local orig=$value
11141         local order=1
11142
11143         while [ $value -ge 2 ]; do
11144                 order=$((order*2))
11145                 value=$((value/2))
11146         done
11147
11148         if [ $orig -gt $order ]; then
11149                 order=$((order*2))
11150         fi
11151         echo $order
11152 }
11153
11154 size_in_KMGT() {
11155     local value=$1
11156     local size=('K' 'M' 'G' 'T');
11157     local i=0
11158     local size_string=$value
11159
11160     while [ $value -ge 1024 ]; do
11161         if [ $i -gt 3 ]; then
11162             #T is the biggest unit we get here, if that is bigger,
11163             #just return XXXT
11164             size_string=${value}T
11165             break
11166         fi
11167         value=$((value >> 10))
11168         if [ $value -lt 1024 ]; then
11169             size_string=${value}${size[$i]}
11170             break
11171         fi
11172         i=$((i + 1))
11173     done
11174
11175     echo $size_string
11176 }
11177
11178 get_rename_size() {
11179         local size=$1
11180         local context=${2:-.}
11181         local sample=$(do_facet $SINGLEMDS $LCTL \
11182                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11183                 grep -A1 $context |
11184                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11185         echo $sample
11186 }
11187
11188 test_133d() {
11189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11190         remote_ost_nodsh && skip "remote OST with nodsh"
11191         remote_mds_nodsh && skip "remote MDS with nodsh"
11192         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11193                 skip_env "MDS doesn't support rename stats"
11194
11195         local testdir1=$DIR/${tdir}/stats_testdir1
11196         local testdir2=$DIR/${tdir}/stats_testdir2
11197         mkdir -p $DIR/${tdir}
11198
11199         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11200
11201         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11202         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11203
11204         createmany -o $testdir1/test 512 || error "createmany failed"
11205
11206         # check samedir rename size
11207         mv ${testdir1}/test0 ${testdir1}/test_0
11208
11209         local testdir1_size=$(ls -l $DIR/${tdir} |
11210                 awk '/stats_testdir1/ {print $5}')
11211         local testdir2_size=$(ls -l $DIR/${tdir} |
11212                 awk '/stats_testdir2/ {print $5}')
11213
11214         testdir1_size=$(order_2 $testdir1_size)
11215         testdir2_size=$(order_2 $testdir2_size)
11216
11217         testdir1_size=$(size_in_KMGT $testdir1_size)
11218         testdir2_size=$(size_in_KMGT $testdir2_size)
11219
11220         echo "source rename dir size: ${testdir1_size}"
11221         echo "target rename dir size: ${testdir2_size}"
11222
11223         local cmd="do_facet $SINGLEMDS $LCTL "
11224         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11225
11226         eval $cmd || error "$cmd failed"
11227         local samedir=$($cmd | grep 'same_dir')
11228         local same_sample=$(get_rename_size $testdir1_size)
11229         [ -z "$samedir" ] && error "samedir_rename_size count error"
11230         [[ $same_sample -eq 1 ]] ||
11231                 error "samedir_rename_size error $same_sample"
11232         echo "Check same dir rename stats success"
11233
11234         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11235
11236         # check crossdir rename size
11237         mv ${testdir1}/test_0 ${testdir2}/test_0
11238
11239         testdir1_size=$(ls -l $DIR/${tdir} |
11240                 awk '/stats_testdir1/ {print $5}')
11241         testdir2_size=$(ls -l $DIR/${tdir} |
11242                 awk '/stats_testdir2/ {print $5}')
11243
11244         testdir1_size=$(order_2 $testdir1_size)
11245         testdir2_size=$(order_2 $testdir2_size)
11246
11247         testdir1_size=$(size_in_KMGT $testdir1_size)
11248         testdir2_size=$(size_in_KMGT $testdir2_size)
11249
11250         echo "source rename dir size: ${testdir1_size}"
11251         echo "target rename dir size: ${testdir2_size}"
11252
11253         eval $cmd || error "$cmd failed"
11254         local crossdir=$($cmd | grep 'crossdir')
11255         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11256         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11257         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11258         [[ $src_sample -eq 1 ]] ||
11259                 error "crossdir_rename_size error $src_sample"
11260         [[ $tgt_sample -eq 1 ]] ||
11261                 error "crossdir_rename_size error $tgt_sample"
11262         echo "Check cross dir rename stats success"
11263         rm -rf $DIR/${tdir}
11264 }
11265 run_test 133d "Verifying rename_stats ========================================"
11266
11267 test_133e() {
11268         remote_mds_nodsh && skip "remote MDS with nodsh"
11269         remote_ost_nodsh && skip "remote OST with nodsh"
11270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11271
11272         local testdir=$DIR/${tdir}/stats_testdir
11273         local ctr f0 f1 bs=32768 count=42 sum
11274
11275         mkdir -p ${testdir} || error "mkdir failed"
11276
11277         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11278
11279         for ctr in {write,read}_bytes; do
11280                 sync
11281                 cancel_lru_locks osc
11282
11283                 do_facet ost1 $LCTL set_param -n \
11284                         "obdfilter.*.exports.clear=clear"
11285
11286                 if [ $ctr = write_bytes ]; then
11287                         f0=/dev/zero
11288                         f1=${testdir}/${tfile}
11289                 else
11290                         f0=${testdir}/${tfile}
11291                         f1=/dev/null
11292                 fi
11293
11294                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11295                         error "dd failed"
11296                 sync
11297                 cancel_lru_locks osc
11298
11299                 sum=$(do_facet ost1 $LCTL get_param \
11300                         "obdfilter.*.exports.*.stats" |
11301                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11302                                 $1 == ctr { sum += $7 }
11303                                 END { printf("%0.0f", sum) }')
11304
11305                 if ((sum != bs * count)); then
11306                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11307                 fi
11308         done
11309
11310         rm -rf $DIR/${tdir}
11311 }
11312 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11313
11314 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11315
11316 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11317 # not honor the -ignore_readdir_race option correctly. So we call
11318 # error_ignore() rather than error() in these cases. See LU-11152.
11319 error_133() {
11320         if (find --version; do_facet mds1 find --version) |
11321                 grep -q '\b4\.5\.1[1-4]\b'; then
11322                 error_ignore LU-11152 "$@"
11323         else
11324                 error "$@"
11325         fi
11326 }
11327
11328 test_133f() {
11329         # First without trusting modes.
11330         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11331         echo "proc_dirs='$proc_dirs'"
11332         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11333         find $proc_dirs -exec cat '{}' \; &> /dev/null
11334
11335         # Second verifying readability.
11336         $LCTL get_param -R '*' &> /dev/null
11337
11338         # Verifing writability with badarea_io.
11339         find $proc_dirs \
11340                 -ignore_readdir_race \
11341                 -type f \
11342                 -not -name force_lbug \
11343                 -not -name changelog_mask \
11344                 -exec badarea_io '{}' \; ||
11345                         error_133 "find $proc_dirs failed"
11346 }
11347 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11348
11349 test_133g() {
11350         remote_mds_nodsh && skip "remote MDS with nodsh"
11351         remote_ost_nodsh && skip "remote OST with nodsh"
11352
11353         # eventually, this can also be replaced with "lctl get_param -R",
11354         # but not until that option is always available on the server
11355         local facet
11356         for facet in mds1 ost1; do
11357                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11358                         skip_noexit "Too old lustre on $facet"
11359                 local facet_proc_dirs=$(do_facet $facet \
11360                                         \\\ls -d $proc_regexp 2>/dev/null)
11361                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11362                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11363                 do_facet $facet find $facet_proc_dirs \
11364                         ! -name req_history \
11365                         -exec cat '{}' \\\; &> /dev/null
11366
11367                 do_facet $facet find $facet_proc_dirs \
11368                         ! -name req_history \
11369                         -type f \
11370                         -exec cat '{}' \\\; &> /dev/null ||
11371                                 error "proc file read failed"
11372
11373                 do_facet $facet find $facet_proc_dirs \
11374                         -ignore_readdir_race \
11375                         -type f \
11376                         -not -name force_lbug \
11377                         -not -name changelog_mask \
11378                         -exec badarea_io '{}' \\\; ||
11379                                 error_133 "$facet find $facet_proc_dirs failed"
11380         done
11381
11382         # remount the FS in case writes/reads /proc break the FS
11383         cleanup || error "failed to unmount"
11384         setup || error "failed to setup"
11385         true
11386 }
11387 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11388
11389 test_133h() {
11390         remote_mds_nodsh && skip "remote MDS with nodsh"
11391         remote_ost_nodsh && skip "remote OST with nodsh"
11392         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11393                 skip "Need MDS version at least 2.9.54"
11394
11395         local facet
11396
11397         for facet in client mds1 ost1; do
11398                 local facet_proc_dirs=$(do_facet $facet \
11399                                         \\\ls -d $proc_regexp 2> /dev/null)
11400                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11401                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11402                 # Get the list of files that are missing the terminating newline
11403                 local missing=($(do_facet $facet \
11404                         find ${facet_proc_dirs} -type f \|              \
11405                                 while read F\; do                       \
11406                                         awk -v FS='\v' -v RS='\v\v'     \
11407                                         "'END { if(NR>0 &&              \
11408                                         \\\$NF !~ /.*\\\n\$/)           \
11409                                                 print FILENAME}'"       \
11410                                         '\$F'\;                         \
11411                                 done 2>/dev/null))
11412                 [ ${#missing[*]} -eq 0 ] ||
11413                         error "files do not end with newline: ${missing[*]}"
11414         done
11415 }
11416 run_test 133h "Proc files should end with newlines"
11417
11418 test_134a() {
11419         remote_mds_nodsh && skip "remote MDS with nodsh"
11420         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11421                 skip "Need MDS version at least 2.7.54"
11422
11423         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11424         cancel_lru_locks mdc
11425
11426         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11427         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11428         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11429
11430         local nr=1000
11431         createmany -o $DIR/$tdir/f $nr ||
11432                 error "failed to create $nr files in $DIR/$tdir"
11433         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11434
11435         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11436         do_facet mds1 $LCTL set_param fail_loc=0x327
11437         do_facet mds1 $LCTL set_param fail_val=500
11438         touch $DIR/$tdir/m
11439
11440         echo "sleep 10 seconds ..."
11441         sleep 10
11442         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11443
11444         do_facet mds1 $LCTL set_param fail_loc=0
11445         do_facet mds1 $LCTL set_param fail_val=0
11446         [ $lck_cnt -lt $unused ] ||
11447                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11448
11449         rm $DIR/$tdir/m
11450         unlinkmany $DIR/$tdir/f $nr
11451 }
11452 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11453
11454 test_134b() {
11455         remote_mds_nodsh && skip "remote MDS with nodsh"
11456         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11457                 skip "Need MDS version at least 2.7.54"
11458
11459         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11460         cancel_lru_locks mdc
11461
11462         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11463                         ldlm.lock_reclaim_threshold_mb)
11464         # disable reclaim temporarily
11465         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11466
11467         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11468         do_facet mds1 $LCTL set_param fail_loc=0x328
11469         do_facet mds1 $LCTL set_param fail_val=500
11470
11471         $LCTL set_param debug=+trace
11472
11473         local nr=600
11474         createmany -o $DIR/$tdir/f $nr &
11475         local create_pid=$!
11476
11477         echo "Sleep $TIMEOUT seconds ..."
11478         sleep $TIMEOUT
11479         if ! ps -p $create_pid  > /dev/null 2>&1; then
11480                 do_facet mds1 $LCTL set_param fail_loc=0
11481                 do_facet mds1 $LCTL set_param fail_val=0
11482                 do_facet mds1 $LCTL set_param \
11483                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11484                 error "createmany finished incorrectly!"
11485         fi
11486         do_facet mds1 $LCTL set_param fail_loc=0
11487         do_facet mds1 $LCTL set_param fail_val=0
11488         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11489         wait $create_pid || return 1
11490
11491         unlinkmany $DIR/$tdir/f $nr
11492 }
11493 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11494
11495 test_140() { #bug-17379
11496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11497
11498         test_mkdir $DIR/$tdir
11499         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11500         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11501
11502         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11503         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11504         local i=0
11505         while i=$((i + 1)); do
11506                 test_mkdir $i
11507                 cd $i || error "Changing to $i"
11508                 ln -s ../stat stat || error "Creating stat symlink"
11509                 # Read the symlink until ELOOP present,
11510                 # not LBUGing the system is considered success,
11511                 # we didn't overrun the stack.
11512                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11513                 if [ $ret -ne 0 ]; then
11514                         if [ $ret -eq 40 ]; then
11515                                 break  # -ELOOP
11516                         else
11517                                 error "Open stat symlink"
11518                                         return
11519                         fi
11520                 fi
11521         done
11522         i=$((i - 1))
11523         echo "The symlink depth = $i"
11524         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11525                 error "Invalid symlink depth"
11526
11527         # Test recursive symlink
11528         ln -s symlink_self symlink_self
11529         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11530         echo "open symlink_self returns $ret"
11531         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11532 }
11533 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11534
11535 test_150() {
11536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11537
11538         local TF="$TMP/$tfile"
11539
11540         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11541         cp $TF $DIR/$tfile
11542         cancel_lru_locks $OSC
11543         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11544         remount_client $MOUNT
11545         df -P $MOUNT
11546         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11547
11548         $TRUNCATE $TF 6000
11549         $TRUNCATE $DIR/$tfile 6000
11550         cancel_lru_locks $OSC
11551         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11552
11553         echo "12345" >>$TF
11554         echo "12345" >>$DIR/$tfile
11555         cancel_lru_locks $OSC
11556         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11557
11558         echo "12345" >>$TF
11559         echo "12345" >>$DIR/$tfile
11560         cancel_lru_locks $OSC
11561         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11562
11563         rm -f $TF
11564         true
11565 }
11566 run_test 150 "truncate/append tests"
11567
11568 #LU-2902 roc_hit was not able to read all values from lproc
11569 function roc_hit_init() {
11570         local list=$(comma_list $(osts_nodes))
11571         local dir=$DIR/$tdir-check
11572         local file=$dir/$tfile
11573         local BEFORE
11574         local AFTER
11575         local idx
11576
11577         test_mkdir $dir
11578         #use setstripe to do a write to every ost
11579         for i in $(seq 0 $((OSTCOUNT-1))); do
11580                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11581                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11582                 idx=$(printf %04x $i)
11583                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11584                         awk '$1 == "cache_access" {sum += $7}
11585                                 END { printf("%0.0f", sum) }')
11586
11587                 cancel_lru_locks osc
11588                 cat $file >/dev/null
11589
11590                 AFTER=$(get_osd_param $list *OST*$idx stats |
11591                         awk '$1 == "cache_access" {sum += $7}
11592                                 END { printf("%0.0f", sum) }')
11593
11594                 echo BEFORE:$BEFORE AFTER:$AFTER
11595                 if ! let "AFTER - BEFORE == 4"; then
11596                         rm -rf $dir
11597                         error "roc_hit is not safe to use"
11598                 fi
11599                 rm $file
11600         done
11601
11602         rm -rf $dir
11603 }
11604
11605 function roc_hit() {
11606         local list=$(comma_list $(osts_nodes))
11607         echo $(get_osd_param $list '' stats |
11608                 awk '$1 == "cache_hit" {sum += $7}
11609                         END { printf("%0.0f", sum) }')
11610 }
11611
11612 function set_cache() {
11613         local on=1
11614
11615         if [ "$2" == "off" ]; then
11616                 on=0;
11617         fi
11618         local list=$(comma_list $(osts_nodes))
11619         set_osd_param $list '' $1_cache_enable $on
11620
11621         cancel_lru_locks osc
11622 }
11623
11624 test_151() {
11625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11626         remote_ost_nodsh && skip "remote OST with nodsh"
11627
11628         local CPAGES=3
11629         local list=$(comma_list $(osts_nodes))
11630
11631         # check whether obdfilter is cache capable at all
11632         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11633                 skip "not cache-capable obdfilter"
11634         fi
11635
11636         # check cache is enabled on all obdfilters
11637         if get_osd_param $list '' read_cache_enable | grep 0; then
11638                 skip "oss cache is disabled"
11639         fi
11640
11641         set_osd_param $list '' writethrough_cache_enable 1
11642
11643         # check write cache is enabled on all obdfilters
11644         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11645                 skip "oss write cache is NOT enabled"
11646         fi
11647
11648         roc_hit_init
11649
11650         #define OBD_FAIL_OBD_NO_LRU  0x609
11651         do_nodes $list $LCTL set_param fail_loc=0x609
11652
11653         # pages should be in the case right after write
11654         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11655                 error "dd failed"
11656
11657         local BEFORE=$(roc_hit)
11658         cancel_lru_locks osc
11659         cat $DIR/$tfile >/dev/null
11660         local AFTER=$(roc_hit)
11661
11662         do_nodes $list $LCTL set_param fail_loc=0
11663
11664         if ! let "AFTER - BEFORE == CPAGES"; then
11665                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11666         fi
11667
11668         # the following read invalidates the cache
11669         cancel_lru_locks osc
11670         set_osd_param $list '' read_cache_enable 0
11671         cat $DIR/$tfile >/dev/null
11672
11673         # now data shouldn't be found in the cache
11674         BEFORE=$(roc_hit)
11675         cancel_lru_locks osc
11676         cat $DIR/$tfile >/dev/null
11677         AFTER=$(roc_hit)
11678         if let "AFTER - BEFORE != 0"; then
11679                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11680         fi
11681
11682         set_osd_param $list '' read_cache_enable 1
11683         rm -f $DIR/$tfile
11684 }
11685 run_test 151 "test cache on oss and controls ==============================="
11686
11687 test_152() {
11688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11689
11690         local TF="$TMP/$tfile"
11691
11692         # simulate ENOMEM during write
11693 #define OBD_FAIL_OST_NOMEM      0x226
11694         lctl set_param fail_loc=0x80000226
11695         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11696         cp $TF $DIR/$tfile
11697         sync || error "sync failed"
11698         lctl set_param fail_loc=0
11699
11700         # discard client's cache
11701         cancel_lru_locks osc
11702
11703         # simulate ENOMEM during read
11704         lctl set_param fail_loc=0x80000226
11705         cmp $TF $DIR/$tfile || error "cmp failed"
11706         lctl set_param fail_loc=0
11707
11708         rm -f $TF
11709 }
11710 run_test 152 "test read/write with enomem ============================"
11711
11712 test_153() {
11713         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11714 }
11715 run_test 153 "test if fdatasync does not crash ======================="
11716
11717 dot_lustre_fid_permission_check() {
11718         local fid=$1
11719         local ffid=$MOUNT/.lustre/fid/$fid
11720         local test_dir=$2
11721
11722         echo "stat fid $fid"
11723         stat $ffid > /dev/null || error "stat $ffid failed."
11724         echo "touch fid $fid"
11725         touch $ffid || error "touch $ffid failed."
11726         echo "write to fid $fid"
11727         cat /etc/hosts > $ffid || error "write $ffid failed."
11728         echo "read fid $fid"
11729         diff /etc/hosts $ffid || error "read $ffid failed."
11730         echo "append write to fid $fid"
11731         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11732         echo "rename fid $fid"
11733         mv $ffid $test_dir/$tfile.1 &&
11734                 error "rename $ffid to $tfile.1 should fail."
11735         touch $test_dir/$tfile.1
11736         mv $test_dir/$tfile.1 $ffid &&
11737                 error "rename $tfile.1 to $ffid should fail."
11738         rm -f $test_dir/$tfile.1
11739         echo "truncate fid $fid"
11740         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11741         echo "link fid $fid"
11742         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11743         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11744                 echo "setfacl fid $fid"
11745                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11746                 echo "getfacl fid $fid"
11747                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11748         fi
11749         echo "unlink fid $fid"
11750         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11751         echo "mknod fid $fid"
11752         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11753
11754         fid=[0xf00000400:0x1:0x0]
11755         ffid=$MOUNT/.lustre/fid/$fid
11756
11757         echo "stat non-exist fid $fid"
11758         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11759         echo "write to non-exist fid $fid"
11760         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11761         echo "link new fid $fid"
11762         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11763
11764         mkdir -p $test_dir/$tdir
11765         touch $test_dir/$tdir/$tfile
11766         fid=$($LFS path2fid $test_dir/$tdir)
11767         rc=$?
11768         [ $rc -ne 0 ] &&
11769                 error "error: could not get fid for $test_dir/$dir/$tfile."
11770
11771         ffid=$MOUNT/.lustre/fid/$fid
11772
11773         echo "ls $fid"
11774         ls $ffid > /dev/null || error "ls $ffid failed."
11775         echo "touch $fid/$tfile.1"
11776         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11777
11778         echo "touch $MOUNT/.lustre/fid/$tfile"
11779         touch $MOUNT/.lustre/fid/$tfile && \
11780                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11781
11782         echo "setxattr to $MOUNT/.lustre/fid"
11783         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11784
11785         echo "listxattr for $MOUNT/.lustre/fid"
11786         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11787
11788         echo "delxattr from $MOUNT/.lustre/fid"
11789         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11790
11791         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11792         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11793                 error "touch invalid fid should fail."
11794
11795         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11796         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11797                 error "touch non-normal fid should fail."
11798
11799         echo "rename $tdir to $MOUNT/.lustre/fid"
11800         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11801                 error "rename to $MOUNT/.lustre/fid should fail."
11802
11803         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11804         then            # LU-3547
11805                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11806                 local new_obf_mode=777
11807
11808                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11809                 chmod $new_obf_mode $DIR/.lustre/fid ||
11810                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11811
11812                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11813                 [ $obf_mode -eq $new_obf_mode ] ||
11814                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11815
11816                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11817                 chmod $old_obf_mode $DIR/.lustre/fid ||
11818                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11819         fi
11820
11821         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11822         fid=$($LFS path2fid $test_dir/$tfile-2)
11823
11824         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11825         then # LU-5424
11826                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11827                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11828                         error "create lov data thru .lustre failed"
11829         fi
11830         echo "cp /etc/passwd $test_dir/$tfile-2"
11831         cp /etc/passwd $test_dir/$tfile-2 ||
11832                 error "copy to $test_dir/$tfile-2 failed."
11833         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11834         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11835                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11836
11837         rm -rf $test_dir/tfile.lnk
11838         rm -rf $test_dir/$tfile-2
11839 }
11840
11841 test_154A() {
11842         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11843                 skip "Need MDS version at least 2.4.1"
11844
11845         local tf=$DIR/$tfile
11846         touch $tf
11847
11848         local fid=$($LFS path2fid $tf)
11849         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11850
11851         # check that we get the same pathname back
11852         local found=$($LFS fid2path $MOUNT "$fid")
11853         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11854         [ "$found" == "$tf" ] ||
11855                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11856 }
11857 run_test 154A "lfs path2fid and fid2path basic checks"
11858
11859 test_154B() {
11860         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11861                 skip "Need MDS version at least 2.4.1"
11862
11863         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11864         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11865         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11866         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11867
11868         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11869         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11870
11871         # check that we get the same pathname
11872         echo "PFID: $PFID, name: $name"
11873         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11874         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11875         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11876                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11877
11878         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11879 }
11880 run_test 154B "verify the ll_decode_linkea tool"
11881
11882 test_154a() {
11883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11884         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11885         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11886                 skip "Need MDS version at least 2.2.51"
11887         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11888
11889         cp /etc/hosts $DIR/$tfile
11890
11891         fid=$($LFS path2fid $DIR/$tfile)
11892         rc=$?
11893         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11894
11895         dot_lustre_fid_permission_check "$fid" $DIR ||
11896                 error "dot lustre permission check $fid failed"
11897
11898         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11899
11900         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11901
11902         touch $MOUNT/.lustre/file &&
11903                 error "creation is not allowed under .lustre"
11904
11905         mkdir $MOUNT/.lustre/dir &&
11906                 error "mkdir is not allowed under .lustre"
11907
11908         rm -rf $DIR/$tfile
11909 }
11910 run_test 154a "Open-by-FID"
11911
11912 test_154b() {
11913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11914         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11916         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11917                 skip "Need MDS version at least 2.2.51"
11918
11919         local remote_dir=$DIR/$tdir/remote_dir
11920         local MDTIDX=1
11921         local rc=0
11922
11923         mkdir -p $DIR/$tdir
11924         $LFS mkdir -i $MDTIDX $remote_dir ||
11925                 error "create remote directory failed"
11926
11927         cp /etc/hosts $remote_dir/$tfile
11928
11929         fid=$($LFS path2fid $remote_dir/$tfile)
11930         rc=$?
11931         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11932
11933         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11934                 error "dot lustre permission check $fid failed"
11935         rm -rf $DIR/$tdir
11936 }
11937 run_test 154b "Open-by-FID for remote directory"
11938
11939 test_154c() {
11940         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11941                 skip "Need MDS version at least 2.4.1"
11942
11943         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11944         local FID1=$($LFS path2fid $DIR/$tfile.1)
11945         local FID2=$($LFS path2fid $DIR/$tfile.2)
11946         local FID3=$($LFS path2fid $DIR/$tfile.3)
11947
11948         local N=1
11949         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11950                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11951                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11952                 local want=FID$N
11953                 [ "$FID" = "${!want}" ] ||
11954                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11955                 N=$((N + 1))
11956         done
11957
11958         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11959         do
11960                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11961                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11962                 N=$((N + 1))
11963         done
11964 }
11965 run_test 154c "lfs path2fid and fid2path multiple arguments"
11966
11967 test_154d() {
11968         remote_mds_nodsh && skip "remote MDS with nodsh"
11969         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11970                 skip "Need MDS version at least 2.5.53"
11971
11972         if remote_mds; then
11973                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11974         else
11975                 nid="0@lo"
11976         fi
11977         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11978         local fd
11979         local cmd
11980
11981         rm -f $DIR/$tfile
11982         touch $DIR/$tfile
11983
11984         local fid=$($LFS path2fid $DIR/$tfile)
11985         # Open the file
11986         fd=$(free_fd)
11987         cmd="exec $fd<$DIR/$tfile"
11988         eval $cmd
11989         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11990         echo "$fid_list" | grep "$fid"
11991         rc=$?
11992
11993         cmd="exec $fd>/dev/null"
11994         eval $cmd
11995         if [ $rc -ne 0 ]; then
11996                 error "FID $fid not found in open files list $fid_list"
11997         fi
11998 }
11999 run_test 154d "Verify open file fid"
12000
12001 test_154e()
12002 {
12003         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12004                 skip "Need MDS version at least 2.6.50"
12005
12006         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12007                 error ".lustre returned by readdir"
12008         fi
12009 }
12010 run_test 154e ".lustre is not returned by readdir"
12011
12012 test_154f() {
12013         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12014
12015         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12016         test_mkdir -p -c1 $DIR/$tdir/d
12017         # test dirs inherit from its stripe
12018         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12019         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12020         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12021         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12022         touch $DIR/f
12023
12024         # get fid of parents
12025         local FID0=$($LFS path2fid $DIR/$tdir/d)
12026         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12027         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12028         local FID3=$($LFS path2fid $DIR)
12029
12030         # check that path2fid --parents returns expected <parent_fid>/name
12031         # 1) test for a directory (single parent)
12032         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12033         [ "$parent" == "$FID0/foo1" ] ||
12034                 error "expected parent: $FID0/foo1, got: $parent"
12035
12036         # 2) test for a file with nlink > 1 (multiple parents)
12037         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12038         echo "$parent" | grep -F "$FID1/$tfile" ||
12039                 error "$FID1/$tfile not returned in parent list"
12040         echo "$parent" | grep -F "$FID2/link" ||
12041                 error "$FID2/link not returned in parent list"
12042
12043         # 3) get parent by fid
12044         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12045         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12046         echo "$parent" | grep -F "$FID1/$tfile" ||
12047                 error "$FID1/$tfile not returned in parent list (by fid)"
12048         echo "$parent" | grep -F "$FID2/link" ||
12049                 error "$FID2/link not returned in parent list (by fid)"
12050
12051         # 4) test for entry in root directory
12052         parent=$($LFS path2fid --parents $DIR/f)
12053         echo "$parent" | grep -F "$FID3/f" ||
12054                 error "$FID3/f not returned in parent list"
12055
12056         # 5) test it on root directory
12057         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12058                 error "$MOUNT should not have parents"
12059
12060         # enable xattr caching and check that linkea is correctly updated
12061         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12062         save_lustre_params client "llite.*.xattr_cache" > $save
12063         lctl set_param llite.*.xattr_cache 1
12064
12065         # 6.1) linkea update on rename
12066         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12067
12068         # get parents by fid
12069         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12070         # foo1 should no longer be returned in parent list
12071         echo "$parent" | grep -F "$FID1" &&
12072                 error "$FID1 should no longer be in parent list"
12073         # the new path should appear
12074         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12075                 error "$FID2/$tfile.moved is not in parent list"
12076
12077         # 6.2) linkea update on unlink
12078         rm -f $DIR/$tdir/d/foo2/link
12079         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12080         # foo2/link should no longer be returned in parent list
12081         echo "$parent" | grep -F "$FID2/link" &&
12082                 error "$FID2/link should no longer be in parent list"
12083         true
12084
12085         rm -f $DIR/f
12086         restore_lustre_params < $save
12087         rm -f $save
12088 }
12089 run_test 154f "get parent fids by reading link ea"
12090
12091 test_154g()
12092 {
12093         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12094         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12095            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12096                 skip "Need MDS version at least 2.6.92"
12097
12098         mkdir -p $DIR/$tdir
12099         llapi_fid_test -d $DIR/$tdir
12100 }
12101 run_test 154g "various llapi FID tests"
12102
12103 test_155_small_load() {
12104     local temp=$TMP/$tfile
12105     local file=$DIR/$tfile
12106
12107     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12108         error "dd of=$temp bs=6096 count=1 failed"
12109     cp $temp $file
12110     cancel_lru_locks $OSC
12111     cmp $temp $file || error "$temp $file differ"
12112
12113     $TRUNCATE $temp 6000
12114     $TRUNCATE $file 6000
12115     cmp $temp $file || error "$temp $file differ (truncate1)"
12116
12117     echo "12345" >>$temp
12118     echo "12345" >>$file
12119     cmp $temp $file || error "$temp $file differ (append1)"
12120
12121     echo "12345" >>$temp
12122     echo "12345" >>$file
12123     cmp $temp $file || error "$temp $file differ (append2)"
12124
12125     rm -f $temp $file
12126     true
12127 }
12128
12129 test_155_big_load() {
12130         remote_ost_nodsh && skip "remote OST with nodsh"
12131
12132         local temp=$TMP/$tfile
12133         local file=$DIR/$tfile
12134
12135         free_min_max
12136         local cache_size=$(do_facet ost$((MAXI+1)) \
12137                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12138         local large_file_size=$((cache_size * 2))
12139
12140         echo "OSS cache size: $cache_size KB"
12141         echo "Large file size: $large_file_size KB"
12142
12143         [ $MAXV -le $large_file_size ] &&
12144                 skip_env "max available OST size needs > $large_file_size KB"
12145
12146         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12147
12148         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12149                 error "dd of=$temp bs=$large_file_size count=1k failed"
12150         cp $temp $file
12151         ls -lh $temp $file
12152         cancel_lru_locks osc
12153         cmp $temp $file || error "$temp $file differ"
12154
12155         rm -f $temp $file
12156         true
12157 }
12158
12159 save_writethrough() {
12160         local facets=$(get_facets OST)
12161
12162         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12163 }
12164
12165 test_155a() {
12166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12167
12168         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12169
12170         save_writethrough $p
12171
12172         set_cache read on
12173         set_cache writethrough on
12174         test_155_small_load
12175         restore_lustre_params < $p
12176         rm -f $p
12177 }
12178 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12179
12180 test_155b() {
12181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12182
12183         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12184
12185         save_writethrough $p
12186
12187         set_cache read on
12188         set_cache writethrough off
12189         test_155_small_load
12190         restore_lustre_params < $p
12191         rm -f $p
12192 }
12193 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12194
12195 test_155c() {
12196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12197
12198         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12199
12200         save_writethrough $p
12201
12202         set_cache read off
12203         set_cache writethrough on
12204         test_155_small_load
12205         restore_lustre_params < $p
12206         rm -f $p
12207 }
12208 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12209
12210 test_155d() {
12211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12212
12213         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12214
12215         save_writethrough $p
12216
12217         set_cache read off
12218         set_cache writethrough off
12219         test_155_small_load
12220         restore_lustre_params < $p
12221         rm -f $p
12222 }
12223 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12224
12225 test_155e() {
12226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12227
12228         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12229
12230         save_writethrough $p
12231
12232         set_cache read on
12233         set_cache writethrough on
12234         test_155_big_load
12235         restore_lustre_params < $p
12236         rm -f $p
12237 }
12238 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12239
12240 test_155f() {
12241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12242
12243         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12244
12245         save_writethrough $p
12246
12247         set_cache read on
12248         set_cache writethrough off
12249         test_155_big_load
12250         restore_lustre_params < $p
12251         rm -f $p
12252 }
12253 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12254
12255 test_155g() {
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257
12258         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12259
12260         save_writethrough $p
12261
12262         set_cache read off
12263         set_cache writethrough on
12264         test_155_big_load
12265         restore_lustre_params < $p
12266         rm -f $p
12267 }
12268 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12269
12270 test_155h() {
12271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12272
12273         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12274
12275         save_writethrough $p
12276
12277         set_cache read off
12278         set_cache writethrough off
12279         test_155_big_load
12280         restore_lustre_params < $p
12281         rm -f $p
12282 }
12283 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12284
12285 test_156() {
12286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12287         remote_ost_nodsh && skip "remote OST with nodsh"
12288         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12289                 skip "stats not implemented on old servers"
12290         [ "$ost1_FSTYPE" = "zfs" ] &&
12291                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12292
12293         local CPAGES=3
12294         local BEFORE
12295         local AFTER
12296         local file="$DIR/$tfile"
12297         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12298
12299         save_writethrough $p
12300         roc_hit_init
12301
12302         log "Turn on read and write cache"
12303         set_cache read on
12304         set_cache writethrough on
12305
12306         log "Write data and read it back."
12307         log "Read should be satisfied from the cache."
12308         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12309         BEFORE=$(roc_hit)
12310         cancel_lru_locks osc
12311         cat $file >/dev/null
12312         AFTER=$(roc_hit)
12313         if ! let "AFTER - BEFORE == CPAGES"; then
12314                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12315         else
12316                 log "cache hits:: before: $BEFORE, after: $AFTER"
12317         fi
12318
12319         log "Read again; it should be satisfied from the cache."
12320         BEFORE=$AFTER
12321         cancel_lru_locks osc
12322         cat $file >/dev/null
12323         AFTER=$(roc_hit)
12324         if ! let "AFTER - BEFORE == CPAGES"; then
12325                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12326         else
12327                 log "cache hits:: before: $BEFORE, after: $AFTER"
12328         fi
12329
12330         log "Turn off the read cache and turn on the write cache"
12331         set_cache read off
12332         set_cache writethrough on
12333
12334         log "Read again; it should be satisfied from the cache."
12335         BEFORE=$(roc_hit)
12336         cancel_lru_locks osc
12337         cat $file >/dev/null
12338         AFTER=$(roc_hit)
12339         if ! let "AFTER - BEFORE == CPAGES"; then
12340                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12341         else
12342                 log "cache hits:: before: $BEFORE, after: $AFTER"
12343         fi
12344
12345         log "Read again; it should not be satisfied from the cache."
12346         BEFORE=$AFTER
12347         cancel_lru_locks osc
12348         cat $file >/dev/null
12349         AFTER=$(roc_hit)
12350         if ! let "AFTER - BEFORE == 0"; then
12351                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12352         else
12353                 log "cache hits:: before: $BEFORE, after: $AFTER"
12354         fi
12355
12356         log "Write data and read it back."
12357         log "Read should be satisfied from the cache."
12358         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12359         BEFORE=$(roc_hit)
12360         cancel_lru_locks osc
12361         cat $file >/dev/null
12362         AFTER=$(roc_hit)
12363         if ! let "AFTER - BEFORE == CPAGES"; then
12364                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12365         else
12366                 log "cache hits:: before: $BEFORE, after: $AFTER"
12367         fi
12368
12369         log "Read again; it should not be satisfied from the cache."
12370         BEFORE=$AFTER
12371         cancel_lru_locks osc
12372         cat $file >/dev/null
12373         AFTER=$(roc_hit)
12374         if ! let "AFTER - BEFORE == 0"; then
12375                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12376         else
12377                 log "cache hits:: before: $BEFORE, after: $AFTER"
12378         fi
12379
12380         log "Turn off read and write cache"
12381         set_cache read off
12382         set_cache writethrough off
12383
12384         log "Write data and read it back"
12385         log "It should not be satisfied from the cache."
12386         rm -f $file
12387         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12388         cancel_lru_locks osc
12389         BEFORE=$(roc_hit)
12390         cat $file >/dev/null
12391         AFTER=$(roc_hit)
12392         if ! let "AFTER - BEFORE == 0"; then
12393                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12394         else
12395                 log "cache hits:: before: $BEFORE, after: $AFTER"
12396         fi
12397
12398         log "Turn on the read cache and turn off the write cache"
12399         set_cache read on
12400         set_cache writethrough off
12401
12402         log "Write data and read it back"
12403         log "It should not be satisfied from the cache."
12404         rm -f $file
12405         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12406         BEFORE=$(roc_hit)
12407         cancel_lru_locks osc
12408         cat $file >/dev/null
12409         AFTER=$(roc_hit)
12410         if ! let "AFTER - BEFORE == 0"; then
12411                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12412         else
12413                 log "cache hits:: before: $BEFORE, after: $AFTER"
12414         fi
12415
12416         log "Read again; it should be satisfied from the cache."
12417         BEFORE=$(roc_hit)
12418         cancel_lru_locks osc
12419         cat $file >/dev/null
12420         AFTER=$(roc_hit)
12421         if ! let "AFTER - BEFORE == CPAGES"; then
12422                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12423         else
12424                 log "cache hits:: before: $BEFORE, after: $AFTER"
12425         fi
12426
12427         restore_lustre_params < $p
12428         rm -f $p $file
12429 }
12430 run_test 156 "Verification of tunables"
12431
12432 test_160a() {
12433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12434         remote_mds_nodsh && skip "remote MDS with nodsh"
12435         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12436                 skip "Need MDS version at least 2.2.0"
12437
12438         changelog_register || error "changelog_register failed"
12439         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12440         changelog_users $SINGLEMDS | grep -q $cl_user ||
12441                 error "User $cl_user not found in changelog_users"
12442
12443         # change something
12444         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12445         changelog_clear 0 || error "changelog_clear failed"
12446         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12447         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12448         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12449         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12450         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12451         rm $DIR/$tdir/pics/desktop.jpg
12452
12453         changelog_dump | tail -10
12454
12455         echo "verifying changelog mask"
12456         changelog_chmask "-MKDIR"
12457         changelog_chmask "-CLOSE"
12458
12459         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12460         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12461
12462         changelog_chmask "+MKDIR"
12463         changelog_chmask "+CLOSE"
12464
12465         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12466         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12467
12468         changelog_dump | tail -10
12469         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12470         CLOSES=$(changelog_dump | grep -c "CLOSE")
12471         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12472         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12473
12474         # verify contents
12475         echo "verifying target fid"
12476         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12477         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12478         [ "$fidc" == "$fidf" ] ||
12479                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12480         echo "verifying parent fid"
12481         # The FID returned from the Changelog may be the directory shard on
12482         # a different MDT, and not the FID returned by path2fid on the parent.
12483         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12484         # since this is what will matter when recreating this file in the tree.
12485         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12486         local pathp=$($LFS fid2path $MOUNT "$fidp")
12487         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12488                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12489
12490         echo "getting records for $cl_user"
12491         changelog_users $SINGLEMDS
12492         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12493         local nclr=3
12494         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12495                 error "changelog_clear failed"
12496         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12497         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12498         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12499                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12500
12501         local min0_rec=$(changelog_users $SINGLEMDS |
12502                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12503         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12504                           awk '{ print $1; exit; }')
12505
12506         changelog_dump | tail -n 5
12507         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12508         [ $first_rec == $((min0_rec + 1)) ] ||
12509                 error "first index should be $min0_rec + 1 not $first_rec"
12510
12511         # LU-3446 changelog index reset on MDT restart
12512         local cur_rec1=$(changelog_users $SINGLEMDS |
12513                          awk '/^current.index:/ { print $NF }')
12514         changelog_clear 0 ||
12515                 error "clear all changelog records for $cl_user failed"
12516         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12517         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12518                 error "Fail to start $SINGLEMDS"
12519         local cur_rec2=$(changelog_users $SINGLEMDS |
12520                          awk '/^current.index:/ { print $NF }')
12521         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12522         [ $cur_rec1 == $cur_rec2 ] ||
12523                 error "current index should be $cur_rec1 not $cur_rec2"
12524
12525         echo "verifying users from this test are deregistered"
12526         changelog_deregister || error "changelog_deregister failed"
12527         changelog_users $SINGLEMDS | grep -q $cl_user &&
12528                 error "User '$cl_user' still in changelog_users"
12529
12530         # lctl get_param -n mdd.*.changelog_users
12531         # current index: 144
12532         # ID    index (idle seconds)
12533         # cl3   144 (2)
12534         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12535                 # this is the normal case where all users were deregistered
12536                 # make sure no new records are added when no users are present
12537                 local last_rec1=$(changelog_users $SINGLEMDS |
12538                                   awk '/^current.index:/ { print $NF }')
12539                 touch $DIR/$tdir/chloe
12540                 local last_rec2=$(changelog_users $SINGLEMDS |
12541                                   awk '/^current.index:/ { print $NF }')
12542                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12543                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12544         else
12545                 # any changelog users must be leftovers from a previous test
12546                 changelog_users $SINGLEMDS
12547                 echo "other changelog users; can't verify off"
12548         fi
12549 }
12550 run_test 160a "changelog sanity"
12551
12552 test_160b() { # LU-3587
12553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12554         remote_mds_nodsh && skip "remote MDS with nodsh"
12555         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12556                 skip "Need MDS version at least 2.2.0"
12557
12558         changelog_register || error "changelog_register failed"
12559         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12560         changelog_users $SINGLEMDS | grep -q $cl_user ||
12561                 error "User '$cl_user' not found in changelog_users"
12562
12563         local longname1=$(str_repeat a 255)
12564         local longname2=$(str_repeat b 255)
12565
12566         cd $DIR
12567         echo "creating very long named file"
12568         touch $longname1 || error "create of '$longname1' failed"
12569         echo "renaming very long named file"
12570         mv $longname1 $longname2
12571
12572         changelog_dump | grep RENME | tail -n 5
12573         rm -f $longname2
12574 }
12575 run_test 160b "Verify that very long rename doesn't crash in changelog"
12576
12577 test_160c() {
12578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12579         remote_mds_nodsh && skip "remote MDS with nodsh"
12580
12581         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12582                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12583                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12584                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12585
12586         local rc=0
12587
12588         # Registration step
12589         changelog_register || error "changelog_register failed"
12590
12591         rm -rf $DIR/$tdir
12592         mkdir -p $DIR/$tdir
12593         $MCREATE $DIR/$tdir/foo_160c
12594         changelog_chmask "-TRUNC"
12595         $TRUNCATE $DIR/$tdir/foo_160c 200
12596         changelog_chmask "+TRUNC"
12597         $TRUNCATE $DIR/$tdir/foo_160c 199
12598         changelog_dump | tail -n 5
12599         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12600         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12601 }
12602 run_test 160c "verify that changelog log catch the truncate event"
12603
12604 test_160d() {
12605         remote_mds_nodsh && skip "remote MDS with nodsh"
12606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12608         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12609                 skip "Need MDS version at least 2.7.60"
12610
12611         # Registration step
12612         changelog_register || error "changelog_register failed"
12613
12614         mkdir -p $DIR/$tdir/migrate_dir
12615         changelog_clear 0 || error "changelog_clear failed"
12616
12617         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12618         changelog_dump | tail -n 5
12619         local migrates=$(changelog_dump | grep -c "MIGRT")
12620         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12621 }
12622 run_test 160d "verify that changelog log catch the migrate event"
12623
12624 test_160e() {
12625         remote_mds_nodsh && skip "remote MDS with nodsh"
12626
12627         # Create a user
12628         changelog_register || error "changelog_register failed"
12629
12630         # Delete a future user (expect fail)
12631         local MDT0=$(facet_svc $SINGLEMDS)
12632         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12633         local rc=$?
12634
12635         if [ $rc -eq 0 ]; then
12636                 error "Deleted non-existant user cl77"
12637         elif [ $rc -ne 2 ]; then
12638                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12639         fi
12640
12641         # Clear to a bad index (1 billion should be safe)
12642         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12643         rc=$?
12644
12645         if [ $rc -eq 0 ]; then
12646                 error "Successfully cleared to invalid CL index"
12647         elif [ $rc -ne 22 ]; then
12648                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12649         fi
12650 }
12651 run_test 160e "changelog negative testing (should return errors)"
12652
12653 test_160f() {
12654         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12655         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12656                 skip "Need MDS version at least 2.10.56"
12657
12658         local mdts=$(comma_list $(mdts_nodes))
12659
12660         # Create a user
12661         changelog_register || error "first changelog_register failed"
12662         changelog_register || error "second changelog_register failed"
12663         local cl_users
12664         declare -A cl_user1
12665         declare -A cl_user2
12666         local user_rec1
12667         local user_rec2
12668         local i
12669
12670         # generate some changelog records to accumulate on each MDT
12671         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12672         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12673                 error "create $DIR/$tdir/$tfile failed"
12674
12675         # check changelogs have been generated
12676         local nbcl=$(changelog_dump | wc -l)
12677         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12678
12679         for param in "changelog_max_idle_time=10" \
12680                      "changelog_gc=1" \
12681                      "changelog_min_gc_interval=2" \
12682                      "changelog_min_free_cat_entries=3"; do
12683                 local MDT0=$(facet_svc $SINGLEMDS)
12684                 local var="${param%=*}"
12685                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12686
12687                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12688                 do_nodes $mdts $LCTL set_param mdd.*.$param
12689         done
12690
12691         # force cl_user2 to be idle (1st part)
12692         sleep 9
12693
12694         # simulate changelog catalog almost full
12695         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12696         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12697
12698         for i in $(seq $MDSCOUNT); do
12699                 cl_users=(${CL_USERS[mds$i]})
12700                 cl_user1[mds$i]="${cl_users[0]}"
12701                 cl_user2[mds$i]="${cl_users[1]}"
12702
12703                 [ -n "${cl_user1[mds$i]}" ] ||
12704                         error "mds$i: no user registered"
12705                 [ -n "${cl_user2[mds$i]}" ] ||
12706                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12707
12708                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12709                 [ -n "$user_rec1" ] ||
12710                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12711                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12712                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12713                 [ -n "$user_rec2" ] ||
12714                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12715                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12716                      "$user_rec1 + 2 == $user_rec2"
12717                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12718                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12719                               "$user_rec1 + 2, but is $user_rec2"
12720                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12721                 [ -n "$user_rec2" ] ||
12722                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12723                 [ $user_rec1 == $user_rec2 ] ||
12724                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12725                               "$user_rec1, but is $user_rec2"
12726         done
12727
12728         # force cl_user2 to be idle (2nd part) and to reach
12729         # changelog_max_idle_time
12730         sleep 2
12731
12732         # generate one more changelog to trigger fail_loc
12733         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12734                 error "create $DIR/$tdir/${tfile}bis failed"
12735
12736         # ensure gc thread is done
12737         for i in $(mdts_nodes); do
12738                 wait_update $i \
12739                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12740                         error "$i: GC-thread not done"
12741         done
12742
12743         local first_rec
12744         for i in $(seq $MDSCOUNT); do
12745                 # check cl_user1 still registered
12746                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12747                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12748                 # check cl_user2 unregistered
12749                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12750                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12751
12752                 # check changelogs are present and starting at $user_rec1 + 1
12753                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12754                 [ -n "$user_rec1" ] ||
12755                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12756                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12757                             awk '{ print $1; exit; }')
12758
12759                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12760                 [ $((user_rec1 + 1)) == $first_rec ] ||
12761                         error "mds$i: first index should be $user_rec1 + 1, " \
12762                               "but is $first_rec"
12763         done
12764 }
12765 run_test 160f "changelog garbage collect (timestamped users)"
12766
12767 test_160g() {
12768         remote_mds_nodsh && skip "remote MDS with nodsh"
12769         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12770                 skip "Need MDS version at least 2.10.56"
12771
12772         local mdts=$(comma_list $(mdts_nodes))
12773
12774         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12775         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12776
12777         # Create a user
12778         changelog_register || error "first changelog_register failed"
12779         changelog_register || error "second changelog_register failed"
12780         local cl_users
12781         declare -A cl_user1
12782         declare -A cl_user2
12783         local user_rec1
12784         local user_rec2
12785         local i
12786
12787         # generate some changelog records to accumulate on each MDT
12788         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12789         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12790                 error "create $DIR/$tdir/$tfile failed"
12791
12792         # check changelogs have been generated
12793         local nbcl=$(changelog_dump | wc -l)
12794         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12795
12796         # reduce the max_idle_indexes value to make sure we exceed it
12797         max_ndx=$((nbcl / 2 - 1))
12798
12799         for param in "changelog_max_idle_indexes=$max_ndx" \
12800                      "changelog_gc=1" \
12801                      "changelog_min_gc_interval=2" \
12802                      "changelog_min_free_cat_entries=3"; do
12803                 local MDT0=$(facet_svc $SINGLEMDS)
12804                 local var="${param%=*}"
12805                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12806
12807                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12808                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12809                         error "unable to set mdd.*.$param"
12810         done
12811
12812         # simulate changelog catalog almost full
12813         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12814         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12815
12816         for i in $(seq $MDSCOUNT); do
12817                 cl_users=(${CL_USERS[mds$i]})
12818                 cl_user1[mds$i]="${cl_users[0]}"
12819                 cl_user2[mds$i]="${cl_users[1]}"
12820
12821                 [ -n "${cl_user1[mds$i]}" ] ||
12822                         error "mds$i: no user registered"
12823                 [ -n "${cl_user2[mds$i]}" ] ||
12824                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12825
12826                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12827                 [ -n "$user_rec1" ] ||
12828                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12829                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12830                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12831                 [ -n "$user_rec2" ] ||
12832                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12833                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12834                      "$user_rec1 + 2 == $user_rec2"
12835                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12836                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12837                               "$user_rec1 + 2, but is $user_rec2"
12838                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12839                 [ -n "$user_rec2" ] ||
12840                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12841                 [ $user_rec1 == $user_rec2 ] ||
12842                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12843                               "$user_rec1, but is $user_rec2"
12844         done
12845
12846         # ensure we are past the previous changelog_min_gc_interval set above
12847         sleep 2
12848
12849         # generate one more changelog to trigger fail_loc
12850         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12851                 error "create $DIR/$tdir/${tfile}bis failed"
12852
12853         # ensure gc thread is done
12854         for i in $(mdts_nodes); do
12855                 wait_update $i \
12856                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12857                         error "$i: GC-thread not done"
12858         done
12859
12860         local first_rec
12861         for i in $(seq $MDSCOUNT); do
12862                 # check cl_user1 still registered
12863                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12865                 # check cl_user2 unregistered
12866                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12867                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12868
12869                 # check changelogs are present and starting at $user_rec1 + 1
12870                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12871                 [ -n "$user_rec1" ] ||
12872                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12873                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12874                             awk '{ print $1; exit; }')
12875
12876                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12877                 [ $((user_rec1 + 1)) == $first_rec ] ||
12878                         error "mds$i: first index should be $user_rec1 + 1, " \
12879                               "but is $first_rec"
12880         done
12881 }
12882 run_test 160g "changelog garbage collect (old users)"
12883
12884 test_160h() {
12885         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12886         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12887                 skip "Need MDS version at least 2.10.56"
12888
12889         local mdts=$(comma_list $(mdts_nodes))
12890
12891         # Create a user
12892         changelog_register || error "first changelog_register failed"
12893         changelog_register || error "second changelog_register failed"
12894         local cl_users
12895         declare -A cl_user1
12896         declare -A cl_user2
12897         local user_rec1
12898         local user_rec2
12899         local i
12900
12901         # generate some changelog records to accumulate on each MDT
12902         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12903         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12904                 error "create $DIR/$tdir/$tfile failed"
12905
12906         # check changelogs have been generated
12907         local nbcl=$(changelog_dump | wc -l)
12908         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12909
12910         for param in "changelog_max_idle_time=10" \
12911                      "changelog_gc=1" \
12912                      "changelog_min_gc_interval=2"; do
12913                 local MDT0=$(facet_svc $SINGLEMDS)
12914                 local var="${param%=*}"
12915                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12916
12917                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12918                 do_nodes $mdts $LCTL set_param mdd.*.$param
12919         done
12920
12921         # force cl_user2 to be idle (1st part)
12922         sleep 9
12923
12924         for i in $(seq $MDSCOUNT); do
12925                 cl_users=(${CL_USERS[mds$i]})
12926                 cl_user1[mds$i]="${cl_users[0]}"
12927                 cl_user2[mds$i]="${cl_users[1]}"
12928
12929                 [ -n "${cl_user1[mds$i]}" ] ||
12930                         error "mds$i: no user registered"
12931                 [ -n "${cl_user2[mds$i]}" ] ||
12932                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12933
12934                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12935                 [ -n "$user_rec1" ] ||
12936                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12937                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12938                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12939                 [ -n "$user_rec2" ] ||
12940                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12941                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12942                      "$user_rec1 + 2 == $user_rec2"
12943                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12944                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12945                               "$user_rec1 + 2, but is $user_rec2"
12946                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12947                 [ -n "$user_rec2" ] ||
12948                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12949                 [ $user_rec1 == $user_rec2 ] ||
12950                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12951                               "$user_rec1, but is $user_rec2"
12952         done
12953
12954         # force cl_user2 to be idle (2nd part) and to reach
12955         # changelog_max_idle_time
12956         sleep 2
12957
12958         # force each GC-thread start and block then
12959         # one per MDT/MDD, set fail_val accordingly
12960         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12961         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12962
12963         # generate more changelogs to trigger fail_loc
12964         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12965                 error "create $DIR/$tdir/${tfile}bis failed"
12966
12967         # stop MDT to stop GC-thread, should be done in back-ground as it will
12968         # block waiting for the thread to be released and exit
12969         declare -A stop_pids
12970         for i in $(seq $MDSCOUNT); do
12971                 stop mds$i &
12972                 stop_pids[mds$i]=$!
12973         done
12974
12975         for i in $(mdts_nodes); do
12976                 local facet
12977                 local nb=0
12978                 local facets=$(facets_up_on_host $i)
12979
12980                 for facet in ${facets//,/ }; do
12981                         if [[ $facet == mds* ]]; then
12982                                 nb=$((nb + 1))
12983                         fi
12984                 done
12985                 # ensure each MDS's gc threads are still present and all in "R"
12986                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12987                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12988                         error "$i: expected $nb GC-thread"
12989                 wait_update $i \
12990                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12991                         "R" 20 ||
12992                         error "$i: GC-thread not found in R-state"
12993                 # check umounts of each MDT on MDS have reached kthread_stop()
12994                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12995                         error "$i: expected $nb umount"
12996                 wait_update $i \
12997                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12998                         error "$i: umount not found in D-state"
12999         done
13000
13001         # release all GC-threads
13002         do_nodes $mdts $LCTL set_param fail_loc=0
13003
13004         # wait for MDT stop to complete
13005         for i in $(seq $MDSCOUNT); do
13006                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13007         done
13008
13009         # XXX
13010         # may try to check if any orphan changelog records are present
13011         # via ldiskfs/zfs and llog_reader...
13012
13013         # re-start/mount MDTs
13014         for i in $(seq $MDSCOUNT); do
13015                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13016                         error "Fail to start mds$i"
13017         done
13018
13019         local first_rec
13020         for i in $(seq $MDSCOUNT); do
13021                 # check cl_user1 still registered
13022                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13023                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13024                 # check cl_user2 unregistered
13025                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13026                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13027
13028                 # check changelogs are present and starting at $user_rec1 + 1
13029                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13030                 [ -n "$user_rec1" ] ||
13031                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13032                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13033                             awk '{ print $1; exit; }')
13034
13035                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13036                 [ $((user_rec1 + 1)) == $first_rec ] ||
13037                         error "mds$i: first index should be $user_rec1 + 1, " \
13038                               "but is $first_rec"
13039         done
13040 }
13041 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13042               "during mount"
13043
13044 test_160i() {
13045
13046         local mdts=$(comma_list $(mdts_nodes))
13047
13048         changelog_register || error "first changelog_register failed"
13049
13050         # generate some changelog records to accumulate on each MDT
13051         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13052         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13053                 error "create $DIR/$tdir/$tfile failed"
13054
13055         # check changelogs have been generated
13056         local nbcl=$(changelog_dump | wc -l)
13057         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13058
13059         # simulate race between register and unregister
13060         # XXX as fail_loc is set per-MDS, with DNE configs the race
13061         # simulation will only occur for one MDT per MDS and for the
13062         # others the normal race scenario will take place
13063         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13064         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13065         do_nodes $mdts $LCTL set_param fail_val=1
13066
13067         # unregister 1st user
13068         changelog_deregister &
13069         local pid1=$!
13070         # wait some time for deregister work to reach race rdv
13071         sleep 2
13072         # register 2nd user
13073         changelog_register || error "2nd user register failed"
13074
13075         wait $pid1 || error "1st user deregister failed"
13076
13077         local i
13078         local last_rec
13079         declare -A LAST_REC
13080         for i in $(seq $MDSCOUNT); do
13081                 if changelog_users mds$i | grep "^cl"; then
13082                         # make sure new records are added with one user present
13083                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13084                                           awk '/^current.index:/ { print $NF }')
13085                 else
13086                         error "mds$i has no user registered"
13087                 fi
13088         done
13089
13090         # generate more changelog records to accumulate on each MDT
13091         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13092                 error "create $DIR/$tdir/${tfile}bis failed"
13093
13094         for i in $(seq $MDSCOUNT); do
13095                 last_rec=$(changelog_users $SINGLEMDS |
13096                            awk '/^current.index:/ { print $NF }')
13097                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13098                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13099                         error "changelogs are off on mds$i"
13100         done
13101 }
13102 run_test 160i "changelog user register/unregister race"
13103
13104 test_161a() {
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106
13107         test_mkdir -c1 $DIR/$tdir
13108         cp /etc/hosts $DIR/$tdir/$tfile
13109         test_mkdir -c1 $DIR/$tdir/foo1
13110         test_mkdir -c1 $DIR/$tdir/foo2
13111         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13112         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13113         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13114         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13115         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13116         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13117                 $LFS fid2path $DIR $FID
13118                 error "bad link ea"
13119         fi
13120         # middle
13121         rm $DIR/$tdir/foo2/zachary
13122         # last
13123         rm $DIR/$tdir/foo2/thor
13124         # first
13125         rm $DIR/$tdir/$tfile
13126         # rename
13127         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13128         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13129                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13130         rm $DIR/$tdir/foo2/maggie
13131
13132         # overflow the EA
13133         local longname=$tfile.avg_len_is_thirty_two_
13134         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13135                 error_noexit 'failed to unlink many hardlinks'" EXIT
13136         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13137                 error "failed to hardlink many files"
13138         links=$($LFS fid2path $DIR $FID | wc -l)
13139         echo -n "${links}/1000 links in link EA"
13140         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13141 }
13142 run_test 161a "link ea sanity"
13143
13144 test_161b() {
13145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13146         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13147
13148         local MDTIDX=1
13149         local remote_dir=$DIR/$tdir/remote_dir
13150
13151         mkdir -p $DIR/$tdir
13152         $LFS mkdir -i $MDTIDX $remote_dir ||
13153                 error "create remote directory failed"
13154
13155         cp /etc/hosts $remote_dir/$tfile
13156         mkdir -p $remote_dir/foo1
13157         mkdir -p $remote_dir/foo2
13158         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13159         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13160         ln $remote_dir/$tfile $remote_dir/foo1/luna
13161         ln $remote_dir/$tfile $remote_dir/foo2/thor
13162
13163         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13164                      tr -d ']')
13165         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13166                 $LFS fid2path $DIR $FID
13167                 error "bad link ea"
13168         fi
13169         # middle
13170         rm $remote_dir/foo2/zachary
13171         # last
13172         rm $remote_dir/foo2/thor
13173         # first
13174         rm $remote_dir/$tfile
13175         # rename
13176         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13177         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13178         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13179                 $LFS fid2path $DIR $FID
13180                 error "bad link rename"
13181         fi
13182         rm $remote_dir/foo2/maggie
13183
13184         # overflow the EA
13185         local longname=filename_avg_len_is_thirty_two_
13186         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13187                 error "failed to hardlink many files"
13188         links=$($LFS fid2path $DIR $FID | wc -l)
13189         echo -n "${links}/1000 links in link EA"
13190         [[ ${links} -gt 60 ]] ||
13191                 error "expected at least 60 links in link EA"
13192         unlinkmany $remote_dir/foo2/$longname 1000 ||
13193         error "failed to unlink many hardlinks"
13194 }
13195 run_test 161b "link ea sanity under remote directory"
13196
13197 test_161c() {
13198         remote_mds_nodsh && skip "remote MDS with nodsh"
13199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13200         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13201                 skip "Need MDS version at least 2.1.5"
13202
13203         # define CLF_RENAME_LAST 0x0001
13204         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13205         changelog_register || error "changelog_register failed"
13206
13207         rm -rf $DIR/$tdir
13208         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13209         touch $DIR/$tdir/foo_161c
13210         touch $DIR/$tdir/bar_161c
13211         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13212         changelog_dump | grep RENME | tail -n 5
13213         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13214         changelog_clear 0 || error "changelog_clear failed"
13215         if [ x$flags != "x0x1" ]; then
13216                 error "flag $flags is not 0x1"
13217         fi
13218
13219         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13220         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13221         touch $DIR/$tdir/foo_161c
13222         touch $DIR/$tdir/bar_161c
13223         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13224         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13225         changelog_dump | grep RENME | tail -n 5
13226         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13227         changelog_clear 0 || error "changelog_clear failed"
13228         if [ x$flags != "x0x0" ]; then
13229                 error "flag $flags is not 0x0"
13230         fi
13231         echo "rename overwrite a target having nlink > 1," \
13232                 "changelog record has flags of $flags"
13233
13234         # rename doesn't overwrite a target (changelog flag 0x0)
13235         touch $DIR/$tdir/foo_161c
13236         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13237         changelog_dump | grep RENME | tail -n 5
13238         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13239         changelog_clear 0 || error "changelog_clear failed"
13240         if [ x$flags != "x0x0" ]; then
13241                 error "flag $flags is not 0x0"
13242         fi
13243         echo "rename doesn't overwrite a target," \
13244                 "changelog record has flags of $flags"
13245
13246         # define CLF_UNLINK_LAST 0x0001
13247         # unlink a file having nlink = 1 (changelog flag 0x1)
13248         rm -f $DIR/$tdir/foo2_161c
13249         changelog_dump | grep UNLNK | tail -n 5
13250         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13251         changelog_clear 0 || error "changelog_clear failed"
13252         if [ x$flags != "x0x1" ]; then
13253                 error "flag $flags is not 0x1"
13254         fi
13255         echo "unlink a file having nlink = 1," \
13256                 "changelog record has flags of $flags"
13257
13258         # unlink a file having nlink > 1 (changelog flag 0x0)
13259         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13260         rm -f $DIR/$tdir/foobar_161c
13261         changelog_dump | grep UNLNK | tail -n 5
13262         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13263         changelog_clear 0 || error "changelog_clear failed"
13264         if [ x$flags != "x0x0" ]; then
13265                 error "flag $flags is not 0x0"
13266         fi
13267         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13268 }
13269 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13270
13271 test_161d() {
13272         remote_mds_nodsh && skip "remote MDS with nodsh"
13273         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13274
13275         local pid
13276         local fid
13277
13278         changelog_register || error "changelog_register failed"
13279
13280         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13281         # interfer with $MOUNT/.lustre/fid/ access
13282         mkdir $DIR/$tdir
13283         [[ $? -eq 0 ]] || error "mkdir failed"
13284
13285         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13286         $LCTL set_param fail_loc=0x8000140c
13287         # 5s pause
13288         $LCTL set_param fail_val=5
13289
13290         # create file
13291         echo foofoo > $DIR/$tdir/$tfile &
13292         pid=$!
13293
13294         # wait for create to be delayed
13295         sleep 2
13296
13297         ps -p $pid
13298         [[ $? -eq 0 ]] || error "create should be blocked"
13299
13300         local tempfile=$(mktemp)
13301         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13302         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13303         # some delay may occur during ChangeLog publishing and file read just
13304         # above, that could allow file write to happen finally
13305         [[ -s $tempfile ]] && echo "file should be empty"
13306
13307         $LCTL set_param fail_loc=0
13308
13309         wait $pid
13310         [[ $? -eq 0 ]] || error "create failed"
13311 }
13312 run_test 161d "create with concurrent .lustre/fid access"
13313
13314 check_path() {
13315         local expected="$1"
13316         shift
13317         local fid="$2"
13318
13319         local path
13320         path=$($LFS fid2path "$@")
13321         local rc=$?
13322
13323         if [ $rc -ne 0 ]; then
13324                 error "path looked up of '$expected' failed: rc=$rc"
13325         elif [ "$path" != "$expected" ]; then
13326                 error "path looked up '$path' instead of '$expected'"
13327         else
13328                 echo "FID '$fid' resolves to path '$path' as expected"
13329         fi
13330 }
13331
13332 test_162a() { # was test_162
13333         test_mkdir -p -c1 $DIR/$tdir/d2
13334         touch $DIR/$tdir/d2/$tfile
13335         touch $DIR/$tdir/d2/x1
13336         touch $DIR/$tdir/d2/x2
13337         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13338         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13339         # regular file
13340         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13341         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13342
13343         # softlink
13344         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13345         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13346         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13347
13348         # softlink to wrong file
13349         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13350         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13351         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13352
13353         # hardlink
13354         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13355         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13356         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13357         # fid2path dir/fsname should both work
13358         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13359         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13360
13361         # hardlink count: check that there are 2 links
13362         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13363         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13364
13365         # hardlink indexing: remove the first link
13366         rm $DIR/$tdir/d2/p/q/r/hlink
13367         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13368 }
13369 run_test 162a "path lookup sanity"
13370
13371 test_162b() {
13372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13374
13375         mkdir $DIR/$tdir
13376         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13377                                 error "create striped dir failed"
13378
13379         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13380                                         tail -n 1 | awk '{print $2}')
13381         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13382
13383         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13384         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13385
13386         # regular file
13387         for ((i=0;i<5;i++)); do
13388                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13389                         error "get fid for f$i failed"
13390                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13391
13392                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13393                         error "get fid for d$i failed"
13394                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13395         done
13396
13397         return 0
13398 }
13399 run_test 162b "striped directory path lookup sanity"
13400
13401 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13402 test_162c() {
13403         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13404                 skip "Need MDS version at least 2.7.51"
13405
13406         local lpath=$tdir.local
13407         local rpath=$tdir.remote
13408
13409         test_mkdir $DIR/$lpath
13410         test_mkdir $DIR/$rpath
13411
13412         for ((i = 0; i <= 101; i++)); do
13413                 lpath="$lpath/$i"
13414                 mkdir $DIR/$lpath
13415                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13416                         error "get fid for local directory $DIR/$lpath failed"
13417                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13418
13419                 rpath="$rpath/$i"
13420                 test_mkdir $DIR/$rpath
13421                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13422                         error "get fid for remote directory $DIR/$rpath failed"
13423                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13424         done
13425
13426         return 0
13427 }
13428 run_test 162c "fid2path works with paths 100 or more directories deep"
13429
13430 test_169() {
13431         # do directio so as not to populate the page cache
13432         log "creating a 10 Mb file"
13433         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13434         log "starting reads"
13435         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13436         log "truncating the file"
13437         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13438         log "killing dd"
13439         kill %+ || true # reads might have finished
13440         echo "wait until dd is finished"
13441         wait
13442         log "removing the temporary file"
13443         rm -rf $DIR/$tfile || error "tmp file removal failed"
13444 }
13445 run_test 169 "parallel read and truncate should not deadlock"
13446
13447 test_170() {
13448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13449
13450         $LCTL clear     # bug 18514
13451         $LCTL debug_daemon start $TMP/${tfile}_log_good
13452         touch $DIR/$tfile
13453         $LCTL debug_daemon stop
13454         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13455                 error "sed failed to read log_good"
13456
13457         $LCTL debug_daemon start $TMP/${tfile}_log_good
13458         rm -rf $DIR/$tfile
13459         $LCTL debug_daemon stop
13460
13461         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13462                error "lctl df log_bad failed"
13463
13464         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13465         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13466
13467         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13468         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13469
13470         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13471                 error "bad_line good_line1 good_line2 are empty"
13472
13473         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13474         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13475         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13476
13477         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13478         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13479         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13480
13481         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13482                 error "bad_line_new good_line_new are empty"
13483
13484         local expected_good=$((good_line1 + good_line2*2))
13485
13486         rm -f $TMP/${tfile}*
13487         # LU-231, short malformed line may not be counted into bad lines
13488         if [ $bad_line -ne $bad_line_new ] &&
13489                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13490                 error "expected $bad_line bad lines, but got $bad_line_new"
13491                 return 1
13492         fi
13493
13494         if [ $expected_good -ne $good_line_new ]; then
13495                 error "expected $expected_good good lines, but got $good_line_new"
13496                 return 2
13497         fi
13498         true
13499 }
13500 run_test 170 "test lctl df to handle corrupted log ====================="
13501
13502 test_171() { # bug20592
13503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13504
13505         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13506         $LCTL set_param fail_loc=0x50e
13507         $LCTL set_param fail_val=3000
13508         multiop_bg_pause $DIR/$tfile O_s || true
13509         local MULTIPID=$!
13510         kill -USR1 $MULTIPID
13511         # cause log dump
13512         sleep 3
13513         wait $MULTIPID
13514         if dmesg | grep "recursive fault"; then
13515                 error "caught a recursive fault"
13516         fi
13517         $LCTL set_param fail_loc=0
13518         true
13519 }
13520 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13521
13522 # it would be good to share it with obdfilter-survey/iokit-libecho code
13523 setup_obdecho_osc () {
13524         local rc=0
13525         local ost_nid=$1
13526         local obdfilter_name=$2
13527         echo "Creating new osc for $obdfilter_name on $ost_nid"
13528         # make sure we can find loopback nid
13529         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13530
13531         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13532                            ${obdfilter_name}_osc_UUID || rc=2; }
13533         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13534                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13535         return $rc
13536 }
13537
13538 cleanup_obdecho_osc () {
13539         local obdfilter_name=$1
13540         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13541         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13542         return 0
13543 }
13544
13545 obdecho_test() {
13546         local OBD=$1
13547         local node=$2
13548         local pages=${3:-64}
13549         local rc=0
13550         local id
13551
13552         local count=10
13553         local obd_size=$(get_obd_size $node $OBD)
13554         local page_size=$(get_page_size $node)
13555         if [[ -n "$obd_size" ]]; then
13556                 local new_count=$((obd_size / (pages * page_size / 1024)))
13557                 [[ $new_count -ge $count ]] || count=$new_count
13558         fi
13559
13560         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13561         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13562                            rc=2; }
13563         if [ $rc -eq 0 ]; then
13564             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13565             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13566         fi
13567         echo "New object id is $id"
13568         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13569                            rc=4; }
13570         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13571                            "test_brw $count w v $pages $id" || rc=4; }
13572         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13573                            rc=4; }
13574         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13575                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13576         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13577                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13578         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13579         return $rc
13580 }
13581
13582 test_180a() {
13583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13584
13585         if ! module_loaded obdecho; then
13586                 load_module obdecho/obdecho &&
13587                         stack_trap "rmmod obdecho" EXIT ||
13588                         error "unable to load obdecho on client"
13589         fi
13590
13591         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13592         local host=$($LCTL get_param -n osc.$osc.import |
13593                      awk '/current_connection:/ { print $2 }' )
13594         local target=$($LCTL get_param -n osc.$osc.import |
13595                        awk '/target:/ { print $2 }' )
13596         target=${target%_UUID}
13597
13598         if [ -n "$target" ]; then
13599                 setup_obdecho_osc $host $target &&
13600                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13601                         { error "obdecho setup failed with $?"; return; }
13602
13603                 obdecho_test ${target}_osc client ||
13604                         error "obdecho_test failed on ${target}_osc"
13605         else
13606                 $LCTL get_param osc.$osc.import
13607                 error "there is no osc.$osc.import target"
13608         fi
13609 }
13610 run_test 180a "test obdecho on osc"
13611
13612 test_180b() {
13613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13614         remote_ost_nodsh && skip "remote OST with nodsh"
13615
13616         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13617                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13618                 error "failed to load module obdecho"
13619
13620         local target=$(do_facet ost1 $LCTL dl |
13621                        awk '/obdfilter/ { print $4; exit; }')
13622
13623         if [ -n "$target" ]; then
13624                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13625         else
13626                 do_facet ost1 $LCTL dl
13627                 error "there is no obdfilter target on ost1"
13628         fi
13629 }
13630 run_test 180b "test obdecho directly on obdfilter"
13631
13632 test_180c() { # LU-2598
13633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13634         remote_ost_nodsh && skip "remote OST with nodsh"
13635         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13636                 skip "Need MDS version at least 2.4.0"
13637
13638         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13639                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13640                 error "failed to load module obdecho"
13641
13642         local target=$(do_facet ost1 $LCTL dl |
13643                        awk '/obdfilter/ { print $4; exit; }')
13644
13645         if [ -n "$target" ]; then
13646                 local pages=16384 # 64MB bulk I/O RPC size
13647
13648                 obdecho_test "$target" ost1 "$pages" ||
13649                         error "obdecho_test with pages=$pages failed with $?"
13650         else
13651                 do_facet ost1 $LCTL dl
13652                 error "there is no obdfilter target on ost1"
13653         fi
13654 }
13655 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13656
13657 test_181() { # bug 22177
13658         test_mkdir $DIR/$tdir
13659         # create enough files to index the directory
13660         createmany -o $DIR/$tdir/foobar 4000
13661         # print attributes for debug purpose
13662         lsattr -d .
13663         # open dir
13664         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13665         MULTIPID=$!
13666         # remove the files & current working dir
13667         unlinkmany $DIR/$tdir/foobar 4000
13668         rmdir $DIR/$tdir
13669         kill -USR1 $MULTIPID
13670         wait $MULTIPID
13671         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13672         return 0
13673 }
13674 run_test 181 "Test open-unlinked dir ========================"
13675
13676 test_182() {
13677         local fcount=1000
13678         local tcount=10
13679
13680         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13681
13682         $LCTL set_param mdc.*.rpc_stats=clear
13683
13684         for (( i = 0; i < $tcount; i++ )) ; do
13685                 mkdir $DIR/$tdir/$i
13686         done
13687
13688         for (( i = 0; i < $tcount; i++ )) ; do
13689                 createmany -o $DIR/$tdir/$i/f- $fcount &
13690         done
13691         wait
13692
13693         for (( i = 0; i < $tcount; i++ )) ; do
13694                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13695         done
13696         wait
13697
13698         $LCTL get_param mdc.*.rpc_stats
13699
13700         rm -rf $DIR/$tdir
13701 }
13702 run_test 182 "Test parallel modify metadata operations ================"
13703
13704 test_183() { # LU-2275
13705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13706         remote_mds_nodsh && skip "remote MDS with nodsh"
13707         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13708                 skip "Need MDS version at least 2.3.56"
13709
13710         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13711         echo aaa > $DIR/$tdir/$tfile
13712
13713 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13714         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13715
13716         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13717         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13718
13719         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13720
13721         # Flush negative dentry cache
13722         touch $DIR/$tdir/$tfile
13723
13724         # We are not checking for any leaked references here, they'll
13725         # become evident next time we do cleanup with module unload.
13726         rm -rf $DIR/$tdir
13727 }
13728 run_test 183 "No crash or request leak in case of strange dispositions ========"
13729
13730 # test suite 184 is for LU-2016, LU-2017
13731 test_184a() {
13732         check_swap_layouts_support
13733
13734         dir0=$DIR/$tdir/$testnum
13735         test_mkdir -p -c1 $dir0
13736         ref1=/etc/passwd
13737         ref2=/etc/group
13738         file1=$dir0/f1
13739         file2=$dir0/f2
13740         $LFS setstripe -c1 $file1
13741         cp $ref1 $file1
13742         $LFS setstripe -c2 $file2
13743         cp $ref2 $file2
13744         gen1=$($LFS getstripe -g $file1)
13745         gen2=$($LFS getstripe -g $file2)
13746
13747         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13748         gen=$($LFS getstripe -g $file1)
13749         [[ $gen1 != $gen ]] ||
13750                 "Layout generation on $file1 does not change"
13751         gen=$($LFS getstripe -g $file2)
13752         [[ $gen2 != $gen ]] ||
13753                 "Layout generation on $file2 does not change"
13754
13755         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13756         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13757
13758         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13759 }
13760 run_test 184a "Basic layout swap"
13761
13762 test_184b() {
13763         check_swap_layouts_support
13764
13765         dir0=$DIR/$tdir/$testnum
13766         mkdir -p $dir0 || error "creating dir $dir0"
13767         file1=$dir0/f1
13768         file2=$dir0/f2
13769         file3=$dir0/f3
13770         dir1=$dir0/d1
13771         dir2=$dir0/d2
13772         mkdir $dir1 $dir2
13773         $LFS setstripe -c1 $file1
13774         $LFS setstripe -c2 $file2
13775         $LFS setstripe -c1 $file3
13776         chown $RUNAS_ID $file3
13777         gen1=$($LFS getstripe -g $file1)
13778         gen2=$($LFS getstripe -g $file2)
13779
13780         $LFS swap_layouts $dir1 $dir2 &&
13781                 error "swap of directories layouts should fail"
13782         $LFS swap_layouts $dir1 $file1 &&
13783                 error "swap of directory and file layouts should fail"
13784         $RUNAS $LFS swap_layouts $file1 $file2 &&
13785                 error "swap of file we cannot write should fail"
13786         $LFS swap_layouts $file1 $file3 &&
13787                 error "swap of file with different owner should fail"
13788         /bin/true # to clear error code
13789 }
13790 run_test 184b "Forbidden layout swap (will generate errors)"
13791
13792 test_184c() {
13793         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13794         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13795         check_swap_layouts_support
13796
13797         local dir0=$DIR/$tdir/$testnum
13798         mkdir -p $dir0 || error "creating dir $dir0"
13799
13800         local ref1=$dir0/ref1
13801         local ref2=$dir0/ref2
13802         local file1=$dir0/file1
13803         local file2=$dir0/file2
13804         # create a file large enough for the concurrent test
13805         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13806         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13807         echo "ref file size: ref1($(stat -c %s $ref1))," \
13808              "ref2($(stat -c %s $ref2))"
13809
13810         cp $ref2 $file2
13811         dd if=$ref1 of=$file1 bs=16k &
13812         local DD_PID=$!
13813
13814         # Make sure dd starts to copy file
13815         while [ ! -f $file1 ]; do sleep 0.1; done
13816
13817         $LFS swap_layouts $file1 $file2
13818         local rc=$?
13819         wait $DD_PID
13820         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13821         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13822
13823         # how many bytes copied before swapping layout
13824         local copied=$(stat -c %s $file2)
13825         local remaining=$(stat -c %s $ref1)
13826         remaining=$((remaining - copied))
13827         echo "Copied $copied bytes before swapping layout..."
13828
13829         cmp -n $copied $file1 $ref2 | grep differ &&
13830                 error "Content mismatch [0, $copied) of ref2 and file1"
13831         cmp -n $copied $file2 $ref1 ||
13832                 error "Content mismatch [0, $copied) of ref1 and file2"
13833         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13834                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13835
13836         # clean up
13837         rm -f $ref1 $ref2 $file1 $file2
13838 }
13839 run_test 184c "Concurrent write and layout swap"
13840
13841 test_184d() {
13842         check_swap_layouts_support
13843         [ -z "$(which getfattr 2>/dev/null)" ] &&
13844                 skip_env "no getfattr command"
13845
13846         local file1=$DIR/$tdir/$tfile-1
13847         local file2=$DIR/$tdir/$tfile-2
13848         local file3=$DIR/$tdir/$tfile-3
13849         local lovea1
13850         local lovea2
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         lovea1=$(get_layout_param $file1)
13859
13860         $LFS swap_layouts $file2 $file3 ||
13861                 error "swap $file2 $file3 layouts failed"
13862         $LFS swap_layouts $file1 $file2 ||
13863                 error "swap $file1 $file2 layouts failed"
13864
13865         lovea2=$(get_layout_param $file2)
13866         echo "$lovea1"
13867         echo "$lovea2"
13868         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13869
13870         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13871         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13872 }
13873 run_test 184d "allow stripeless layouts swap"
13874
13875 test_184e() {
13876         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13877                 skip "Need MDS version at least 2.6.94"
13878         check_swap_layouts_support
13879         [ -z "$(which getfattr 2>/dev/null)" ] &&
13880                 skip_env "no getfattr command"
13881
13882         local file1=$DIR/$tdir/$tfile-1
13883         local file2=$DIR/$tdir/$tfile-2
13884         local file3=$DIR/$tdir/$tfile-3
13885         local lovea
13886
13887         mkdir -p $DIR/$tdir
13888         touch $file1 || error "create $file1 failed"
13889         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13890                 error "create $file2 failed"
13891         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13892                 error "create $file3 failed"
13893
13894         $LFS swap_layouts $file1 $file2 ||
13895                 error "swap $file1 $file2 layouts failed"
13896
13897         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13898         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13899
13900         echo 123 > $file1 || error "Should be able to write into $file1"
13901
13902         $LFS swap_layouts $file1 $file3 ||
13903                 error "swap $file1 $file3 layouts failed"
13904
13905         echo 123 > $file1 || error "Should be able to write into $file1"
13906
13907         rm -rf $file1 $file2 $file3
13908 }
13909 run_test 184e "Recreate layout after stripeless layout swaps"
13910
13911 test_184f() {
13912         # Create a file with name longer than sizeof(struct stat) ==
13913         # 144 to see if we can get chars from the file name to appear
13914         # in the returned striping. Note that 'f' == 0x66.
13915         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13916
13917         mkdir -p $DIR/$tdir
13918         mcreate $DIR/$tdir/$file
13919         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13920                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13921         fi
13922 }
13923 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13924
13925 test_185() { # LU-2441
13926         # LU-3553 - no volatile file support in old servers
13927         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13928                 skip "Need MDS version at least 2.3.60"
13929
13930         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13931         touch $DIR/$tdir/spoo
13932         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13933         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13934                 error "cannot create/write a volatile file"
13935         [ "$FILESET" == "" ] &&
13936         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13937                 error "FID is still valid after close"
13938
13939         multiop_bg_pause $DIR/$tdir vVw4096_c
13940         local multi_pid=$!
13941
13942         local OLD_IFS=$IFS
13943         IFS=":"
13944         local fidv=($fid)
13945         IFS=$OLD_IFS
13946         # assume that the next FID for this client is sequential, since stdout
13947         # is unfortunately eaten by multiop_bg_pause
13948         local n=$((${fidv[1]} + 1))
13949         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13950         if [ "$FILESET" == "" ]; then
13951                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13952                         error "FID is missing before close"
13953         fi
13954         kill -USR1 $multi_pid
13955         # 1 second delay, so if mtime change we will see it
13956         sleep 1
13957         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13958         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13959 }
13960 run_test 185 "Volatile file support"
13961
13962 test_187a() {
13963         remote_mds_nodsh && skip "remote MDS with nodsh"
13964         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13965                 skip "Need MDS version at least 2.3.0"
13966
13967         local dir0=$DIR/$tdir/$testnum
13968         mkdir -p $dir0 || error "creating dir $dir0"
13969
13970         local file=$dir0/file1
13971         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13972         local dv1=$($LFS data_version $file)
13973         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13974         local dv2=$($LFS data_version $file)
13975         [[ $dv1 != $dv2 ]] ||
13976                 error "data version did not change on write $dv1 == $dv2"
13977
13978         # clean up
13979         rm -f $file1
13980 }
13981 run_test 187a "Test data version change"
13982
13983 test_187b() {
13984         remote_mds_nodsh && skip "remote MDS with nodsh"
13985         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13986                 skip "Need MDS version at least 2.3.0"
13987
13988         local dir0=$DIR/$tdir/$testnum
13989         mkdir -p $dir0 || error "creating dir $dir0"
13990
13991         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13992         [[ ${DV[0]} != ${DV[1]} ]] ||
13993                 error "data version did not change on write"\
13994                       " ${DV[0]} == ${DV[1]}"
13995
13996         # clean up
13997         rm -f $file1
13998 }
13999 run_test 187b "Test data version change on volatile file"
14000
14001 test_200() {
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003         remote_mgs_nodsh && skip "remote MGS with nodsh"
14004         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14005
14006         local POOL=${POOL:-cea1}
14007         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14008         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14009         # Pool OST targets
14010         local first_ost=0
14011         local last_ost=$(($OSTCOUNT - 1))
14012         local ost_step=2
14013         local ost_list=$(seq $first_ost $ost_step $last_ost)
14014         local ost_range="$first_ost $last_ost $ost_step"
14015         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14016         local file_dir=$POOL_ROOT/file_tst
14017         local subdir=$test_path/subdir
14018         local rc=0
14019
14020         if ! combined_mgs_mds ; then
14021                 mount_mgs_client
14022         fi
14023
14024         while : ; do
14025                 # former test_200a test_200b
14026                 pool_add $POOL                          || { rc=$? ; break; }
14027                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14028                 # former test_200c test_200d
14029                 mkdir -p $test_path
14030                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14031                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14032                 mkdir -p $subdir
14033                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14034                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14035                                                         || { rc=$? ; break; }
14036                 # former test_200e test_200f
14037                 local files=$((OSTCOUNT*3))
14038                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14039                                                         || { rc=$? ; break; }
14040                 pool_create_files $POOL $file_dir $files "$ost_list" \
14041                                                         || { rc=$? ; break; }
14042                 # former test_200g test_200h
14043                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14044                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14045
14046                 # former test_201a test_201b test_201c
14047                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14048
14049                 local f=$test_path/$tfile
14050                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14051                 pool_remove $POOL $f                    || { rc=$? ; break; }
14052                 break
14053         done
14054
14055         destroy_test_pools
14056
14057         if ! combined_mgs_mds ; then
14058                 umount_mgs_client
14059         fi
14060         return $rc
14061 }
14062 run_test 200 "OST pools"
14063
14064 # usage: default_attr <count | size | offset>
14065 default_attr() {
14066         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14067 }
14068
14069 # usage: check_default_stripe_attr
14070 check_default_stripe_attr() {
14071         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14072         case $1 in
14073         --stripe-count|-c)
14074                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14075         --stripe-size|-S)
14076                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14077         --stripe-index|-i)
14078                 EXPECTED=-1;;
14079         *)
14080                 error "unknown getstripe attr '$1'"
14081         esac
14082
14083         [ $ACTUAL == $EXPECTED ] ||
14084                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14085 }
14086
14087 test_204a() {
14088         test_mkdir $DIR/$tdir
14089         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14090
14091         check_default_stripe_attr --stripe-count
14092         check_default_stripe_attr --stripe-size
14093         check_default_stripe_attr --stripe-index
14094 }
14095 run_test 204a "Print default stripe attributes"
14096
14097 test_204b() {
14098         test_mkdir $DIR/$tdir
14099         $LFS setstripe --stripe-count 1 $DIR/$tdir
14100
14101         check_default_stripe_attr --stripe-size
14102         check_default_stripe_attr --stripe-index
14103 }
14104 run_test 204b "Print default stripe size and offset"
14105
14106 test_204c() {
14107         test_mkdir $DIR/$tdir
14108         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14109
14110         check_default_stripe_attr --stripe-count
14111         check_default_stripe_attr --stripe-index
14112 }
14113 run_test 204c "Print default stripe count and offset"
14114
14115 test_204d() {
14116         test_mkdir $DIR/$tdir
14117         $LFS setstripe --stripe-index 0 $DIR/$tdir
14118
14119         check_default_stripe_attr --stripe-count
14120         check_default_stripe_attr --stripe-size
14121 }
14122 run_test 204d "Print default stripe count and size"
14123
14124 test_204e() {
14125         test_mkdir $DIR/$tdir
14126         $LFS setstripe -d $DIR/$tdir
14127
14128         check_default_stripe_attr --stripe-count --raw
14129         check_default_stripe_attr --stripe-size --raw
14130         check_default_stripe_attr --stripe-index --raw
14131 }
14132 run_test 204e "Print raw stripe attributes"
14133
14134 test_204f() {
14135         test_mkdir $DIR/$tdir
14136         $LFS setstripe --stripe-count 1 $DIR/$tdir
14137
14138         check_default_stripe_attr --stripe-size --raw
14139         check_default_stripe_attr --stripe-index --raw
14140 }
14141 run_test 204f "Print raw stripe size and offset"
14142
14143 test_204g() {
14144         test_mkdir $DIR/$tdir
14145         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14146
14147         check_default_stripe_attr --stripe-count --raw
14148         check_default_stripe_attr --stripe-index --raw
14149 }
14150 run_test 204g "Print raw stripe count and offset"
14151
14152 test_204h() {
14153         test_mkdir $DIR/$tdir
14154         $LFS setstripe --stripe-index 0 $DIR/$tdir
14155
14156         check_default_stripe_attr --stripe-count --raw
14157         check_default_stripe_attr --stripe-size --raw
14158 }
14159 run_test 204h "Print raw stripe count and size"
14160
14161 # Figure out which job scheduler is being used, if any,
14162 # or use a fake one
14163 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14164         JOBENV=SLURM_JOB_ID
14165 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14166         JOBENV=LSB_JOBID
14167 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14168         JOBENV=PBS_JOBID
14169 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14170         JOBENV=LOADL_STEP_ID
14171 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14172         JOBENV=JOB_ID
14173 else
14174         $LCTL list_param jobid_name > /dev/null 2>&1
14175         if [ $? -eq 0 ]; then
14176                 JOBENV=nodelocal
14177         else
14178                 JOBENV=FAKE_JOBID
14179         fi
14180 fi
14181 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14182
14183 verify_jobstats() {
14184         local cmd=($1)
14185         shift
14186         local facets="$@"
14187
14188 # we don't really need to clear the stats for this test to work, since each
14189 # command has a unique jobid, but it makes debugging easier if needed.
14190 #       for facet in $facets; do
14191 #               local dev=$(convert_facet2label $facet)
14192 #               # clear old jobstats
14193 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14194 #       done
14195
14196         # use a new JobID for each test, or we might see an old one
14197         [ "$JOBENV" = "FAKE_JOBID" ] &&
14198                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14199
14200         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14201
14202         [ "$JOBENV" = "nodelocal" ] && {
14203                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14204                 $LCTL set_param jobid_name=$FAKE_JOBID
14205                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14206         }
14207
14208         log "Test: ${cmd[*]}"
14209         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14210
14211         if [ $JOBENV = "FAKE_JOBID" ]; then
14212                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14213         else
14214                 ${cmd[*]}
14215         fi
14216
14217         # all files are created on OST0000
14218         for facet in $facets; do
14219                 local stats="*.$(convert_facet2label $facet).job_stats"
14220
14221                 # strip out libtool wrappers for in-tree executables
14222                 if [ $(do_facet $facet lctl get_param $stats |
14223                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14224                         do_facet $facet lctl get_param $stats
14225                         error "No jobstats for $JOBVAL found on $facet::$stats"
14226                 fi
14227         done
14228 }
14229
14230 jobstats_set() {
14231         local new_jobenv=$1
14232
14233         set_persistent_param_and_check client "jobid_var" \
14234                 "$FSNAME.sys.jobid_var" $new_jobenv
14235 }
14236
14237 test_205() { # Job stats
14238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14239         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14240                 skip "Need MDS version with at least 2.7.1"
14241         remote_mgs_nodsh && skip "remote MGS with nodsh"
14242         remote_mds_nodsh && skip "remote MDS with nodsh"
14243         remote_ost_nodsh && skip "remote OST with nodsh"
14244         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14245                 skip "Server doesn't support jobstats"
14246         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14247
14248         local old_jobenv=$($LCTL get_param -n jobid_var)
14249         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14250
14251         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14252                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14253         else
14254                 stack_trap "do_facet mgs $PERM_CMD \
14255                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14256         fi
14257         changelog_register
14258
14259         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14260                                 mdt.*.job_cleanup_interval | head -n 1)
14261         local new_interval=5
14262         do_facet $SINGLEMDS \
14263                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14264         stack_trap "do_facet $SINGLEMDS \
14265                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14266         local start=$SECONDS
14267
14268         local cmd
14269         # mkdir
14270         cmd="mkdir $DIR/$tdir"
14271         verify_jobstats "$cmd" "$SINGLEMDS"
14272         # rmdir
14273         cmd="rmdir $DIR/$tdir"
14274         verify_jobstats "$cmd" "$SINGLEMDS"
14275         # mkdir on secondary MDT
14276         if [ $MDSCOUNT -gt 1 ]; then
14277                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14278                 verify_jobstats "$cmd" "mds2"
14279         fi
14280         # mknod
14281         cmd="mknod $DIR/$tfile c 1 3"
14282         verify_jobstats "$cmd" "$SINGLEMDS"
14283         # unlink
14284         cmd="rm -f $DIR/$tfile"
14285         verify_jobstats "$cmd" "$SINGLEMDS"
14286         # create all files on OST0000 so verify_jobstats can find OST stats
14287         # open & close
14288         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14289         verify_jobstats "$cmd" "$SINGLEMDS"
14290         # setattr
14291         cmd="touch $DIR/$tfile"
14292         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14293         # write
14294         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14295         verify_jobstats "$cmd" "ost1"
14296         # read
14297         cancel_lru_locks osc
14298         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14299         verify_jobstats "$cmd" "ost1"
14300         # truncate
14301         cmd="$TRUNCATE $DIR/$tfile 0"
14302         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14303         # rename
14304         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14305         verify_jobstats "$cmd" "$SINGLEMDS"
14306         # jobstats expiry - sleep until old stats should be expired
14307         local left=$((new_interval + 5 - (SECONDS - start)))
14308         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14309                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14310                         "0" $left
14311         cmd="mkdir $DIR/$tdir.expire"
14312         verify_jobstats "$cmd" "$SINGLEMDS"
14313         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14314             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14315
14316         # Ensure that jobid are present in changelog (if supported by MDS)
14317         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14318                 changelog_dump | tail -10
14319                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14320                 [ $jobids -eq 9 ] ||
14321                         error "Wrong changelog jobid count $jobids != 9"
14322
14323                 # LU-5862
14324                 JOBENV="disable"
14325                 jobstats_set $JOBENV
14326                 touch $DIR/$tfile
14327                 changelog_dump | grep $tfile
14328                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14329                 [ $jobids -eq 0 ] ||
14330                         error "Unexpected jobids when jobid_var=$JOBENV"
14331         fi
14332
14333         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14334         JOBENV="JOBCOMPLEX"
14335         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14336
14337         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14338 }
14339 run_test 205 "Verify job stats"
14340
14341 # LU-1480, LU-1773 and LU-1657
14342 test_206() {
14343         mkdir -p $DIR/$tdir
14344         $LFS setstripe -c -1 $DIR/$tdir
14345 #define OBD_FAIL_LOV_INIT 0x1403
14346         $LCTL set_param fail_loc=0xa0001403
14347         $LCTL set_param fail_val=1
14348         touch $DIR/$tdir/$tfile || true
14349 }
14350 run_test 206 "fail lov_init_raid0() doesn't lbug"
14351
14352 test_207a() {
14353         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14354         local fsz=`stat -c %s $DIR/$tfile`
14355         cancel_lru_locks mdc
14356
14357         # do not return layout in getattr intent
14358 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14359         $LCTL set_param fail_loc=0x170
14360         local sz=`stat -c %s $DIR/$tfile`
14361
14362         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14363
14364         rm -rf $DIR/$tfile
14365 }
14366 run_test 207a "can refresh layout at glimpse"
14367
14368 test_207b() {
14369         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14370         local cksum=`md5sum $DIR/$tfile`
14371         local fsz=`stat -c %s $DIR/$tfile`
14372         cancel_lru_locks mdc
14373         cancel_lru_locks osc
14374
14375         # do not return layout in getattr intent
14376 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14377         $LCTL set_param fail_loc=0x171
14378
14379         # it will refresh layout after the file is opened but before read issues
14380         echo checksum is "$cksum"
14381         echo "$cksum" |md5sum -c --quiet || error "file differs"
14382
14383         rm -rf $DIR/$tfile
14384 }
14385 run_test 207b "can refresh layout at open"
14386
14387 test_208() {
14388         # FIXME: in this test suite, only RD lease is used. This is okay
14389         # for now as only exclusive open is supported. After generic lease
14390         # is done, this test suite should be revised. - Jinshan
14391
14392         remote_mds_nodsh && skip "remote MDS with nodsh"
14393         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14394                 skip "Need MDS version at least 2.4.52"
14395
14396         echo "==== test 1: verify get lease work"
14397         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14398
14399         echo "==== test 2: verify lease can be broken by upcoming open"
14400         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14401         local PID=$!
14402         sleep 1
14403
14404         $MULTIOP $DIR/$tfile oO_RDONLY:c
14405         kill -USR1 $PID && wait $PID || error "break lease error"
14406
14407         echo "==== test 3: verify lease can't be granted if an open already exists"
14408         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14409         local PID=$!
14410         sleep 1
14411
14412         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14413         kill -USR1 $PID && wait $PID || error "open file error"
14414
14415         echo "==== test 4: lease can sustain over recovery"
14416         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14417         PID=$!
14418         sleep 1
14419
14420         fail mds1
14421
14422         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14423
14424         echo "==== test 5: lease broken can't be regained by replay"
14425         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14426         PID=$!
14427         sleep 1
14428
14429         # open file to break lease and then recovery
14430         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14431         fail mds1
14432
14433         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14434
14435         rm -f $DIR/$tfile
14436 }
14437 run_test 208 "Exclusive open"
14438
14439 test_209() {
14440         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14441                 skip_env "must have disp_stripe"
14442
14443         touch $DIR/$tfile
14444         sync; sleep 5; sync;
14445
14446         echo 3 > /proc/sys/vm/drop_caches
14447         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14448
14449         # open/close 500 times
14450         for i in $(seq 500); do
14451                 cat $DIR/$tfile
14452         done
14453
14454         echo 3 > /proc/sys/vm/drop_caches
14455         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14456
14457         echo "before: $req_before, after: $req_after"
14458         [ $((req_after - req_before)) -ge 300 ] &&
14459                 error "open/close requests are not freed"
14460         return 0
14461 }
14462 run_test 209 "read-only open/close requests should be freed promptly"
14463
14464 test_212() {
14465         size=`date +%s`
14466         size=$((size % 8192 + 1))
14467         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14468         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14469         rm -f $DIR/f212 $DIR/f212.xyz
14470 }
14471 run_test 212 "Sendfile test ============================================"
14472
14473 test_213() {
14474         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14475         cancel_lru_locks osc
14476         lctl set_param fail_loc=0x8000040f
14477         # generate a read lock
14478         cat $DIR/$tfile > /dev/null
14479         # write to the file, it will try to cancel the above read lock.
14480         cat /etc/hosts >> $DIR/$tfile
14481 }
14482 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14483
14484 test_214() { # for bug 20133
14485         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14486         for (( i=0; i < 340; i++ )) ; do
14487                 touch $DIR/$tdir/d214c/a$i
14488         done
14489
14490         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14491         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14492         ls $DIR/d214c || error "ls $DIR/d214c failed"
14493         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14494         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14495 }
14496 run_test 214 "hash-indexed directory test - bug 20133"
14497
14498 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14499 create_lnet_proc_files() {
14500         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14501 }
14502
14503 # counterpart of create_lnet_proc_files
14504 remove_lnet_proc_files() {
14505         rm -f $TMP/lnet_$1.sys
14506 }
14507
14508 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14509 # 3rd arg as regexp for body
14510 check_lnet_proc_stats() {
14511         local l=$(cat "$TMP/lnet_$1" |wc -l)
14512         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14513
14514         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14515 }
14516
14517 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14518 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14519 # optional and can be regexp for 2nd line (lnet.routes case)
14520 check_lnet_proc_entry() {
14521         local blp=2          # blp stands for 'position of 1st line of body'
14522         [ -z "$5" ] || blp=3 # lnet.routes case
14523
14524         local l=$(cat "$TMP/lnet_$1" |wc -l)
14525         # subtracting one from $blp because the body can be empty
14526         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14527
14528         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14529                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14530
14531         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14532                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14533
14534         # bail out if any unexpected line happened
14535         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14536         [ "$?" != 0 ] || error "$2 misformatted"
14537 }
14538
14539 test_215() { # for bugs 18102, 21079, 21517
14540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14541
14542         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14543         local P='[1-9][0-9]*'           # positive numeric
14544         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14545         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14546         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14547         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14548
14549         local L1 # regexp for 1st line
14550         local L2 # regexp for 2nd line (optional)
14551         local BR # regexp for the rest (body)
14552
14553         # lnet.stats should look as 11 space-separated non-negative numerics
14554         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14555         create_lnet_proc_files "stats"
14556         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14557         remove_lnet_proc_files "stats"
14558
14559         # lnet.routes should look like this:
14560         # Routing disabled/enabled
14561         # net hops priority state router
14562         # where net is a string like tcp0, hops > 0, priority >= 0,
14563         # state is up/down,
14564         # router is a string like 192.168.1.1@tcp2
14565         L1="^Routing (disabled|enabled)$"
14566         L2="^net +hops +priority +state +router$"
14567         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14568         create_lnet_proc_files "routes"
14569         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14570         remove_lnet_proc_files "routes"
14571
14572         # lnet.routers should look like this:
14573         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14574         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14575         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14576         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14577         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14578         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14579         create_lnet_proc_files "routers"
14580         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14581         remove_lnet_proc_files "routers"
14582
14583         # lnet.peers should look like this:
14584         # nid refs state last max rtr min tx min queue
14585         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14586         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14587         # numeric (0 or >0 or <0), queue >= 0.
14588         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14589         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14590         create_lnet_proc_files "peers"
14591         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14592         remove_lnet_proc_files "peers"
14593
14594         # lnet.buffers  should look like this:
14595         # pages count credits min
14596         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14597         L1="^pages +count +credits +min$"
14598         BR="^ +$N +$N +$I +$I$"
14599         create_lnet_proc_files "buffers"
14600         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14601         remove_lnet_proc_files "buffers"
14602
14603         # lnet.nis should look like this:
14604         # nid status alive refs peer rtr max tx min
14605         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14606         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14607         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14608         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14609         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14610         create_lnet_proc_files "nis"
14611         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14612         remove_lnet_proc_files "nis"
14613
14614         # can we successfully write to lnet.stats?
14615         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14616 }
14617 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14618
14619 test_216() { # bug 20317
14620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14621         remote_ost_nodsh && skip "remote OST with nodsh"
14622
14623         local node
14624         local facets=$(get_facets OST)
14625         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14626
14627         save_lustre_params client "osc.*.contention_seconds" > $p
14628         save_lustre_params $facets \
14629                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14630         save_lustre_params $facets \
14631                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14632         save_lustre_params $facets \
14633                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14634         clear_stats osc.*.osc_stats
14635
14636         # agressive lockless i/o settings
14637         do_nodes $(comma_list $(osts_nodes)) \
14638                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14639                         ldlm.namespaces.filter-*.contended_locks=0 \
14640                         ldlm.namespaces.filter-*.contention_seconds=60"
14641         lctl set_param -n osc.*.contention_seconds=60
14642
14643         $DIRECTIO write $DIR/$tfile 0 10 4096
14644         $CHECKSTAT -s 40960 $DIR/$tfile
14645
14646         # disable lockless i/o
14647         do_nodes $(comma_list $(osts_nodes)) \
14648                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14649                         ldlm.namespaces.filter-*.contended_locks=32 \
14650                         ldlm.namespaces.filter-*.contention_seconds=0"
14651         lctl set_param -n osc.*.contention_seconds=0
14652         clear_stats osc.*.osc_stats
14653
14654         dd if=/dev/zero of=$DIR/$tfile count=0
14655         $CHECKSTAT -s 0 $DIR/$tfile
14656
14657         restore_lustre_params <$p
14658         rm -f $p
14659         rm $DIR/$tfile
14660 }
14661 run_test 216 "check lockless direct write updates file size and kms correctly"
14662
14663 test_217() { # bug 22430
14664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14665
14666         local node
14667         local nid
14668
14669         for node in $(nodes_list); do
14670                 nid=$(host_nids_address $node $NETTYPE)
14671                 if [[ $nid = *-* ]] ; then
14672                         echo "lctl ping $(h2nettype $nid)"
14673                         lctl ping $(h2nettype $nid)
14674                 else
14675                         echo "skipping $node (no hyphen detected)"
14676                 fi
14677         done
14678 }
14679 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14680
14681 test_218() {
14682        # do directio so as not to populate the page cache
14683        log "creating a 10 Mb file"
14684        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14685        log "starting reads"
14686        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14687        log "truncating the file"
14688        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14689        log "killing dd"
14690        kill %+ || true # reads might have finished
14691        echo "wait until dd is finished"
14692        wait
14693        log "removing the temporary file"
14694        rm -rf $DIR/$tfile || error "tmp file removal failed"
14695 }
14696 run_test 218 "parallel read and truncate should not deadlock"
14697
14698 test_219() {
14699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14700
14701         # write one partial page
14702         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14703         # set no grant so vvp_io_commit_write will do sync write
14704         $LCTL set_param fail_loc=0x411
14705         # write a full page at the end of file
14706         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14707
14708         $LCTL set_param fail_loc=0
14709         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14710         $LCTL set_param fail_loc=0x411
14711         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14712
14713         # LU-4201
14714         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14715         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14716 }
14717 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14718
14719 test_220() { #LU-325
14720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14721         remote_ost_nodsh && skip "remote OST with nodsh"
14722         remote_mds_nodsh && skip "remote MDS with nodsh"
14723         remote_mgs_nodsh && skip "remote MGS with nodsh"
14724
14725         local OSTIDX=0
14726
14727         # create on MDT0000 so the last_id and next_id are correct
14728         mkdir $DIR/$tdir
14729         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14730         OST=${OST%_UUID}
14731
14732         # on the mdt's osc
14733         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14734         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14735                         osc.$mdtosc_proc1.prealloc_last_id)
14736         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14737                         osc.$mdtosc_proc1.prealloc_next_id)
14738
14739         $LFS df -i
14740
14741         if ! combined_mgs_mds ; then
14742                 mount_mgs_client
14743         fi
14744
14745         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14746         #define OBD_FAIL_OST_ENOINO              0x229
14747         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14748         create_pool $FSNAME.$TESTNAME || return 1
14749         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14750
14751         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14752
14753         MDSOBJS=$((last_id - next_id))
14754         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14755
14756         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14757         echo "OST still has $count kbytes free"
14758
14759         echo "create $MDSOBJS files @next_id..."
14760         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14761
14762         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14763                         osc.$mdtosc_proc1.prealloc_last_id)
14764         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14765                         osc.$mdtosc_proc1.prealloc_next_id)
14766
14767         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14768         $LFS df -i
14769
14770         echo "cleanup..."
14771
14772         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14773         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14774
14775         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14776                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14777         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14778                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14779         echo "unlink $MDSOBJS files @$next_id..."
14780         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14781
14782         if ! combined_mgs_mds ; then
14783                 umount_mgs_client
14784         fi
14785 }
14786 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14787
14788 test_221() {
14789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14790
14791         dd if=`which date` of=$MOUNT/date oflag=sync
14792         chmod +x $MOUNT/date
14793
14794         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14795         $LCTL set_param fail_loc=0x80001401
14796
14797         $MOUNT/date > /dev/null
14798         rm -f $MOUNT/date
14799 }
14800 run_test 221 "make sure fault and truncate race to not cause OOM"
14801
14802 test_222a () {
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804
14805         rm -rf $DIR/$tdir
14806         test_mkdir $DIR/$tdir
14807         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14808         createmany -o $DIR/$tdir/$tfile 10
14809         cancel_lru_locks mdc
14810         cancel_lru_locks osc
14811         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14812         $LCTL set_param fail_loc=0x31a
14813         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14814         $LCTL set_param fail_loc=0
14815         rm -r $DIR/$tdir
14816 }
14817 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14818
14819 test_222b () {
14820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14821
14822         rm -rf $DIR/$tdir
14823         test_mkdir $DIR/$tdir
14824         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14825         createmany -o $DIR/$tdir/$tfile 10
14826         cancel_lru_locks mdc
14827         cancel_lru_locks osc
14828         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14829         $LCTL set_param fail_loc=0x31a
14830         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14831         $LCTL set_param fail_loc=0
14832 }
14833 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14834
14835 test_223 () {
14836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14837
14838         rm -rf $DIR/$tdir
14839         test_mkdir $DIR/$tdir
14840         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14841         createmany -o $DIR/$tdir/$tfile 10
14842         cancel_lru_locks mdc
14843         cancel_lru_locks osc
14844         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14845         $LCTL set_param fail_loc=0x31b
14846         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14847         $LCTL set_param fail_loc=0
14848         rm -r $DIR/$tdir
14849 }
14850 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14851
14852 test_224a() { # LU-1039, MRP-303
14853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14854
14855         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14856         $LCTL set_param fail_loc=0x508
14857         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14858         $LCTL set_param fail_loc=0
14859         df $DIR
14860 }
14861 run_test 224a "Don't panic on bulk IO failure"
14862
14863 test_224b() { # LU-1039, MRP-303
14864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14865
14866         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14867         cancel_lru_locks osc
14868         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14869         $LCTL set_param fail_loc=0x515
14870         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14871         $LCTL set_param fail_loc=0
14872         df $DIR
14873 }
14874 run_test 224b "Don't panic on bulk IO failure"
14875
14876 test_224c() { # LU-6441
14877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14878         remote_mds_nodsh && skip "remote MDS with nodsh"
14879
14880         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14881         save_writethrough $p
14882         set_cache writethrough on
14883
14884         local pages_per_rpc=$($LCTL get_param \
14885                                 osc.*.max_pages_per_rpc)
14886         local at_max=$($LCTL get_param -n at_max)
14887         local timeout=$($LCTL get_param -n timeout)
14888         local test_at="at_max"
14889         local param_at="$FSNAME.sys.at_max"
14890         local test_timeout="timeout"
14891         local param_timeout="$FSNAME.sys.timeout"
14892
14893         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14894
14895         set_persistent_param_and_check client "$test_at" "$param_at" 0
14896         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14897
14898         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14899         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14900         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14901         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14902         sync
14903         do_facet ost1 "$LCTL set_param fail_loc=0"
14904
14905         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14906         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14907                 $timeout
14908
14909         $LCTL set_param -n $pages_per_rpc
14910         restore_lustre_params < $p
14911         rm -f $p
14912 }
14913 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14914
14915 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14916 test_225a () {
14917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14918         if [ -z ${MDSSURVEY} ]; then
14919                 skip_env "mds-survey not found"
14920         fi
14921         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14922                 skip "Need MDS version at least 2.2.51"
14923
14924         local mds=$(facet_host $SINGLEMDS)
14925         local target=$(do_nodes $mds 'lctl dl' |
14926                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14927
14928         local cmd1="file_count=1000 thrhi=4"
14929         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14930         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14931         local cmd="$cmd1 $cmd2 $cmd3"
14932
14933         rm -f ${TMP}/mds_survey*
14934         echo + $cmd
14935         eval $cmd || error "mds-survey with zero-stripe failed"
14936         cat ${TMP}/mds_survey*
14937         rm -f ${TMP}/mds_survey*
14938 }
14939 run_test 225a "Metadata survey sanity with zero-stripe"
14940
14941 test_225b () {
14942         if [ -z ${MDSSURVEY} ]; then
14943                 skip_env "mds-survey not found"
14944         fi
14945         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14946                 skip "Need MDS version at least 2.2.51"
14947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14948         remote_mds_nodsh && skip "remote MDS with nodsh"
14949         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14950                 skip_env "Need to mount OST to test"
14951         fi
14952
14953         local mds=$(facet_host $SINGLEMDS)
14954         local target=$(do_nodes $mds 'lctl dl' |
14955                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14956
14957         local cmd1="file_count=1000 thrhi=4"
14958         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14959         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14960         local cmd="$cmd1 $cmd2 $cmd3"
14961
14962         rm -f ${TMP}/mds_survey*
14963         echo + $cmd
14964         eval $cmd || error "mds-survey with stripe_count failed"
14965         cat ${TMP}/mds_survey*
14966         rm -f ${TMP}/mds_survey*
14967 }
14968 run_test 225b "Metadata survey sanity with stripe_count = 1"
14969
14970 mcreate_path2fid () {
14971         local mode=$1
14972         local major=$2
14973         local minor=$3
14974         local name=$4
14975         local desc=$5
14976         local path=$DIR/$tdir/$name
14977         local fid
14978         local rc
14979         local fid_path
14980
14981         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14982                 error "cannot create $desc"
14983
14984         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14985         rc=$?
14986         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14987
14988         fid_path=$($LFS fid2path $MOUNT $fid)
14989         rc=$?
14990         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14991
14992         [ "$path" == "$fid_path" ] ||
14993                 error "fid2path returned $fid_path, expected $path"
14994
14995         echo "pass with $path and $fid"
14996 }
14997
14998 test_226a () {
14999         rm -rf $DIR/$tdir
15000         mkdir -p $DIR/$tdir
15001
15002         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15003         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15004         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15005         mcreate_path2fid 0040666 0 0 dir "directory"
15006         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15007         mcreate_path2fid 0100666 0 0 file "regular file"
15008         mcreate_path2fid 0120666 0 0 link "symbolic link"
15009         mcreate_path2fid 0140666 0 0 sock "socket"
15010 }
15011 run_test 226a "call path2fid and fid2path on files of all type"
15012
15013 test_226b () {
15014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15015
15016         local MDTIDX=1
15017
15018         rm -rf $DIR/$tdir
15019         mkdir -p $DIR/$tdir
15020         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15021                 error "create remote directory failed"
15022         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15023         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15024                                 "character special file (null)"
15025         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15026                                 "character special file (no device)"
15027         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15028         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15029                                 "block special file (loop)"
15030         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15031         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15032         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15033 }
15034 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15035
15036 # LU-1299 Executing or running ldd on a truncated executable does not
15037 # cause an out-of-memory condition.
15038 test_227() {
15039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15040         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15041
15042         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15043         chmod +x $MOUNT/date
15044
15045         $MOUNT/date > /dev/null
15046         ldd $MOUNT/date > /dev/null
15047         rm -f $MOUNT/date
15048 }
15049 run_test 227 "running truncated executable does not cause OOM"
15050
15051 # LU-1512 try to reuse idle OI blocks
15052 test_228a() {
15053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15054         remote_mds_nodsh && skip "remote MDS with nodsh"
15055         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15056
15057         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15058         local myDIR=$DIR/$tdir
15059
15060         mkdir -p $myDIR
15061         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15062         $LCTL set_param fail_loc=0x80001002
15063         createmany -o $myDIR/t- 10000
15064         $LCTL set_param fail_loc=0
15065         # The guard is current the largest FID holder
15066         touch $myDIR/guard
15067         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15068                     tr -d '[')
15069         local IDX=$(($SEQ % 64))
15070
15071         do_facet $SINGLEMDS sync
15072         # Make sure journal flushed.
15073         sleep 6
15074         local blk1=$(do_facet $SINGLEMDS \
15075                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15076                      grep Blockcount | awk '{print $4}')
15077
15078         # Remove old files, some OI blocks will become idle.
15079         unlinkmany $myDIR/t- 10000
15080         # Create new files, idle OI blocks should be reused.
15081         createmany -o $myDIR/t- 2000
15082         do_facet $SINGLEMDS sync
15083         # Make sure journal flushed.
15084         sleep 6
15085         local blk2=$(do_facet $SINGLEMDS \
15086                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15087                      grep Blockcount | awk '{print $4}')
15088
15089         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15090 }
15091 run_test 228a "try to reuse idle OI blocks"
15092
15093 test_228b() {
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095         remote_mds_nodsh && skip "remote MDS with nodsh"
15096         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15097
15098         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15099         local myDIR=$DIR/$tdir
15100
15101         mkdir -p $myDIR
15102         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15103         $LCTL set_param fail_loc=0x80001002
15104         createmany -o $myDIR/t- 10000
15105         $LCTL set_param fail_loc=0
15106         # The guard is current the largest FID holder
15107         touch $myDIR/guard
15108         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15109                     tr -d '[')
15110         local IDX=$(($SEQ % 64))
15111
15112         do_facet $SINGLEMDS sync
15113         # Make sure journal flushed.
15114         sleep 6
15115         local blk1=$(do_facet $SINGLEMDS \
15116                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15117                      grep Blockcount | awk '{print $4}')
15118
15119         # Remove old files, some OI blocks will become idle.
15120         unlinkmany $myDIR/t- 10000
15121
15122         # stop the MDT
15123         stop $SINGLEMDS || error "Fail to stop MDT."
15124         # remount the MDT
15125         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15126
15127         df $MOUNT || error "Fail to df."
15128         # Create new files, idle OI blocks should be reused.
15129         createmany -o $myDIR/t- 2000
15130         do_facet $SINGLEMDS sync
15131         # Make sure journal flushed.
15132         sleep 6
15133         local blk2=$(do_facet $SINGLEMDS \
15134                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15135                      grep Blockcount | awk '{print $4}')
15136
15137         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15138 }
15139 run_test 228b "idle OI blocks can be reused after MDT restart"
15140
15141 #LU-1881
15142 test_228c() {
15143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15144         remote_mds_nodsh && skip "remote MDS with nodsh"
15145         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15146
15147         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15148         local myDIR=$DIR/$tdir
15149
15150         mkdir -p $myDIR
15151         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15152         $LCTL set_param fail_loc=0x80001002
15153         # 20000 files can guarantee there are index nodes in the OI file
15154         createmany -o $myDIR/t- 20000
15155         $LCTL set_param fail_loc=0
15156         # The guard is current the largest FID holder
15157         touch $myDIR/guard
15158         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15159                     tr -d '[')
15160         local IDX=$(($SEQ % 64))
15161
15162         do_facet $SINGLEMDS sync
15163         # Make sure journal flushed.
15164         sleep 6
15165         local blk1=$(do_facet $SINGLEMDS \
15166                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15167                      grep Blockcount | awk '{print $4}')
15168
15169         # Remove old files, some OI blocks will become idle.
15170         unlinkmany $myDIR/t- 20000
15171         rm -f $myDIR/guard
15172         # The OI file should become empty now
15173
15174         # Create new files, idle OI blocks should be reused.
15175         createmany -o $myDIR/t- 2000
15176         do_facet $SINGLEMDS sync
15177         # Make sure journal flushed.
15178         sleep 6
15179         local blk2=$(do_facet $SINGLEMDS \
15180                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15181                      grep Blockcount | awk '{print $4}')
15182
15183         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15184 }
15185 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15186
15187 test_229() { # LU-2482, LU-3448
15188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15189         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15190         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15191                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15192
15193         rm -f $DIR/$tfile
15194
15195         # Create a file with a released layout and stripe count 2.
15196         $MULTIOP $DIR/$tfile H2c ||
15197                 error "failed to create file with released layout"
15198
15199         $LFS getstripe -v $DIR/$tfile
15200
15201         local pattern=$($LFS getstripe -L $DIR/$tfile)
15202         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15203
15204         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15205                 error "getstripe"
15206         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15207         stat $DIR/$tfile || error "failed to stat released file"
15208
15209         chown $RUNAS_ID $DIR/$tfile ||
15210                 error "chown $RUNAS_ID $DIR/$tfile failed"
15211
15212         chgrp $RUNAS_ID $DIR/$tfile ||
15213                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15214
15215         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15216         rm $DIR/$tfile || error "failed to remove released file"
15217 }
15218 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15219
15220 test_230a() {
15221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15223         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15224                 skip "Need MDS version at least 2.11.52"
15225
15226         local MDTIDX=1
15227
15228         test_mkdir $DIR/$tdir
15229         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15230         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15231         [ $mdt_idx -ne 0 ] &&
15232                 error "create local directory on wrong MDT $mdt_idx"
15233
15234         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15235                         error "create remote directory failed"
15236         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15237         [ $mdt_idx -ne $MDTIDX ] &&
15238                 error "create remote directory on wrong MDT $mdt_idx"
15239
15240         createmany -o $DIR/$tdir/test_230/t- 10 ||
15241                 error "create files on remote directory failed"
15242         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15243         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15244         rm -r $DIR/$tdir || error "unlink remote directory failed"
15245 }
15246 run_test 230a "Create remote directory and files under the remote directory"
15247
15248 test_230b() {
15249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15251         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15252                 skip "Need MDS version at least 2.11.52"
15253
15254         local MDTIDX=1
15255         local mdt_index
15256         local i
15257         local file
15258         local pid
15259         local stripe_count
15260         local migrate_dir=$DIR/$tdir/migrate_dir
15261         local other_dir=$DIR/$tdir/other_dir
15262
15263         test_mkdir $DIR/$tdir
15264         test_mkdir -i0 -c1 $migrate_dir
15265         test_mkdir -i0 -c1 $other_dir
15266         for ((i=0; i<10; i++)); do
15267                 mkdir -p $migrate_dir/dir_${i}
15268                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15269                         error "create files under remote dir failed $i"
15270         done
15271
15272         cp /etc/passwd $migrate_dir/$tfile
15273         cp /etc/passwd $other_dir/$tfile
15274         chattr +SAD $migrate_dir
15275         chattr +SAD $migrate_dir/$tfile
15276
15277         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15278         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15279         local old_dir_mode=$(stat -c%f $migrate_dir)
15280         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15281
15282         mkdir -p $migrate_dir/dir_default_stripe2
15283         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15284         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15285
15286         mkdir -p $other_dir
15287         ln $migrate_dir/$tfile $other_dir/luna
15288         ln $migrate_dir/$tfile $migrate_dir/sofia
15289         ln $other_dir/$tfile $migrate_dir/david
15290         ln -s $migrate_dir/$tfile $other_dir/zachary
15291         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15292         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15293
15294         $LFS migrate -m $MDTIDX $migrate_dir ||
15295                 error "fails on migrating remote dir to MDT1"
15296
15297         echo "migratate to MDT1, then checking.."
15298         for ((i = 0; i < 10; i++)); do
15299                 for file in $(find $migrate_dir/dir_${i}); do
15300                         mdt_index=$($LFS getstripe -m $file)
15301                         [ $mdt_index == $MDTIDX ] ||
15302                                 error "$file is not on MDT${MDTIDX}"
15303                 done
15304         done
15305
15306         # the multiple link file should still in MDT0
15307         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15308         [ $mdt_index == 0 ] ||
15309                 error "$file is not on MDT${MDTIDX}"
15310
15311         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15312         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15313                 error " expect $old_dir_flag get $new_dir_flag"
15314
15315         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15316         [ "$old_file_flag" = "$new_file_flag" ] ||
15317                 error " expect $old_file_flag get $new_file_flag"
15318
15319         local new_dir_mode=$(stat -c%f $migrate_dir)
15320         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15321                 error "expect mode $old_dir_mode get $new_dir_mode"
15322
15323         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15324         [ "$old_file_mode" = "$new_file_mode" ] ||
15325                 error "expect mode $old_file_mode get $new_file_mode"
15326
15327         diff /etc/passwd $migrate_dir/$tfile ||
15328                 error "$tfile different after migration"
15329
15330         diff /etc/passwd $other_dir/luna ||
15331                 error "luna different after migration"
15332
15333         diff /etc/passwd $migrate_dir/sofia ||
15334                 error "sofia different after migration"
15335
15336         diff /etc/passwd $migrate_dir/david ||
15337                 error "david different after migration"
15338
15339         diff /etc/passwd $other_dir/zachary ||
15340                 error "zachary different after migration"
15341
15342         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15343                 error "${tfile}_ln different after migration"
15344
15345         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15346                 error "${tfile}_ln_other different after migration"
15347
15348         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15349         [ $stripe_count = 2 ] ||
15350                 error "dir strpe_count $d != 2 after migration."
15351
15352         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15353         [ $stripe_count = 2 ] ||
15354                 error "file strpe_count $d != 2 after migration."
15355
15356         #migrate back to MDT0
15357         MDTIDX=0
15358
15359         $LFS migrate -m $MDTIDX $migrate_dir ||
15360                 error "fails on migrating remote dir to MDT0"
15361
15362         echo "migrate back to MDT0, checking.."
15363         for file in $(find $migrate_dir); do
15364                 mdt_index=$($LFS getstripe -m $file)
15365                 [ $mdt_index == $MDTIDX ] ||
15366                         error "$file is not on MDT${MDTIDX}"
15367         done
15368
15369         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15370         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15371                 error " expect $old_dir_flag get $new_dir_flag"
15372
15373         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15374         [ "$old_file_flag" = "$new_file_flag" ] ||
15375                 error " expect $old_file_flag get $new_file_flag"
15376
15377         local new_dir_mode=$(stat -c%f $migrate_dir)
15378         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15379                 error "expect mode $old_dir_mode get $new_dir_mode"
15380
15381         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15382         [ "$old_file_mode" = "$new_file_mode" ] ||
15383                 error "expect mode $old_file_mode get $new_file_mode"
15384
15385         diff /etc/passwd ${migrate_dir}/$tfile ||
15386                 error "$tfile different after migration"
15387
15388         diff /etc/passwd ${other_dir}/luna ||
15389                 error "luna different after migration"
15390
15391         diff /etc/passwd ${migrate_dir}/sofia ||
15392                 error "sofia different after migration"
15393
15394         diff /etc/passwd ${other_dir}/zachary ||
15395                 error "zachary different after migration"
15396
15397         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15398                 error "${tfile}_ln different after migration"
15399
15400         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15401                 error "${tfile}_ln_other different after migration"
15402
15403         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15404         [ $stripe_count = 2 ] ||
15405                 error "dir strpe_count $d != 2 after migration."
15406
15407         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15408         [ $stripe_count = 2 ] ||
15409                 error "file strpe_count $d != 2 after migration."
15410
15411         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15412 }
15413 run_test 230b "migrate directory"
15414
15415 test_230c() {
15416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15418         remote_mds_nodsh && skip "remote MDS with nodsh"
15419         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15420                 skip "Need MDS version at least 2.11.52"
15421
15422         local MDTIDX=1
15423         local total=3
15424         local mdt_index
15425         local file
15426         local migrate_dir=$DIR/$tdir/migrate_dir
15427
15428         #If migrating directory fails in the middle, all entries of
15429         #the directory is still accessiable.
15430         test_mkdir $DIR/$tdir
15431         test_mkdir -i0 -c1 $migrate_dir
15432         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15433         stat $migrate_dir
15434         createmany -o $migrate_dir/f $total ||
15435                 error "create files under ${migrate_dir} failed"
15436
15437         # fail after migrating top dir, and this will fail only once, so the
15438         # first sub file migration will fail (currently f3), others succeed.
15439         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15440         do_facet mds1 lctl set_param fail_loc=0x1801
15441         local t=$(ls $migrate_dir | wc -l)
15442         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15443                 error "migrate should fail"
15444         local u=$(ls $migrate_dir | wc -l)
15445         [ "$u" == "$t" ] || error "$u != $t during migration"
15446
15447         # add new dir/file should succeed
15448         mkdir $migrate_dir/dir ||
15449                 error "mkdir failed under migrating directory"
15450         touch $migrate_dir/file ||
15451                 error "create file failed under migrating directory"
15452
15453         # add file with existing name should fail
15454         for file in $migrate_dir/f*; do
15455                 stat $file > /dev/null || error "stat $file failed"
15456                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15457                         error "open(O_CREAT|O_EXCL) $file should fail"
15458                 $MULTIOP $file m && error "create $file should fail"
15459                 touch $DIR/$tdir/remote_dir/$tfile ||
15460                         error "touch $tfile failed"
15461                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15462                         error "link $file should fail"
15463                 mdt_index=$($LFS getstripe -m $file)
15464                 if [ $mdt_index == 0 ]; then
15465                         # file failed to migrate is not allowed to rename to
15466                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15467                                 error "rename to $file should fail"
15468                 else
15469                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15470                                 error "rename to $file failed"
15471                 fi
15472                 echo hello >> $file || error "write $file failed"
15473         done
15474
15475         # resume migration with different options should fail
15476         $LFS migrate -m 0 $migrate_dir &&
15477                 error "migrate -m 0 $migrate_dir should fail"
15478
15479         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15480                 error "migrate -c 2 $migrate_dir should fail"
15481
15482         # resume migration should succeed
15483         $LFS migrate -m $MDTIDX $migrate_dir ||
15484                 error "migrate $migrate_dir failed"
15485
15486         echo "Finish migration, then checking.."
15487         for file in $(find $migrate_dir); do
15488                 mdt_index=$($LFS getstripe -m $file)
15489                 [ $mdt_index == $MDTIDX ] ||
15490                         error "$file is not on MDT${MDTIDX}"
15491         done
15492
15493         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15494 }
15495 run_test 230c "check directory accessiblity if migration failed"
15496
15497 test_230d() {
15498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15499         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15500         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15501                 skip "Need MDS version at least 2.11.52"
15502         # LU-11235
15503         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15504
15505         local migrate_dir=$DIR/$tdir/migrate_dir
15506         local old_index
15507         local new_index
15508         local old_count
15509         local new_count
15510         local new_hash
15511         local mdt_index
15512         local i
15513         local j
15514
15515         old_index=$((RANDOM % MDSCOUNT))
15516         old_count=$((MDSCOUNT - old_index))
15517         new_index=$((RANDOM % MDSCOUNT))
15518         new_count=$((MDSCOUNT - new_index))
15519         new_hash="all_char"
15520
15521         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15522         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15523
15524         test_mkdir $DIR/$tdir
15525         test_mkdir -i $old_index -c $old_count $migrate_dir
15526
15527         for ((i=0; i<100; i++)); do
15528                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15529                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15530                         error "create files under remote dir failed $i"
15531         done
15532
15533         echo -n "Migrate from MDT$old_index "
15534         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15535         echo -n "to MDT$new_index"
15536         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15537         echo
15538
15539         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15540         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15541                 error "migrate remote dir error"
15542
15543         echo "Finish migration, then checking.."
15544         for file in $(find $migrate_dir); do
15545                 mdt_index=$($LFS getstripe -m $file)
15546                 if [ $mdt_index -lt $new_index ] ||
15547                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15548                         error "$file is on MDT$mdt_index"
15549                 fi
15550         done
15551
15552         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15553 }
15554 run_test 230d "check migrate big directory"
15555
15556 test_230e() {
15557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15559         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15560                 skip "Need MDS version at least 2.11.52"
15561
15562         local i
15563         local j
15564         local a_fid
15565         local b_fid
15566
15567         mkdir -p $DIR/$tdir
15568         mkdir $DIR/$tdir/migrate_dir
15569         mkdir $DIR/$tdir/other_dir
15570         touch $DIR/$tdir/migrate_dir/a
15571         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15572         ls $DIR/$tdir/other_dir
15573
15574         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15575                 error "migrate dir fails"
15576
15577         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15578         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15579
15580         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15581         [ $mdt_index == 0 ] || error "a is not on MDT0"
15582
15583         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15584                 error "migrate dir fails"
15585
15586         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15587         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15588
15589         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15590         [ $mdt_index == 1 ] || error "a is not on MDT1"
15591
15592         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15593         [ $mdt_index == 1 ] || error "b is not on MDT1"
15594
15595         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15596         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15597
15598         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15599
15600         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15601 }
15602 run_test 230e "migrate mulitple local link files"
15603
15604 test_230f() {
15605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15607         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15608                 skip "Need MDS version at least 2.11.52"
15609
15610         local a_fid
15611         local ln_fid
15612
15613         mkdir -p $DIR/$tdir
15614         mkdir $DIR/$tdir/migrate_dir
15615         $LFS mkdir -i1 $DIR/$tdir/other_dir
15616         touch $DIR/$tdir/migrate_dir/a
15617         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15618         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15619         ls $DIR/$tdir/other_dir
15620
15621         # a should be migrated to MDT1, since no other links on MDT0
15622         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15623                 error "#1 migrate dir fails"
15624         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15625         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15626         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15627         [ $mdt_index == 1 ] || error "a is not on MDT1"
15628
15629         # a should stay on MDT1, because it is a mulitple link file
15630         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15631                 error "#2 migrate dir fails"
15632         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15633         [ $mdt_index == 1 ] || error "a is not on MDT1"
15634
15635         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15636                 error "#3 migrate dir fails"
15637
15638         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15639         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15640         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15641
15642         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15643         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15644
15645         # a should be migrated to MDT0, since no other links on MDT1
15646         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15647                 error "#4 migrate dir fails"
15648         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15649         [ $mdt_index == 0 ] || error "a is not on MDT0"
15650
15651         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15652 }
15653 run_test 230f "migrate mulitple remote link files"
15654
15655 test_230g() {
15656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15658         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15659                 skip "Need MDS version at least 2.11.52"
15660
15661         mkdir -p $DIR/$tdir/migrate_dir
15662
15663         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15664                 error "migrating dir to non-exist MDT succeeds"
15665         true
15666 }
15667 run_test 230g "migrate dir to non-exist MDT"
15668
15669 test_230h() {
15670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15672         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15673                 skip "Need MDS version at least 2.11.52"
15674
15675         local mdt_index
15676
15677         mkdir -p $DIR/$tdir/migrate_dir
15678
15679         $LFS migrate -m1 $DIR &&
15680                 error "migrating mountpoint1 should fail"
15681
15682         $LFS migrate -m1 $DIR/$tdir/.. &&
15683                 error "migrating mountpoint2 should fail"
15684
15685         # same as mv
15686         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15687                 error "migrating $tdir/migrate_dir/.. should fail"
15688
15689         true
15690 }
15691 run_test 230h "migrate .. and root"
15692
15693 test_230i() {
15694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15697                 skip "Need MDS version at least 2.11.52"
15698
15699         mkdir -p $DIR/$tdir/migrate_dir
15700
15701         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15702                 error "migration fails with a tailing slash"
15703
15704         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15705                 error "migration fails with two tailing slashes"
15706 }
15707 run_test 230i "lfs migrate -m tolerates trailing slashes"
15708
15709 test_230j() {
15710         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15711         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15712                 skip "Need MDS version at least 2.11.52"
15713
15714         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15715         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15716                 error "create $tfile failed"
15717         cat /etc/passwd > $DIR/$tdir/$tfile
15718
15719         $LFS migrate -m 1 $DIR/$tdir
15720
15721         cmp /etc/passwd $DIR/$tdir/$tfile ||
15722                 error "DoM file mismatch after migration"
15723 }
15724 run_test 230j "DoM file data not changed after dir migration"
15725
15726 test_230k() {
15727         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15728         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15729                 skip "Need MDS version at least 2.11.56"
15730
15731         local total=20
15732         local files_on_starting_mdt=0
15733
15734         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15735         $LFS getdirstripe $DIR/$tdir
15736         for i in $(seq $total); do
15737                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15738                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15739                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15740         done
15741
15742         echo "$files_on_starting_mdt files on MDT0"
15743
15744         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15745         $LFS getdirstripe $DIR/$tdir
15746
15747         files_on_starting_mdt=0
15748         for i in $(seq $total); do
15749                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15750                         error "file $tfile.$i mismatch after migration"
15751                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15752                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15753         done
15754
15755         echo "$files_on_starting_mdt files on MDT1 after migration"
15756         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15757
15758         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15759         $LFS getdirstripe $DIR/$tdir
15760
15761         files_on_starting_mdt=0
15762         for i in $(seq $total); do
15763                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15764                         error "file $tfile.$i mismatch after 2nd migration"
15765                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15766                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15767         done
15768
15769         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15770         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15771
15772         true
15773 }
15774 run_test 230k "file data not changed after dir migration"
15775
15776 test_230l() {
15777         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15778         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15779                 skip "Need MDS version at least 2.11.56"
15780
15781         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15782         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15783                 error "create files under remote dir failed $i"
15784         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15785 }
15786 run_test 230l "readdir between MDTs won't crash"
15787
15788 test_231a()
15789 {
15790         # For simplicity this test assumes that max_pages_per_rpc
15791         # is the same across all OSCs
15792         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15793         local bulk_size=$((max_pages * PAGE_SIZE))
15794         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15795                                        head -n 1)
15796
15797         mkdir -p $DIR/$tdir
15798         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15799                 error "failed to set stripe with -S ${brw_size}M option"
15800
15801         # clear the OSC stats
15802         $LCTL set_param osc.*.stats=0 &>/dev/null
15803         stop_writeback
15804
15805         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15806         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15807                 oflag=direct &>/dev/null || error "dd failed"
15808
15809         sync; sleep 1; sync # just to be safe
15810         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15811         if [ x$nrpcs != "x1" ]; then
15812                 $LCTL get_param osc.*.stats
15813                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15814         fi
15815
15816         start_writeback
15817         # Drop the OSC cache, otherwise we will read from it
15818         cancel_lru_locks osc
15819
15820         # clear the OSC stats
15821         $LCTL set_param osc.*.stats=0 &>/dev/null
15822
15823         # Client reads $bulk_size.
15824         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15825                 iflag=direct &>/dev/null || error "dd failed"
15826
15827         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15828         if [ x$nrpcs != "x1" ]; then
15829                 $LCTL get_param osc.*.stats
15830                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15831         fi
15832 }
15833 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15834
15835 test_231b() {
15836         mkdir -p $DIR/$tdir
15837         local i
15838         for i in {0..1023}; do
15839                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15840                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15841                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15842         done
15843         sync
15844 }
15845 run_test 231b "must not assert on fully utilized OST request buffer"
15846
15847 test_232a() {
15848         mkdir -p $DIR/$tdir
15849         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15850
15851         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15852         do_facet ost1 $LCTL set_param fail_loc=0x31c
15853
15854         # ignore dd failure
15855         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15856
15857         do_facet ost1 $LCTL set_param fail_loc=0
15858         umount_client $MOUNT || error "umount failed"
15859         mount_client $MOUNT || error "mount failed"
15860         stop ost1 || error "cannot stop ost1"
15861         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15862 }
15863 run_test 232a "failed lock should not block umount"
15864
15865 test_232b() {
15866         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15867                 skip "Need MDS version at least 2.10.58"
15868
15869         mkdir -p $DIR/$tdir
15870         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15871         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15872         sync
15873         cancel_lru_locks osc
15874
15875         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15876         do_facet ost1 $LCTL set_param fail_loc=0x31c
15877
15878         # ignore failure
15879         $LFS data_version $DIR/$tdir/$tfile || true
15880
15881         do_facet ost1 $LCTL set_param fail_loc=0
15882         umount_client $MOUNT || error "umount failed"
15883         mount_client $MOUNT || error "mount failed"
15884         stop ost1 || error "cannot stop ost1"
15885         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15886 }
15887 run_test 232b "failed data version lock should not block umount"
15888
15889 test_233a() {
15890         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15891                 skip "Need MDS version at least 2.3.64"
15892         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15893
15894         local fid=$($LFS path2fid $MOUNT)
15895
15896         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15897                 error "cannot access $MOUNT using its FID '$fid'"
15898 }
15899 run_test 233a "checking that OBF of the FS root succeeds"
15900
15901 test_233b() {
15902         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15903                 skip "Need MDS version at least 2.5.90"
15904         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15905
15906         local fid=$($LFS path2fid $MOUNT/.lustre)
15907
15908         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15909                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15910
15911         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15912         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15913                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15914 }
15915 run_test 233b "checking that OBF of the FS .lustre succeeds"
15916
15917 test_234() {
15918         local p="$TMP/sanityN-$TESTNAME.parameters"
15919         save_lustre_params client "llite.*.xattr_cache" > $p
15920         lctl set_param llite.*.xattr_cache 1 ||
15921                 skip_env "xattr cache is not supported"
15922
15923         mkdir -p $DIR/$tdir || error "mkdir failed"
15924         touch $DIR/$tdir/$tfile || error "touch failed"
15925         # OBD_FAIL_LLITE_XATTR_ENOMEM
15926         $LCTL set_param fail_loc=0x1405
15927         getfattr -n user.attr $DIR/$tdir/$tfile &&
15928                 error "getfattr should have failed with ENOMEM"
15929         $LCTL set_param fail_loc=0x0
15930         rm -rf $DIR/$tdir
15931
15932         restore_lustre_params < $p
15933         rm -f $p
15934 }
15935 run_test 234 "xattr cache should not crash on ENOMEM"
15936
15937 test_235() {
15938         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15939                 skip "Need MDS version at least 2.4.52"
15940
15941         flock_deadlock $DIR/$tfile
15942         local RC=$?
15943         case $RC in
15944                 0)
15945                 ;;
15946                 124) error "process hangs on a deadlock"
15947                 ;;
15948                 *) error "error executing flock_deadlock $DIR/$tfile"
15949                 ;;
15950         esac
15951 }
15952 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15953
15954 #LU-2935
15955 test_236() {
15956         check_swap_layouts_support
15957
15958         local ref1=/etc/passwd
15959         local ref2=/etc/group
15960         local file1=$DIR/$tdir/f1
15961         local file2=$DIR/$tdir/f2
15962
15963         test_mkdir -c1 $DIR/$tdir
15964         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15965         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15966         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15967         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15968         local fd=$(free_fd)
15969         local cmd="exec $fd<>$file2"
15970         eval $cmd
15971         rm $file2
15972         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15973                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15974         cmd="exec $fd>&-"
15975         eval $cmd
15976         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15977
15978         #cleanup
15979         rm -rf $DIR/$tdir
15980 }
15981 run_test 236 "Layout swap on open unlinked file"
15982
15983 # LU-4659 linkea consistency
15984 test_238() {
15985         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15986                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15987                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15988                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15989
15990         touch $DIR/$tfile
15991         ln $DIR/$tfile $DIR/$tfile.lnk
15992         touch $DIR/$tfile.new
15993         mv $DIR/$tfile.new $DIR/$tfile
15994         local fid1=$($LFS path2fid $DIR/$tfile)
15995         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15996         local path1=$($LFS fid2path $FSNAME "$fid1")
15997         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15998         local path2=$($LFS fid2path $FSNAME "$fid2")
15999         [ $tfile.lnk == $path2 ] ||
16000                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16001         rm -f $DIR/$tfile*
16002 }
16003 run_test 238 "Verify linkea consistency"
16004
16005 test_239A() { # was test_239
16006         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16007                 skip "Need MDS version at least 2.5.60"
16008
16009         local list=$(comma_list $(mdts_nodes))
16010
16011         mkdir -p $DIR/$tdir
16012         createmany -o $DIR/$tdir/f- 5000
16013         unlinkmany $DIR/$tdir/f- 5000
16014         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16015                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16016         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16017                         osp.*MDT*.sync_in_flight" | calc_sum)
16018         [ "$changes" -eq 0 ] || error "$changes not synced"
16019 }
16020 run_test 239A "osp_sync test"
16021
16022 test_239a() { #LU-5297
16023         remote_mds_nodsh && skip "remote MDS with nodsh"
16024
16025         touch $DIR/$tfile
16026         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16027         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16028         chgrp $RUNAS_GID $DIR/$tfile
16029         wait_delete_completed
16030 }
16031 run_test 239a "process invalid osp sync record correctly"
16032
16033 test_239b() { #LU-5297
16034         remote_mds_nodsh && skip "remote MDS with nodsh"
16035
16036         touch $DIR/$tfile1
16037         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16038         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16039         chgrp $RUNAS_GID $DIR/$tfile1
16040         wait_delete_completed
16041         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16042         touch $DIR/$tfile2
16043         chgrp $RUNAS_GID $DIR/$tfile2
16044         wait_delete_completed
16045 }
16046 run_test 239b "process osp sync record with ENOMEM error correctly"
16047
16048 test_240() {
16049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16050         remote_mds_nodsh && skip "remote MDS with nodsh"
16051
16052         mkdir -p $DIR/$tdir
16053
16054         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16055                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16056         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16057                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16058
16059         umount_client $MOUNT || error "umount failed"
16060         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16061         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16062         mount_client $MOUNT || error "failed to mount client"
16063
16064         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16065         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16066 }
16067 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16068
16069 test_241_bio() {
16070         local count=$1
16071         local bsize=$2
16072
16073         for LOOP in $(seq $count); do
16074                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16075                 cancel_lru_locks $OSC || true
16076         done
16077 }
16078
16079 test_241_dio() {
16080         local count=$1
16081         local bsize=$2
16082
16083         for LOOP in $(seq $1); do
16084                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16085                         2>/dev/null
16086         done
16087 }
16088
16089 test_241a() { # was test_241
16090         local bsize=$PAGE_SIZE
16091
16092         (( bsize < 40960 )) && bsize=40960
16093         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16094         ls -la $DIR/$tfile
16095         cancel_lru_locks $OSC
16096         test_241_bio 1000 $bsize &
16097         PID=$!
16098         test_241_dio 1000 $bsize
16099         wait $PID
16100 }
16101 run_test 241a "bio vs dio"
16102
16103 test_241b() {
16104         local bsize=$PAGE_SIZE
16105
16106         (( bsize < 40960 )) && bsize=40960
16107         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16108         ls -la $DIR/$tfile
16109         test_241_dio 1000 $bsize &
16110         PID=$!
16111         test_241_dio 1000 $bsize
16112         wait $PID
16113 }
16114 run_test 241b "dio vs dio"
16115
16116 test_242() {
16117         remote_mds_nodsh && skip "remote MDS with nodsh"
16118
16119         mkdir -p $DIR/$tdir
16120         touch $DIR/$tdir/$tfile
16121
16122         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16123         do_facet mds1 lctl set_param fail_loc=0x105
16124         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16125
16126         do_facet mds1 lctl set_param fail_loc=0
16127         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16128 }
16129 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16130
16131 test_243()
16132 {
16133         test_mkdir $DIR/$tdir
16134         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16135 }
16136 run_test 243 "various group lock tests"
16137
16138 test_244()
16139 {
16140         test_mkdir $DIR/$tdir
16141         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16142         sendfile_grouplock $DIR/$tdir/$tfile || \
16143                 error "sendfile+grouplock failed"
16144         rm -rf $DIR/$tdir
16145 }
16146 run_test 244 "sendfile with group lock tests"
16147
16148 test_245() {
16149         local flagname="multi_mod_rpcs"
16150         local connect_data_name="max_mod_rpcs"
16151         local out
16152
16153         # check if multiple modify RPCs flag is set
16154         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16155                 grep "connect_flags:")
16156         echo "$out"
16157
16158         echo "$out" | grep -qw $flagname
16159         if [ $? -ne 0 ]; then
16160                 echo "connect flag $flagname is not set"
16161                 return
16162         fi
16163
16164         # check if multiple modify RPCs data is set
16165         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16166         echo "$out"
16167
16168         echo "$out" | grep -qw $connect_data_name ||
16169                 error "import should have connect data $connect_data_name"
16170 }
16171 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16172
16173 test_246() { # LU-7371
16174         remote_ost_nodsh && skip "remote OST with nodsh"
16175         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16176                 skip "Need OST version >= 2.7.62"
16177
16178         do_facet ost1 $LCTL set_param fail_val=4095
16179 #define OBD_FAIL_OST_READ_SIZE          0x234
16180         do_facet ost1 $LCTL set_param fail_loc=0x234
16181         $LFS setstripe $DIR/$tfile -i 0 -c 1
16182         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16183         cancel_lru_locks $FSNAME-OST0000
16184         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16185 }
16186 run_test 246 "Read file of size 4095 should return right length"
16187
16188 cleanup_247() {
16189         local submount=$1
16190
16191         trap 0
16192         umount_client $submount
16193         rmdir $submount
16194 }
16195
16196 test_247a() {
16197         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16198                 grep -q subtree ||
16199                 skip_env "Fileset feature is not supported"
16200
16201         local submount=${MOUNT}_$tdir
16202
16203         mkdir $MOUNT/$tdir
16204         mkdir -p $submount || error "mkdir $submount failed"
16205         FILESET="$FILESET/$tdir" mount_client $submount ||
16206                 error "mount $submount failed"
16207         trap "cleanup_247 $submount" EXIT
16208         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16209         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16210                 error "read $MOUNT/$tdir/$tfile failed"
16211         cleanup_247 $submount
16212 }
16213 run_test 247a "mount subdir as fileset"
16214
16215 test_247b() {
16216         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16217                 skip_env "Fileset feature is not supported"
16218
16219         local submount=${MOUNT}_$tdir
16220
16221         rm -rf $MOUNT/$tdir
16222         mkdir -p $submount || error "mkdir $submount failed"
16223         SKIP_FILESET=1
16224         FILESET="$FILESET/$tdir" mount_client $submount &&
16225                 error "mount $submount should fail"
16226         rmdir $submount
16227 }
16228 run_test 247b "mount subdir that dose not exist"
16229
16230 test_247c() {
16231         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16232                 skip_env "Fileset feature is not supported"
16233
16234         local submount=${MOUNT}_$tdir
16235
16236         mkdir -p $MOUNT/$tdir/dir1
16237         mkdir -p $submount || error "mkdir $submount failed"
16238         trap "cleanup_247 $submount" EXIT
16239         FILESET="$FILESET/$tdir" mount_client $submount ||
16240                 error "mount $submount failed"
16241         local fid=$($LFS path2fid $MOUNT/)
16242         $LFS fid2path $submount $fid && error "fid2path should fail"
16243         cleanup_247 $submount
16244 }
16245 run_test 247c "running fid2path outside root"
16246
16247 test_247d() {
16248         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16249                 skip "Fileset feature is not supported"
16250
16251         local submount=${MOUNT}_$tdir
16252
16253         mkdir -p $MOUNT/$tdir/dir1
16254         mkdir -p $submount || error "mkdir $submount failed"
16255         FILESET="$FILESET/$tdir" mount_client $submount ||
16256                 error "mount $submount failed"
16257         trap "cleanup_247 $submount" EXIT
16258         local fid=$($LFS path2fid $submount/dir1)
16259         $LFS fid2path $submount $fid || error "fid2path should succeed"
16260         cleanup_247 $submount
16261 }
16262 run_test 247d "running fid2path inside root"
16263
16264 # LU-8037
16265 test_247e() {
16266         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16267                 grep -q subtree ||
16268                 skip "Fileset feature is not supported"
16269
16270         local submount=${MOUNT}_$tdir
16271
16272         mkdir $MOUNT/$tdir
16273         mkdir -p $submount || error "mkdir $submount failed"
16274         FILESET="$FILESET/.." mount_client $submount &&
16275                 error "mount $submount should fail"
16276         rmdir $submount
16277 }
16278 run_test 247e "mount .. as fileset"
16279
16280 test_248() {
16281         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16282         [ -z "$fast_read_sav" ] && skip "no fast read support"
16283
16284         # create a large file for fast read verification
16285         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16286
16287         # make sure the file is created correctly
16288         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16289                 { rm -f $DIR/$tfile; skip "file creation error"; }
16290
16291         echo "Test 1: verify that fast read is 4 times faster on cache read"
16292
16293         # small read with fast read enabled
16294         $LCTL set_param -n llite.*.fast_read=1
16295         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16296                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16297                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16298         # small read with fast read disabled
16299         $LCTL set_param -n llite.*.fast_read=0
16300         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16301                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16302                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16303
16304         # verify that fast read is 4 times faster for cache read
16305         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16306                 error_not_in_vm "fast read was not 4 times faster: " \
16307                            "$t_fast vs $t_slow"
16308
16309         echo "Test 2: verify the performance between big and small read"
16310         $LCTL set_param -n llite.*.fast_read=1
16311
16312         # 1k non-cache read
16313         cancel_lru_locks osc
16314         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16315                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16316                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16317
16318         # 1M non-cache read
16319         cancel_lru_locks osc
16320         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16321                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16322                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16323
16324         # verify that big IO is not 4 times faster than small IO
16325         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16326                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16327
16328         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16329         rm -f $DIR/$tfile
16330 }
16331 run_test 248 "fast read verification"
16332
16333 test_249() { # LU-7890
16334         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16335                 skip "Need at least version 2.8.54"
16336
16337         rm -f $DIR/$tfile
16338         $LFS setstripe -c 1 $DIR/$tfile
16339         # Offset 2T == 4k * 512M
16340         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16341                 error "dd to 2T offset failed"
16342 }
16343 run_test 249 "Write above 2T file size"
16344
16345 test_250() {
16346         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16347          && skip "no 16TB file size limit on ZFS"
16348
16349         $LFS setstripe -c 1 $DIR/$tfile
16350         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16351         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16352         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16353         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16354                 conv=notrunc,fsync && error "append succeeded"
16355         return 0
16356 }
16357 run_test 250 "Write above 16T limit"
16358
16359 test_251() {
16360         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16361
16362         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16363         #Skip once - writing the first stripe will succeed
16364         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16365         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16366                 error "short write happened"
16367
16368         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16369         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16370                 error "short read happened"
16371
16372         rm -f $DIR/$tfile
16373 }
16374 run_test 251 "Handling short read and write correctly"
16375
16376 test_252() {
16377         remote_mds_nodsh && skip "remote MDS with nodsh"
16378         remote_ost_nodsh && skip "remote OST with nodsh"
16379         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16380                 skip_env "ldiskfs only test"
16381         fi
16382
16383         local tgt
16384         local dev
16385         local out
16386         local uuid
16387         local num
16388         local gen
16389
16390         # check lr_reader on OST0000
16391         tgt=ost1
16392         dev=$(facet_device $tgt)
16393         out=$(do_facet $tgt $LR_READER $dev)
16394         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16395         echo "$out"
16396         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16397         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16398                 error "Invalid uuid returned by $LR_READER on target $tgt"
16399         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16400
16401         # check lr_reader -c on MDT0000
16402         tgt=mds1
16403         dev=$(facet_device $tgt)
16404         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16405                 skip "$LR_READER does not support additional options"
16406         fi
16407         out=$(do_facet $tgt $LR_READER -c $dev)
16408         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16409         echo "$out"
16410         num=$(echo "$out" | grep -c "mdtlov")
16411         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16412                 error "Invalid number of mdtlov clients returned by $LR_READER"
16413         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16414
16415         # check lr_reader -cr on MDT0000
16416         out=$(do_facet $tgt $LR_READER -cr $dev)
16417         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16418         echo "$out"
16419         echo "$out" | grep -q "^reply_data:$" ||
16420                 error "$LR_READER should have returned 'reply_data' section"
16421         num=$(echo "$out" | grep -c "client_generation")
16422         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16423 }
16424 run_test 252 "check lr_reader tool"
16425
16426 test_253_fill_ost() {
16427         local size_mb #how many MB should we write to pass watermark
16428         local lwm=$3  #low watermark
16429         local free_10mb #10% of free space
16430
16431         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16432         size_mb=$((free_kb / 1024 - lwm))
16433         free_10mb=$((free_kb / 10240))
16434         #If 10% of free space cross low watermark use it
16435         if (( free_10mb > size_mb )); then
16436                 size_mb=$free_10mb
16437         else
16438                 #At least we need to store 1.1 of difference between
16439                 #free space and low watermark
16440                 size_mb=$((size_mb + size_mb / 10))
16441         fi
16442         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16443                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16444                          oflag=append conv=notrunc
16445         fi
16446
16447         sleep_maxage
16448
16449         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16450         echo "OST still has $((free_kb / 1024)) mbytes free"
16451 }
16452
16453 test_253() {
16454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16455         remote_mds_nodsh && skip "remote MDS with nodsh"
16456         remote_mgs_nodsh && skip "remote MGS with nodsh"
16457
16458         local ostidx=0
16459         local rc=0
16460
16461         local ost_name=$($LFS osts |
16462                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16463         # on the mdt's osc
16464         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16465         do_facet $SINGLEMDS $LCTL get_param -n \
16466                 osp.$mdtosc_proc1.reserved_mb_high ||
16467                 skip  "remote MDS does not support reserved_mb_high"
16468
16469         rm -rf $DIR/$tdir
16470         wait_mds_ost_sync
16471         wait_delete_completed
16472         mkdir $DIR/$tdir
16473
16474         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16475                         osp.$mdtosc_proc1.reserved_mb_high)
16476         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16477                         osp.$mdtosc_proc1.reserved_mb_low)
16478         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16479
16480         if ! combined_mgs_mds ; then
16481                 mount_mgs_client
16482         fi
16483         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16484         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16485                 error "Adding $ost_name to pool failed"
16486
16487         # Wait for client to see a OST at pool
16488         wait_update $HOSTNAME "$LCTL get_param -n
16489                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16490                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16491                 error "Client can not see the pool"
16492         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16493                 error "Setstripe failed"
16494
16495         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16496         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16497         echo "OST still has $((blocks/1024)) mbytes free"
16498
16499         local new_lwm=$((blocks/1024-10))
16500         do_facet $SINGLEMDS $LCTL set_param \
16501                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16502         do_facet $SINGLEMDS $LCTL set_param \
16503                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16504
16505         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16506
16507         #First enospc could execute orphan deletion so repeat.
16508         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16509
16510         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16511                         osp.$mdtosc_proc1.prealloc_status)
16512         echo "prealloc_status $oa_status"
16513
16514         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16515                 error "File creation should fail"
16516         #object allocation was stopped, but we still able to append files
16517         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16518                 error "Append failed"
16519         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16520
16521         wait_delete_completed
16522
16523         sleep_maxage
16524
16525         for i in $(seq 10 12); do
16526                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16527                         error "File creation failed after rm";
16528         done
16529
16530         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16531                         osp.$mdtosc_proc1.prealloc_status)
16532         echo "prealloc_status $oa_status"
16533
16534         if (( oa_status != 0 )); then
16535                 error "Object allocation still disable after rm"
16536         fi
16537         do_facet $SINGLEMDS $LCTL set_param \
16538                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16539         do_facet $SINGLEMDS $LCTL set_param \
16540                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16541
16542
16543         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16544                 error "Remove $ost_name from pool failed"
16545         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16546                 error "Pool destroy fialed"
16547
16548         if ! combined_mgs_mds ; then
16549                 umount_mgs_client
16550         fi
16551 }
16552 run_test 253 "Check object allocation limit"
16553
16554 test_254() {
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556         remote_mds_nodsh && skip "remote MDS with nodsh"
16557         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16558                 skip "MDS does not support changelog_size"
16559
16560         local cl_user
16561         local MDT0=$(facet_svc $SINGLEMDS)
16562
16563         changelog_register || error "changelog_register failed"
16564
16565         changelog_clear 0 || error "changelog_clear failed"
16566
16567         local size1=$(do_facet $SINGLEMDS \
16568                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16569         echo "Changelog size $size1"
16570
16571         rm -rf $DIR/$tdir
16572         $LFS mkdir -i 0 $DIR/$tdir
16573         # change something
16574         mkdir -p $DIR/$tdir/pics/2008/zachy
16575         touch $DIR/$tdir/pics/2008/zachy/timestamp
16576         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16577         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16578         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16579         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16580         rm $DIR/$tdir/pics/desktop.jpg
16581
16582         local size2=$(do_facet $SINGLEMDS \
16583                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16584         echo "Changelog size after work $size2"
16585
16586         (( $size2 > $size1 )) ||
16587                 error "new Changelog size=$size2 less than old size=$size1"
16588 }
16589 run_test 254 "Check changelog size"
16590
16591 ladvise_no_type()
16592 {
16593         local type=$1
16594         local file=$2
16595
16596         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16597                 awk -F: '{print $2}' | grep $type > /dev/null
16598         if [ $? -ne 0 ]; then
16599                 return 0
16600         fi
16601         return 1
16602 }
16603
16604 ladvise_no_ioctl()
16605 {
16606         local file=$1
16607
16608         lfs ladvise -a willread $file > /dev/null 2>&1
16609         if [ $? -eq 0 ]; then
16610                 return 1
16611         fi
16612
16613         lfs ladvise -a willread $file 2>&1 |
16614                 grep "Inappropriate ioctl for device" > /dev/null
16615         if [ $? -eq 0 ]; then
16616                 return 0
16617         fi
16618         return 1
16619 }
16620
16621 percent() {
16622         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16623 }
16624
16625 # run a random read IO workload
16626 # usage: random_read_iops <filename> <filesize> <iosize>
16627 random_read_iops() {
16628         local file=$1
16629         local fsize=$2
16630         local iosize=${3:-4096}
16631
16632         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16633                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16634 }
16635
16636 drop_file_oss_cache() {
16637         local file="$1"
16638         local nodes="$2"
16639
16640         $LFS ladvise -a dontneed $file 2>/dev/null ||
16641                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16642 }
16643
16644 ladvise_willread_performance()
16645 {
16646         local repeat=10
16647         local average_origin=0
16648         local average_cache=0
16649         local average_ladvise=0
16650
16651         for ((i = 1; i <= $repeat; i++)); do
16652                 echo "Iter $i/$repeat: reading without willread hint"
16653                 cancel_lru_locks osc
16654                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16655                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16656                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16657                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16658
16659                 cancel_lru_locks osc
16660                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16661                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16662                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16663
16664                 cancel_lru_locks osc
16665                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16666                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16667                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16668                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16669                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16670         done
16671         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16672         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16673         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16674
16675         speedup_cache=$(percent $average_cache $average_origin)
16676         speedup_ladvise=$(percent $average_ladvise $average_origin)
16677
16678         echo "Average uncached read: $average_origin"
16679         echo "Average speedup with OSS cached read: " \
16680                 "$average_cache = +$speedup_cache%"
16681         echo "Average speedup with ladvise willread: " \
16682                 "$average_ladvise = +$speedup_ladvise%"
16683
16684         local lowest_speedup=20
16685         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16686                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16687                         "got $average_cache%. Skipping ladvise willread check."
16688                 return 0
16689         fi
16690
16691         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16692         # it is still good to run until then to exercise 'ladvise willread'
16693         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16694                 [ "$ost1_FSTYPE" = "zfs" ] &&
16695                 echo "osd-zfs does not support dontneed or drop_caches" &&
16696                 return 0
16697
16698         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16699         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16700                 error_not_in_vm "Speedup with willread is less than " \
16701                         "$lowest_speedup%, got $average_ladvise%"
16702 }
16703
16704 test_255a() {
16705         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16706                 skip "lustre < 2.8.54 does not support ladvise "
16707         remote_ost_nodsh && skip "remote OST with nodsh"
16708
16709         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16710
16711         ladvise_no_type willread $DIR/$tfile &&
16712                 skip "willread ladvise is not supported"
16713
16714         ladvise_no_ioctl $DIR/$tfile &&
16715                 skip "ladvise ioctl is not supported"
16716
16717         local size_mb=100
16718         local size=$((size_mb * 1048576))
16719         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16720                 error "dd to $DIR/$tfile failed"
16721
16722         lfs ladvise -a willread $DIR/$tfile ||
16723                 error "Ladvise failed with no range argument"
16724
16725         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16726                 error "Ladvise failed with no -l or -e argument"
16727
16728         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16729                 error "Ladvise failed with only -e argument"
16730
16731         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16732                 error "Ladvise failed with only -l argument"
16733
16734         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16735                 error "End offset should not be smaller than start offset"
16736
16737         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16738                 error "End offset should not be equal to start offset"
16739
16740         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16741                 error "Ladvise failed with overflowing -s argument"
16742
16743         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16744                 error "Ladvise failed with overflowing -e argument"
16745
16746         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16747                 error "Ladvise failed with overflowing -l argument"
16748
16749         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16750                 error "Ladvise succeeded with conflicting -l and -e arguments"
16751
16752         echo "Synchronous ladvise should wait"
16753         local delay=4
16754 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16755         do_nodes $(comma_list $(osts_nodes)) \
16756                 $LCTL set_param fail_val=$delay fail_loc=0x237
16757
16758         local start_ts=$SECONDS
16759         lfs ladvise -a willread $DIR/$tfile ||
16760                 error "Ladvise failed with no range argument"
16761         local end_ts=$SECONDS
16762         local inteval_ts=$((end_ts - start_ts))
16763
16764         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16765                 error "Synchronous advice didn't wait reply"
16766         fi
16767
16768         echo "Asynchronous ladvise shouldn't wait"
16769         local start_ts=$SECONDS
16770         lfs ladvise -a willread -b $DIR/$tfile ||
16771                 error "Ladvise failed with no range argument"
16772         local end_ts=$SECONDS
16773         local inteval_ts=$((end_ts - start_ts))
16774
16775         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16776                 error "Asynchronous advice blocked"
16777         fi
16778
16779         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16780         ladvise_willread_performance
16781 }
16782 run_test 255a "check 'lfs ladvise -a willread'"
16783
16784 facet_meminfo() {
16785         local facet=$1
16786         local info=$2
16787
16788         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16789 }
16790
16791 test_255b() {
16792         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16793                 skip "lustre < 2.8.54 does not support ladvise "
16794         remote_ost_nodsh && skip "remote OST with nodsh"
16795
16796         lfs setstripe -c 1 -i 0 $DIR/$tfile
16797
16798         ladvise_no_type dontneed $DIR/$tfile &&
16799                 skip "dontneed ladvise is not supported"
16800
16801         ladvise_no_ioctl $DIR/$tfile &&
16802                 skip "ladvise ioctl is not supported"
16803
16804         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16805                 [ "$ost1_FSTYPE" = "zfs" ] &&
16806                 skip "zfs-osd does not support 'ladvise dontneed'"
16807
16808         local size_mb=100
16809         local size=$((size_mb * 1048576))
16810         # In order to prevent disturbance of other processes, only check 3/4
16811         # of the memory usage
16812         local kibibytes=$((size_mb * 1024 * 3 / 4))
16813
16814         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16815                 error "dd to $DIR/$tfile failed"
16816
16817         #force write to complete before dropping OST cache & checking memory
16818         sync
16819
16820         local total=$(facet_meminfo ost1 MemTotal)
16821         echo "Total memory: $total KiB"
16822
16823         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16824         local before_read=$(facet_meminfo ost1 Cached)
16825         echo "Cache used before read: $before_read KiB"
16826
16827         lfs ladvise -a willread $DIR/$tfile ||
16828                 error "Ladvise willread failed"
16829         local after_read=$(facet_meminfo ost1 Cached)
16830         echo "Cache used after read: $after_read KiB"
16831
16832         lfs ladvise -a dontneed $DIR/$tfile ||
16833                 error "Ladvise dontneed again failed"
16834         local no_read=$(facet_meminfo ost1 Cached)
16835         echo "Cache used after dontneed ladvise: $no_read KiB"
16836
16837         if [ $total -lt $((before_read + kibibytes)) ]; then
16838                 echo "Memory is too small, abort checking"
16839                 return 0
16840         fi
16841
16842         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16843                 error "Ladvise willread should use more memory" \
16844                         "than $kibibytes KiB"
16845         fi
16846
16847         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16848                 error "Ladvise dontneed should release more memory" \
16849                         "than $kibibytes KiB"
16850         fi
16851 }
16852 run_test 255b "check 'lfs ladvise -a dontneed'"
16853
16854 test_255c() {
16855         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16856                 skip "lustre < 2.10.53 does not support lockahead"
16857
16858         local count
16859         local new_count
16860         local difference
16861         local i
16862         local rc
16863
16864         test_mkdir -p $DIR/$tdir
16865         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16866
16867         #test 10 returns only success/failure
16868         i=10
16869         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16870         rc=$?
16871         if [ $rc -eq 255 ]; then
16872                 error "Ladvise test${i} failed, ${rc}"
16873         fi
16874
16875         #test 11 counts lock enqueue requests, all others count new locks
16876         i=11
16877         count=$(do_facet ost1 \
16878                 $LCTL get_param -n ost.OSS.ost.stats)
16879         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16880
16881         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16882         rc=$?
16883         if [ $rc -eq 255 ]; then
16884                 error "Ladvise test${i} failed, ${rc}"
16885         fi
16886
16887         new_count=$(do_facet ost1 \
16888                 $LCTL get_param -n ost.OSS.ost.stats)
16889         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16890                    awk '{ print $2 }')
16891
16892         difference="$((new_count - count))"
16893         if [ $difference -ne $rc ]; then
16894                 error "Ladvise test${i}, bad enqueue count, returned " \
16895                       "${rc}, actual ${difference}"
16896         fi
16897
16898         for i in $(seq 12 21); do
16899                 # If we do not do this, we run the risk of having too many
16900                 # locks and starting lock cancellation while we are checking
16901                 # lock counts.
16902                 cancel_lru_locks osc
16903
16904                 count=$($LCTL get_param -n \
16905                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16906
16907                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16908                 rc=$?
16909                 if [ $rc -eq 255 ]; then
16910                         error "Ladvise test ${i} failed, ${rc}"
16911                 fi
16912
16913                 new_count=$($LCTL get_param -n \
16914                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16915                 difference="$((new_count - count))"
16916
16917                 # Test 15 output is divided by 100 to map down to valid return
16918                 if [ $i -eq 15 ]; then
16919                         rc="$((rc * 100))"
16920                 fi
16921
16922                 if [ $difference -ne $rc ]; then
16923                         error "Ladvise test ${i}, bad lock count, returned " \
16924                               "${rc}, actual ${difference}"
16925                 fi
16926         done
16927
16928         #test 22 returns only success/failure
16929         i=22
16930         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16931         rc=$?
16932         if [ $rc -eq 255 ]; then
16933                 error "Ladvise test${i} failed, ${rc}"
16934         fi
16935 }
16936 run_test 255c "suite of ladvise lockahead tests"
16937
16938 test_256() {
16939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16940         remote_mds_nodsh && skip "remote MDS with nodsh"
16941         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16942         changelog_users $SINGLEMDS | grep "^cl" &&
16943                 skip "active changelog user"
16944
16945         local cl_user
16946         local cat_sl
16947         local mdt_dev
16948
16949         mdt_dev=$(mdsdevname 1)
16950         echo $mdt_dev
16951
16952         changelog_register || error "changelog_register failed"
16953
16954         rm -rf $DIR/$tdir
16955         mkdir -p $DIR/$tdir
16956
16957         changelog_clear 0 || error "changelog_clear failed"
16958
16959         # change something
16960         touch $DIR/$tdir/{1..10}
16961
16962         # stop the MDT
16963         stop $SINGLEMDS || error "Fail to stop MDT"
16964
16965         # remount the MDT
16966
16967         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16968
16969         #after mount new plainllog is used
16970         touch $DIR/$tdir/{11..19}
16971         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16972         cat_sl=$(do_facet $SINGLEMDS "sync; \
16973                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16974                  llog_reader $tmpfile | grep -c type=1064553b")
16975         do_facet $SINGLEMDS llog_reader $tmpfile
16976
16977         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16978
16979         changelog_clear 0 || error "changelog_clear failed"
16980
16981         cat_sl=$(do_facet $SINGLEMDS "sync; \
16982                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16983                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16984
16985         if (( cat_sl == 2 )); then
16986                 error "Empty plain llog was not deleted from changelog catalog"
16987         elif (( cat_sl != 1 )); then
16988                 error "Active plain llog shouldn't be deleted from catalog"
16989         fi
16990 }
16991 run_test 256 "Check llog delete for empty and not full state"
16992
16993 test_257() {
16994         remote_mds_nodsh && skip "remote MDS with nodsh"
16995         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16996                 skip "Need MDS version at least 2.8.55"
16997
16998         test_mkdir $DIR/$tdir
16999
17000         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17001                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17002         stat $DIR/$tdir
17003
17004 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17005         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17006         local facet=mds$((mdtidx + 1))
17007         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17008         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17009
17010         stop $facet || error "stop MDS failed"
17011         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17012                 error "start MDS fail"
17013         wait_recovery_complete $facet
17014 }
17015 run_test 257 "xattr locks are not lost"
17016
17017 # Verify we take the i_mutex when security requires it
17018 test_258a() {
17019 #define OBD_FAIL_IMUTEX_SEC 0x141c
17020         $LCTL set_param fail_loc=0x141c
17021         touch $DIR/$tfile
17022         chmod u+s $DIR/$tfile
17023         chmod a+rwx $DIR/$tfile
17024         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17025         RC=$?
17026         if [ $RC -ne 0 ]; then
17027                 error "error, failed to take i_mutex, rc=$?"
17028         fi
17029         rm -f $DIR/$tfile
17030 }
17031 run_test 258a
17032
17033 # Verify we do NOT take the i_mutex in the normal case
17034 test_258b() {
17035 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17036         $LCTL set_param fail_loc=0x141d
17037         touch $DIR/$tfile
17038         chmod a+rwx $DIR
17039         chmod a+rw $DIR/$tfile
17040         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17041         RC=$?
17042         if [ $RC -ne 0 ]; then
17043                 error "error, took i_mutex unnecessarily, rc=$?"
17044         fi
17045         rm -f $DIR/$tfile
17046
17047 }
17048 run_test 258b "verify i_mutex security behavior"
17049
17050 test_259() {
17051         local file=$DIR/$tfile
17052         local before
17053         local after
17054
17055         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17056
17057         stack_trap "rm -f $file" EXIT
17058
17059         wait_delete_completed
17060         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17061         echo "before: $before"
17062
17063         $LFS setstripe -i 0 -c 1 $file
17064         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17065         sync_all_data
17066         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17067         echo "after write: $after"
17068
17069 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17070         do_facet ost1 $LCTL set_param fail_loc=0x2301
17071         $TRUNCATE $file 0
17072         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17073         echo "after truncate: $after"
17074
17075         stop ost1
17076         do_facet ost1 $LCTL set_param fail_loc=0
17077         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17078         sleep 2
17079         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17080         echo "after restart: $after"
17081         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17082                 error "missing truncate?"
17083
17084         return 0
17085 }
17086 run_test 259 "crash at delayed truncate"
17087
17088 test_260() {
17089 #define OBD_FAIL_MDC_CLOSE               0x806
17090         $LCTL set_param fail_loc=0x80000806
17091         touch $DIR/$tfile
17092
17093 }
17094 run_test 260 "Check mdc_close fail"
17095
17096 ### Data-on-MDT sanity tests ###
17097 test_270a() {
17098         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17099                 skip "Need MDS version at least 2.10.55 for DoM"
17100
17101         # create DoM file
17102         local dom=$DIR/$tdir/dom_file
17103         local tmp=$DIR/$tdir/tmp_file
17104
17105         mkdir -p $DIR/$tdir
17106
17107         # basic checks for DoM component creation
17108         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17109                 error "Can set MDT layout to non-first entry"
17110
17111         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17112                 error "Can define multiple entries as MDT layout"
17113
17114         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17115
17116         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17117         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17118         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17119
17120         local mdtidx=$($LFS getstripe -m $dom)
17121         local mdtname=MDT$(printf %04x $mdtidx)
17122         local facet=mds$((mdtidx + 1))
17123         local space_check=1
17124
17125         # Skip free space checks with ZFS
17126         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17127
17128         # write
17129         sync
17130         local size_tmp=$((65536 * 3))
17131         local mdtfree1=$(do_facet $facet \
17132                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17133
17134         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17135         # check also direct IO along write
17136         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17137         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17138         sync
17139         cmp $tmp $dom || error "file data is different"
17140         [ $(stat -c%s $dom) == $size_tmp ] ||
17141                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17142         if [ $space_check == 1 ]; then
17143                 local mdtfree2=$(do_facet $facet \
17144                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17145
17146                 # increase in usage from by $size_tmp
17147                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17148                         error "MDT free space wrong after write: " \
17149                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17150         fi
17151
17152         # truncate
17153         local size_dom=10000
17154
17155         $TRUNCATE $dom $size_dom
17156         [ $(stat -c%s $dom) == $size_dom ] ||
17157                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17158         if [ $space_check == 1 ]; then
17159                 mdtfree1=$(do_facet $facet \
17160                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17161                 # decrease in usage from $size_tmp to new $size_dom
17162                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17163                   $(((size_tmp - size_dom) / 1024)) ] ||
17164                         error "MDT free space is wrong after truncate: " \
17165                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17166         fi
17167
17168         # append
17169         cat $tmp >> $dom
17170         sync
17171         size_dom=$((size_dom + size_tmp))
17172         [ $(stat -c%s $dom) == $size_dom ] ||
17173                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17174         if [ $space_check == 1 ]; then
17175                 mdtfree2=$(do_facet $facet \
17176                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17177                 # increase in usage by $size_tmp from previous
17178                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17179                         error "MDT free space is wrong after append: " \
17180                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17181         fi
17182
17183         # delete
17184         rm $dom
17185         if [ $space_check == 1 ]; then
17186                 mdtfree1=$(do_facet $facet \
17187                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17188                 # decrease in usage by $size_dom from previous
17189                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17190                         error "MDT free space is wrong after removal: " \
17191                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17192         fi
17193
17194         # combined striping
17195         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17196                 error "Can't create DoM + OST striping"
17197
17198         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17199         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17200         # check also direct IO along write
17201         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17202         sync
17203         cmp $tmp $dom || error "file data is different"
17204         [ $(stat -c%s $dom) == $size_tmp ] ||
17205                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17206         rm $dom $tmp
17207
17208         return 0
17209 }
17210 run_test 270a "DoM: basic functionality tests"
17211
17212 test_270b() {
17213         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17214                 skip "Need MDS version at least 2.10.55"
17215
17216         local dom=$DIR/$tdir/dom_file
17217         local max_size=1048576
17218
17219         mkdir -p $DIR/$tdir
17220         $LFS setstripe -E $max_size -L mdt $dom
17221
17222         # truncate over the limit
17223         $TRUNCATE $dom $(($max_size + 1)) &&
17224                 error "successful truncate over the maximum size"
17225         # write over the limit
17226         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17227                 error "successful write over the maximum size"
17228         # append over the limit
17229         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17230         echo "12345" >> $dom && error "successful append over the maximum size"
17231         rm $dom
17232
17233         return 0
17234 }
17235 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17236
17237 test_270c() {
17238         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17239                 skip "Need MDS version at least 2.10.55"
17240
17241         mkdir -p $DIR/$tdir
17242         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17243
17244         # check files inherit DoM EA
17245         touch $DIR/$tdir/first
17246         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17247                 error "bad pattern"
17248         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17249                 error "bad stripe count"
17250         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17251                 error "bad stripe size"
17252
17253         # check directory inherits DoM EA and uses it as default
17254         mkdir $DIR/$tdir/subdir
17255         touch $DIR/$tdir/subdir/second
17256         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17257                 error "bad pattern in sub-directory"
17258         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17259                 error "bad stripe count in sub-directory"
17260         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17261                 error "bad stripe size in sub-directory"
17262         return 0
17263 }
17264 run_test 270c "DoM: DoM EA inheritance tests"
17265
17266 test_270d() {
17267         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17268                 skip "Need MDS version at least 2.10.55"
17269
17270         mkdir -p $DIR/$tdir
17271         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17272
17273         # inherit default DoM striping
17274         mkdir $DIR/$tdir/subdir
17275         touch $DIR/$tdir/subdir/f1
17276
17277         # change default directory striping
17278         $LFS setstripe -c 1 $DIR/$tdir/subdir
17279         touch $DIR/$tdir/subdir/f2
17280         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17281                 error "wrong default striping in file 2"
17282         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17283                 error "bad pattern in file 2"
17284         return 0
17285 }
17286 run_test 270d "DoM: change striping from DoM to RAID0"
17287
17288 test_270e() {
17289         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17290                 skip "Need MDS version at least 2.10.55"
17291
17292         mkdir -p $DIR/$tdir/dom
17293         mkdir -p $DIR/$tdir/norm
17294         DOMFILES=20
17295         NORMFILES=10
17296         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17297         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17298
17299         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17300         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17301
17302         # find DoM files by layout
17303         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17304         [ $NUM -eq  $DOMFILES ] ||
17305                 error "lfs find -L: found $NUM, expected $DOMFILES"
17306         echo "Test 1: lfs find 20 DOM files by layout: OK"
17307
17308         # there should be 1 dir with default DOM striping
17309         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17310         [ $NUM -eq  1 ] ||
17311                 error "lfs find -L: found $NUM, expected 1 dir"
17312         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17313
17314         # find DoM files by stripe size
17315         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17316         [ $NUM -eq  $DOMFILES ] ||
17317                 error "lfs find -S: found $NUM, expected $DOMFILES"
17318         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17319
17320         # find files by stripe offset except DoM files
17321         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17322         [ $NUM -eq  $NORMFILES ] ||
17323                 error "lfs find -i: found $NUM, expected $NORMFILES"
17324         echo "Test 5: lfs find no DOM files by stripe index: OK"
17325         return 0
17326 }
17327 run_test 270e "DoM: lfs find with DoM files test"
17328
17329 test_270f() {
17330         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17331                 skip "Need MDS version at least 2.10.55"
17332
17333         local mdtname=${FSNAME}-MDT0000-mdtlov
17334         local dom=$DIR/$tdir/dom_file
17335         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17336                                                 lod.$mdtname.dom_stripesize)
17337         local dom_limit=131072
17338
17339         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17340         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17341                                                 lod.$mdtname.dom_stripesize)
17342         [ ${dom_limit} -eq ${dom_current} ] ||
17343                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17344
17345         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17346         $LFS setstripe -d $DIR/$tdir
17347         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17348                 error "Can't set directory default striping"
17349
17350         # exceed maximum stripe size
17351         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17352                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17353         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17354                 error "Able to create DoM component size more than LOD limit"
17355
17356         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17357         dom_current=$(do_facet mds1 $LCTL get_param -n \
17358                                                 lod.$mdtname.dom_stripesize)
17359         [ 0 -eq ${dom_current} ] ||
17360                 error "Can't set zero DoM stripe limit"
17361         rm $dom
17362
17363         # attempt to create DoM file on server with disabled DoM should
17364         # remove DoM entry from layout and be succeed
17365         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17366                 error "Can't create DoM file (DoM is disabled)"
17367         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17368                 error "File has DoM component while DoM is disabled"
17369         rm $dom
17370
17371         # attempt to create DoM file with only DoM stripe should return error
17372         $LFS setstripe -E $dom_limit -L mdt $dom &&
17373                 error "Able to create DoM-only file while DoM is disabled"
17374
17375         # too low values to be aligned with smallest stripe size 64K
17376         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17377         dom_current=$(do_facet mds1 $LCTL get_param -n \
17378                                                 lod.$mdtname.dom_stripesize)
17379         [ 30000 -eq ${dom_current} ] &&
17380                 error "Can set too small DoM stripe limit"
17381
17382         # 64K is a minimal stripe size in Lustre, expect limit of that size
17383         [ 65536 -eq ${dom_current} ] ||
17384                 error "Limit is not set to 64K but ${dom_current}"
17385
17386         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17387         dom_current=$(do_facet mds1 $LCTL get_param -n \
17388                                                 lod.$mdtname.dom_stripesize)
17389         echo $dom_current
17390         [ 2147483648 -eq ${dom_current} ] &&
17391                 error "Can set too large DoM stripe limit"
17392
17393         do_facet mds1 $LCTL set_param -n \
17394                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17395         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17396                 error "Can't create DoM component size after limit change"
17397         do_facet mds1 $LCTL set_param -n \
17398                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17399         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17400                 error "Can't create DoM file after limit decrease"
17401         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17402                 error "Can create big DoM component after limit decrease"
17403         touch ${dom}_def ||
17404                 error "Can't create file with old default layout"
17405
17406         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17407         return 0
17408 }
17409 run_test 270f "DoM: maximum DoM stripe size checks"
17410
17411 test_271a() {
17412         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17413                 skip "Need MDS version at least 2.10.55"
17414
17415         local dom=$DIR/$tdir/dom
17416
17417         mkdir -p $DIR/$tdir
17418
17419         $LFS setstripe -E 1024K -L mdt $dom
17420
17421         lctl set_param -n mdc.*.stats=clear
17422         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17423         cat $dom > /dev/null
17424         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17425         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17426         ls $dom
17427         rm -f $dom
17428 }
17429 run_test 271a "DoM: data is cached for read after write"
17430
17431 test_271b() {
17432         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17433                 skip "Need MDS version at least 2.10.55"
17434
17435         local dom=$DIR/$tdir/dom
17436
17437         mkdir -p $DIR/$tdir
17438
17439         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17440
17441         lctl set_param -n mdc.*.stats=clear
17442         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17443         cancel_lru_locks mdc
17444         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17445         # second stat to check size is cached on client
17446         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17447         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17448         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17449         rm -f $dom
17450 }
17451 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17452
17453 test_271ba() {
17454         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17455                 skip "Need MDS version at least 2.10.55"
17456
17457         local dom=$DIR/$tdir/dom
17458
17459         mkdir -p $DIR/$tdir
17460
17461         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17462
17463         lctl set_param -n mdc.*.stats=clear
17464         lctl set_param -n osc.*.stats=clear
17465         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17466         cancel_lru_locks mdc
17467         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17468         # second stat to check size is cached on client
17469         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17470         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17471         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17472         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17473         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17474         rm -f $dom
17475 }
17476 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17477
17478
17479 get_mdc_stats() {
17480         local mdtidx=$1
17481         local param=$2
17482         local mdt=MDT$(printf %04x $mdtidx)
17483
17484         if [ -z $param ]; then
17485                 lctl get_param -n mdc.*$mdt*.stats
17486         else
17487                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17488         fi
17489 }
17490
17491 test_271c() {
17492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17493                 skip "Need MDS version at least 2.10.55"
17494
17495         local dom=$DIR/$tdir/dom
17496
17497         mkdir -p $DIR/$tdir
17498
17499         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17500
17501         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17502         local facet=mds$((mdtidx + 1))
17503
17504         cancel_lru_locks mdc
17505         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17506         createmany -o $dom 1000
17507         lctl set_param -n mdc.*.stats=clear
17508         smalliomany -w $dom 1000 200
17509         get_mdc_stats $mdtidx
17510         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17511         # Each file has 1 open, 1 IO enqueues, total 2000
17512         # but now we have also +1 getxattr for security.capability, total 3000
17513         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17514         unlinkmany $dom 1000
17515
17516         cancel_lru_locks mdc
17517         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17518         createmany -o $dom 1000
17519         lctl set_param -n mdc.*.stats=clear
17520         smalliomany -w $dom 1000 200
17521         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17522         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17523         # for OPEN and IO lock.
17524         [ $((enq - enq_2)) -ge 1000 ] ||
17525                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17526         unlinkmany $dom 1000
17527         return 0
17528 }
17529 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17530
17531 cleanup_271def_tests() {
17532         trap 0
17533         rm -f $1
17534 }
17535
17536 test_271d() {
17537         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17538                 skip "Need MDS version at least 2.10.57"
17539
17540         local dom=$DIR/$tdir/dom
17541         local tmp=$TMP/$tfile
17542         trap "cleanup_271def_tests $tmp" EXIT
17543
17544         mkdir -p $DIR/$tdir
17545
17546         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17547
17548         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17549
17550         cancel_lru_locks mdc
17551         dd if=/dev/urandom of=$tmp bs=1000 count=1
17552         dd if=$tmp of=$dom bs=1000 count=1
17553         cancel_lru_locks mdc
17554
17555         cat /etc/hosts >> $tmp
17556         lctl set_param -n mdc.*.stats=clear
17557
17558         # append data to the same file it should update local page
17559         echo "Append to the same page"
17560         cat /etc/hosts >> $dom
17561         local num=$(get_mdc_stats $mdtidx ost_read)
17562         local ra=$(get_mdc_stats $mdtidx req_active)
17563         local rw=$(get_mdc_stats $mdtidx req_waittime)
17564
17565         [ -z $num ] || error "$num READ RPC occured"
17566         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17567         echo "... DONE"
17568
17569         # compare content
17570         cmp $tmp $dom || error "file miscompare"
17571
17572         cancel_lru_locks mdc
17573         lctl set_param -n mdc.*.stats=clear
17574
17575         echo "Open and read file"
17576         cat $dom > /dev/null
17577         local num=$(get_mdc_stats $mdtidx ost_read)
17578         local ra=$(get_mdc_stats $mdtidx req_active)
17579         local rw=$(get_mdc_stats $mdtidx req_waittime)
17580
17581         [ -z $num ] || error "$num READ RPC occured"
17582         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17583         echo "... DONE"
17584
17585         # compare content
17586         cmp $tmp $dom || error "file miscompare"
17587
17588         return 0
17589 }
17590 run_test 271d "DoM: read on open (1K file in reply buffer)"
17591
17592 test_271f() {
17593         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17594                 skip "Need MDS version at least 2.10.57"
17595
17596         local dom=$DIR/$tdir/dom
17597         local tmp=$TMP/$tfile
17598         trap "cleanup_271def_tests $tmp" EXIT
17599
17600         mkdir -p $DIR/$tdir
17601
17602         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17603
17604         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17605
17606         cancel_lru_locks mdc
17607         dd if=/dev/urandom of=$tmp bs=200000 count=1
17608         dd if=$tmp of=$dom bs=200000 count=1
17609         cancel_lru_locks mdc
17610         cat /etc/hosts >> $tmp
17611         lctl set_param -n mdc.*.stats=clear
17612
17613         echo "Append to the same page"
17614         cat /etc/hosts >> $dom
17615         local num=$(get_mdc_stats $mdtidx ost_read)
17616         local ra=$(get_mdc_stats $mdtidx req_active)
17617         local rw=$(get_mdc_stats $mdtidx req_waittime)
17618
17619         [ -z $num ] || error "$num READ RPC occured"
17620         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17621         echo "... DONE"
17622
17623         # compare content
17624         cmp $tmp $dom || error "file miscompare"
17625
17626         cancel_lru_locks mdc
17627         lctl set_param -n mdc.*.stats=clear
17628
17629         echo "Open and read file"
17630         cat $dom > /dev/null
17631         local num=$(get_mdc_stats $mdtidx ost_read)
17632         local ra=$(get_mdc_stats $mdtidx req_active)
17633         local rw=$(get_mdc_stats $mdtidx req_waittime)
17634
17635         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17636         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17637         echo "... DONE"
17638
17639         # compare content
17640         cmp $tmp $dom || error "file miscompare"
17641
17642         return 0
17643 }
17644 run_test 271f "DoM: read on open (200K file and read tail)"
17645
17646 test_272a() {
17647         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17648                 skip "Need MDS version at least 2.11.50"
17649
17650         local dom=$DIR/$tdir/dom
17651         mkdir -p $DIR/$tdir
17652
17653         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17654         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17655                 error "failed to write data into $dom"
17656         local old_md5=$(md5sum $dom)
17657
17658         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17659                 error "failed to migrate to the same DoM component"
17660
17661         local new_md5=$(md5sum $dom)
17662
17663         [ "$old_md5" == "$new_md5" ] ||
17664                 error "md5sum differ: $old_md5, $new_md5"
17665
17666         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17667                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17668 }
17669 run_test 272a "DoM migration: new layout with the same DOM component"
17670
17671 test_272b() {
17672         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17673                 skip "Need MDS version at least 2.11.50"
17674
17675         local dom=$DIR/$tdir/dom
17676         mkdir -p $DIR/$tdir
17677         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17678
17679         local mdtidx=$($LFS getstripe -m $dom)
17680         local mdtname=MDT$(printf %04x $mdtidx)
17681         local facet=mds$((mdtidx + 1))
17682
17683         local mdtfree1=$(do_facet $facet \
17684                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17685         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17686                 error "failed to write data into $dom"
17687         local old_md5=$(md5sum $dom)
17688         cancel_lru_locks mdc
17689         local mdtfree1=$(do_facet $facet \
17690                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17691
17692         $LFS migrate -c2 $dom ||
17693                 error "failed to migrate to the new composite layout"
17694         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17695                 error "MDT stripe was not removed"
17696
17697         cancel_lru_locks mdc
17698         local new_md5=$(md5sum $dom)
17699         [ "$old_md5" != "$new_md5" ] &&
17700                 error "$old_md5 != $new_md5"
17701
17702         # Skip free space checks with ZFS
17703         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17704                 local mdtfree2=$(do_facet $facet \
17705                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17706                 [ $mdtfree2 -gt $mdtfree1 ] ||
17707                         error "MDT space is not freed after migration"
17708         fi
17709         return 0
17710 }
17711 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17712
17713 test_272c() {
17714         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17715                 skip "Need MDS version at least 2.11.50"
17716
17717         local dom=$DIR/$tdir/$tfile
17718         mkdir -p $DIR/$tdir
17719         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17720
17721         local mdtidx=$($LFS getstripe -m $dom)
17722         local mdtname=MDT$(printf %04x $mdtidx)
17723         local facet=mds$((mdtidx + 1))
17724
17725         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17726                 error "failed to write data into $dom"
17727         local old_md5=$(md5sum $dom)
17728         cancel_lru_locks mdc
17729         local mdtfree1=$(do_facet $facet \
17730                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17731
17732         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17733                 error "failed to migrate to the new composite layout"
17734         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17735                 error "MDT stripe was not removed"
17736
17737         cancel_lru_locks mdc
17738         local new_md5=$(md5sum $dom)
17739         [ "$old_md5" != "$new_md5" ] &&
17740                 error "$old_md5 != $new_md5"
17741
17742         # Skip free space checks with ZFS
17743         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17744                 local mdtfree2=$(do_facet $facet \
17745                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17746                 [ $mdtfree2 -gt $mdtfree1 ] ||
17747                         error "MDS space is not freed after migration"
17748         fi
17749         return 0
17750 }
17751 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17752
17753 test_273a() {
17754         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17755                 skip "Need MDS version at least 2.11.50"
17756
17757         # Layout swap cannot be done if either file has DOM component,
17758         # this will never be supported, migration should be used instead
17759
17760         local dom=$DIR/$tdir/$tfile
17761         mkdir -p $DIR/$tdir
17762
17763         $LFS setstripe -c2 ${dom}_plain
17764         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17765         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17766                 error "can swap layout with DoM component"
17767         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17768                 error "can swap layout with DoM component"
17769
17770         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17771         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17772                 error "can swap layout with DoM component"
17773         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17774                 error "can swap layout with DoM component"
17775         return 0
17776 }
17777 run_test 273a "DoM: layout swapping should fail with DOM"
17778
17779 test_275() {
17780         remote_ost_nodsh && skip "remote OST with nodsh"
17781         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17782                 skip "Need OST version >= 2.10.57"
17783
17784         local file=$DIR/$tfile
17785         local oss
17786
17787         oss=$(comma_list $(osts_nodes))
17788
17789         dd if=/dev/urandom of=$file bs=1M count=2 ||
17790                 error "failed to create a file"
17791         cancel_lru_locks osc
17792
17793         #lock 1
17794         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17795                 error "failed to read a file"
17796
17797 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17798         $LCTL set_param fail_loc=0x8000031f
17799
17800         cancel_lru_locks osc &
17801         sleep 1
17802
17803 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17804         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17805         #IO takes another lock, but matches the PENDING one
17806         #and places it to the IO RPC
17807         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17808                 error "failed to read a file with PENDING lock"
17809 }
17810 run_test 275 "Read on a canceled duplicate lock"
17811
17812 test_276() {
17813         remote_ost_nodsh && skip "remote OST with nodsh"
17814         local pid
17815
17816         do_facet ost1 "(while true; do \
17817                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17818                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17819         pid=$!
17820
17821         for LOOP in $(seq 20); do
17822                 stop ost1
17823                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17824         done
17825         kill -9 $pid
17826         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17827                 rm $TMP/sanity_276_pid"
17828 }
17829 run_test 276 "Race between mount and obd_statfs"
17830
17831 cleanup_test_300() {
17832         trap 0
17833         umask $SAVE_UMASK
17834 }
17835 test_striped_dir() {
17836         local mdt_index=$1
17837         local stripe_count
17838         local stripe_index
17839
17840         mkdir -p $DIR/$tdir
17841
17842         SAVE_UMASK=$(umask)
17843         trap cleanup_test_300 RETURN EXIT
17844
17845         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17846                                                 $DIR/$tdir/striped_dir ||
17847                 error "set striped dir error"
17848
17849         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17850         [ "$mode" = "755" ] || error "expect 755 got $mode"
17851
17852         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17853                 error "getdirstripe failed"
17854         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17855         if [ "$stripe_count" != "2" ]; then
17856                 error "1:stripe_count is $stripe_count, expect 2"
17857         fi
17858         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17859         if [ "$stripe_count" != "2" ]; then
17860                 error "2:stripe_count is $stripe_count, expect 2"
17861         fi
17862
17863         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17864         if [ "$stripe_index" != "$mdt_index" ]; then
17865                 error "stripe_index is $stripe_index, expect $mdt_index"
17866         fi
17867
17868         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17869                 error "nlink error after create striped dir"
17870
17871         mkdir $DIR/$tdir/striped_dir/a
17872         mkdir $DIR/$tdir/striped_dir/b
17873
17874         stat $DIR/$tdir/striped_dir/a ||
17875                 error "create dir under striped dir failed"
17876         stat $DIR/$tdir/striped_dir/b ||
17877                 error "create dir under striped dir failed"
17878
17879         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17880                 error "nlink error after mkdir"
17881
17882         rmdir $DIR/$tdir/striped_dir/a
17883         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17884                 error "nlink error after rmdir"
17885
17886         rmdir $DIR/$tdir/striped_dir/b
17887         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17888                 error "nlink error after rmdir"
17889
17890         chattr +i $DIR/$tdir/striped_dir
17891         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17892                 error "immutable flags not working under striped dir!"
17893         chattr -i $DIR/$tdir/striped_dir
17894
17895         rmdir $DIR/$tdir/striped_dir ||
17896                 error "rmdir striped dir error"
17897
17898         cleanup_test_300
17899
17900         true
17901 }
17902
17903 test_300a() {
17904         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17905                 skip "skipped for lustre < 2.7.0"
17906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17908
17909         test_striped_dir 0 || error "failed on striped dir on MDT0"
17910         test_striped_dir 1 || error "failed on striped dir on MDT0"
17911 }
17912 run_test 300a "basic striped dir sanity test"
17913
17914 test_300b() {
17915         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17916                 skip "skipped for lustre < 2.7.0"
17917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17919
17920         local i
17921         local mtime1
17922         local mtime2
17923         local mtime3
17924
17925         test_mkdir $DIR/$tdir || error "mkdir fail"
17926         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17927                 error "set striped dir error"
17928         for i in {0..9}; do
17929                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17930                 sleep 1
17931                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17932                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17933                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17934                 sleep 1
17935                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17936                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17937                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17938         done
17939         true
17940 }
17941 run_test 300b "check ctime/mtime for striped dir"
17942
17943 test_300c() {
17944         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17945                 skip "skipped for lustre < 2.7.0"
17946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17947         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17948
17949         local file_count
17950
17951         mkdir -p $DIR/$tdir
17952         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17953                 error "set striped dir error"
17954
17955         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17956                 error "chown striped dir failed"
17957
17958         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17959                 error "create 5k files failed"
17960
17961         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17962
17963         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17964
17965         rm -rf $DIR/$tdir
17966 }
17967 run_test 300c "chown && check ls under striped directory"
17968
17969 test_300d() {
17970         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17971                 skip "skipped for lustre < 2.7.0"
17972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17974
17975         local stripe_count
17976         local file
17977
17978         mkdir -p $DIR/$tdir
17979         $LFS setstripe -c 2 $DIR/$tdir
17980
17981         #local striped directory
17982         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17983                 error "set striped dir error"
17984         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17985                 error "create 10 files failed"
17986
17987         #remote striped directory
17988         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17989                 error "set striped dir error"
17990         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17991                 error "create 10 files failed"
17992
17993         for file in $(find $DIR/$tdir); do
17994                 stripe_count=$($LFS getstripe -c $file)
17995                 [ $stripe_count -eq 2 ] ||
17996                         error "wrong stripe $stripe_count for $file"
17997         done
17998
17999         rm -rf $DIR/$tdir
18000 }
18001 run_test 300d "check default stripe under striped directory"
18002
18003 test_300e() {
18004         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18005                 skip "Need MDS version at least 2.7.55"
18006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18008
18009         local stripe_count
18010         local file
18011
18012         mkdir -p $DIR/$tdir
18013
18014         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18015                 error "set striped dir error"
18016
18017         touch $DIR/$tdir/striped_dir/a
18018         touch $DIR/$tdir/striped_dir/b
18019         touch $DIR/$tdir/striped_dir/c
18020
18021         mkdir $DIR/$tdir/striped_dir/dir_a
18022         mkdir $DIR/$tdir/striped_dir/dir_b
18023         mkdir $DIR/$tdir/striped_dir/dir_c
18024
18025         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18026                 error "set striped adir under striped dir error"
18027
18028         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18029                 error "set striped bdir under striped dir error"
18030
18031         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18032                 error "set striped cdir under striped dir error"
18033
18034         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18035                 error "rename dir under striped dir fails"
18036
18037         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18038                 error "rename dir under different stripes fails"
18039
18040         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18041                 error "rename file under striped dir should succeed"
18042
18043         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18044                 error "rename dir under striped dir should succeed"
18045
18046         rm -rf $DIR/$tdir
18047 }
18048 run_test 300e "check rename under striped directory"
18049
18050 test_300f() {
18051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18052         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18053         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18054                 skip "Need MDS version at least 2.7.55"
18055
18056         local stripe_count
18057         local file
18058
18059         rm -rf $DIR/$tdir
18060         mkdir -p $DIR/$tdir
18061
18062         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18063                 error "set striped dir error"
18064
18065         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18066                 error "set striped dir error"
18067
18068         touch $DIR/$tdir/striped_dir/a
18069         mkdir $DIR/$tdir/striped_dir/dir_a
18070         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18071                 error "create striped dir under striped dir fails"
18072
18073         touch $DIR/$tdir/striped_dir1/b
18074         mkdir $DIR/$tdir/striped_dir1/dir_b
18075         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18076                 error "create striped dir under striped dir fails"
18077
18078         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18079                 error "rename dir under different striped dir should fail"
18080
18081         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18082                 error "rename striped dir under diff striped dir should fail"
18083
18084         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18085                 error "rename file under diff striped dirs fails"
18086
18087         rm -rf $DIR/$tdir
18088 }
18089 run_test 300f "check rename cross striped directory"
18090
18091 test_300_check_default_striped_dir()
18092 {
18093         local dirname=$1
18094         local default_count=$2
18095         local default_index=$3
18096         local stripe_count
18097         local stripe_index
18098         local dir_stripe_index
18099         local dir
18100
18101         echo "checking $dirname $default_count $default_index"
18102         $LFS setdirstripe -D -c $default_count -i $default_index \
18103                                 -t all_char $DIR/$tdir/$dirname ||
18104                 error "set default stripe on striped dir error"
18105         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18106         [ $stripe_count -eq $default_count ] ||
18107                 error "expect $default_count get $stripe_count for $dirname"
18108
18109         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18110         [ $stripe_index -eq $default_index ] ||
18111                 error "expect $default_index get $stripe_index for $dirname"
18112
18113         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18114                                                 error "create dirs failed"
18115
18116         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18117         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18118         for dir in $(find $DIR/$tdir/$dirname/*); do
18119                 stripe_count=$($LFS getdirstripe -c $dir)
18120                 [ $stripe_count -eq $default_count ] ||
18121                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18122                 error "stripe count $default_count != $stripe_count for $dir"
18123
18124                 stripe_index=$($LFS getdirstripe -i $dir)
18125                 [ $default_index -eq -1 ] ||
18126                         [ $stripe_index -eq $default_index ] ||
18127                         error "$stripe_index != $default_index for $dir"
18128
18129                 #check default stripe
18130                 stripe_count=$($LFS getdirstripe -D -c $dir)
18131                 [ $stripe_count -eq $default_count ] ||
18132                 error "default count $default_count != $stripe_count for $dir"
18133
18134                 stripe_index=$($LFS getdirstripe -D -i $dir)
18135                 [ $stripe_index -eq $default_index ] ||
18136                 error "default index $default_index != $stripe_index for $dir"
18137         done
18138         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18139 }
18140
18141 test_300g() {
18142         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18143         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18144                 skip "Need MDS version at least 2.7.55"
18145
18146         local dir
18147         local stripe_count
18148         local stripe_index
18149
18150         mkdir $DIR/$tdir
18151         mkdir $DIR/$tdir/normal_dir
18152
18153         #Checking when client cache stripe index
18154         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18155         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18156                 error "create striped_dir failed"
18157
18158         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18159                 error "create dir0 fails"
18160         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18161         [ $stripe_index -eq 0 ] ||
18162                 error "dir0 expect index 0 got $stripe_index"
18163
18164         mkdir $DIR/$tdir/striped_dir/dir1 ||
18165                 error "create dir1 fails"
18166         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18167         [ $stripe_index -eq 1 ] ||
18168                 error "dir1 expect index 1 got $stripe_index"
18169
18170         #check default stripe count/stripe index
18171         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18172         test_300_check_default_striped_dir normal_dir 1 0
18173         test_300_check_default_striped_dir normal_dir 2 1
18174         test_300_check_default_striped_dir normal_dir 2 -1
18175
18176         #delete default stripe information
18177         echo "delete default stripeEA"
18178         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18179                 error "set default stripe on striped dir error"
18180
18181         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18182         for dir in $(find $DIR/$tdir/normal_dir/*); do
18183                 stripe_count=$($LFS getdirstripe -c $dir)
18184                 [ $stripe_count -eq 0 ] ||
18185                         error "expect 1 get $stripe_count for $dir"
18186                 stripe_index=$($LFS getdirstripe -i $dir)
18187                 [ $stripe_index -eq 0 ] ||
18188                         error "expect 0 get $stripe_index for $dir"
18189         done
18190 }
18191 run_test 300g "check default striped directory for normal directory"
18192
18193 test_300h() {
18194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18196                 skip "Need MDS version at least 2.7.55"
18197
18198         local dir
18199         local stripe_count
18200
18201         mkdir $DIR/$tdir
18202         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18203                 error "set striped dir error"
18204
18205         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18206         test_300_check_default_striped_dir striped_dir 1 0
18207         test_300_check_default_striped_dir striped_dir 2 1
18208         test_300_check_default_striped_dir striped_dir 2 -1
18209
18210         #delete default stripe information
18211         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18212                 error "set default stripe on striped dir error"
18213
18214         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18215         for dir in $(find $DIR/$tdir/striped_dir/*); do
18216                 stripe_count=$($LFS getdirstripe -c $dir)
18217                 [ $stripe_count -eq 0 ] ||
18218                         error "expect 1 get $stripe_count for $dir"
18219         done
18220 }
18221 run_test 300h "check default striped directory for striped directory"
18222
18223 test_300i() {
18224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18226         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18227                 skip "Need MDS version at least 2.7.55"
18228
18229         local stripe_count
18230         local file
18231
18232         mkdir $DIR/$tdir
18233
18234         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18235                 error "set striped dir error"
18236
18237         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18238                 error "create files under striped dir failed"
18239
18240         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18241                 error "set striped hashdir error"
18242
18243         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18244                 error "create dir0 under hash dir failed"
18245         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18246                 error "create dir1 under hash dir failed"
18247
18248         # unfortunately, we need to umount to clear dir layout cache for now
18249         # once we fully implement dir layout, we can drop this
18250         umount_client $MOUNT || error "umount failed"
18251         mount_client $MOUNT || error "mount failed"
18252
18253         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18254         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18255         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18256
18257         #set the stripe to be unknown hash type
18258         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18259         $LCTL set_param fail_loc=0x1901
18260         for ((i = 0; i < 10; i++)); do
18261                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18262                         error "stat f-$i failed"
18263                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18264         done
18265
18266         touch $DIR/$tdir/striped_dir/f0 &&
18267                 error "create under striped dir with unknown hash should fail"
18268
18269         $LCTL set_param fail_loc=0
18270
18271         umount_client $MOUNT || error "umount failed"
18272         mount_client $MOUNT || error "mount failed"
18273
18274         return 0
18275 }
18276 run_test 300i "client handle unknown hash type striped directory"
18277
18278 test_300j() {
18279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18281         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18282                 skip "Need MDS version at least 2.7.55"
18283
18284         local stripe_count
18285         local file
18286
18287         mkdir $DIR/$tdir
18288
18289         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18290         $LCTL set_param fail_loc=0x1702
18291         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18292                 error "set striped dir error"
18293
18294         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18295                 error "create files under striped dir failed"
18296
18297         $LCTL set_param fail_loc=0
18298
18299         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18300
18301         return 0
18302 }
18303 run_test 300j "test large update record"
18304
18305 test_300k() {
18306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18308         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18309                 skip "Need MDS version at least 2.7.55"
18310
18311         # this test needs a huge transaction
18312         local kb
18313         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18314         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18315
18316         local stripe_count
18317         local file
18318
18319         mkdir $DIR/$tdir
18320
18321         #define OBD_FAIL_LARGE_STRIPE   0x1703
18322         $LCTL set_param fail_loc=0x1703
18323         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18324                 error "set striped dir error"
18325         $LCTL set_param fail_loc=0
18326
18327         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18328                 error "getstripeddir fails"
18329         rm -rf $DIR/$tdir/striped_dir ||
18330                 error "unlink striped dir fails"
18331
18332         return 0
18333 }
18334 run_test 300k "test large striped directory"
18335
18336 test_300l() {
18337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18339         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18340                 skip "Need MDS version at least 2.7.55"
18341
18342         local stripe_index
18343
18344         test_mkdir -p $DIR/$tdir/striped_dir
18345         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18346                         error "chown $RUNAS_ID failed"
18347         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18348                 error "set default striped dir failed"
18349
18350         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18351         $LCTL set_param fail_loc=0x80000158
18352         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18353
18354         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18355         [ $stripe_index -eq 1 ] ||
18356                 error "expect 1 get $stripe_index for $dir"
18357 }
18358 run_test 300l "non-root user to create dir under striped dir with stale layout"
18359
18360 test_300m() {
18361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18362         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18363         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18364                 skip "Need MDS version at least 2.7.55"
18365
18366         mkdir -p $DIR/$tdir/striped_dir
18367         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18368                 error "set default stripes dir error"
18369
18370         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18371
18372         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18373         [ $stripe_count -eq 0 ] ||
18374                         error "expect 0 get $stripe_count for a"
18375
18376         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18377                 error "set default stripes dir error"
18378
18379         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18380
18381         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18382         [ $stripe_count -eq 0 ] ||
18383                         error "expect 0 get $stripe_count for b"
18384
18385         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18386                 error "set default stripes dir error"
18387
18388         mkdir $DIR/$tdir/striped_dir/c &&
18389                 error "default stripe_index is invalid, mkdir c should fails"
18390
18391         rm -rf $DIR/$tdir || error "rmdir fails"
18392 }
18393 run_test 300m "setstriped directory on single MDT FS"
18394
18395 cleanup_300n() {
18396         local list=$(comma_list $(mdts_nodes))
18397
18398         trap 0
18399         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18400 }
18401
18402 test_300n() {
18403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18404         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18405         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18406                 skip "Need MDS version at least 2.7.55"
18407         remote_mds_nodsh && skip "remote MDS with nodsh"
18408
18409         local stripe_index
18410         local list=$(comma_list $(mdts_nodes))
18411
18412         trap cleanup_300n RETURN EXIT
18413         mkdir -p $DIR/$tdir
18414         chmod 777 $DIR/$tdir
18415         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18416                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18417                 error "create striped dir succeeds with gid=0"
18418
18419         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18420         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18421                 error "create striped dir fails with gid=-1"
18422
18423         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18424         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18425                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18426                 error "set default striped dir succeeds with gid=0"
18427
18428
18429         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18430         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18431                 error "set default striped dir fails with gid=-1"
18432
18433
18434         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18435         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18436                                         error "create test_dir fails"
18437         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18438                                         error "create test_dir1 fails"
18439         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18440                                         error "create test_dir2 fails"
18441         cleanup_300n
18442 }
18443 run_test 300n "non-root user to create dir under striped dir with default EA"
18444
18445 test_300o() {
18446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18448         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18449                 skip "Need MDS version at least 2.7.55"
18450
18451         local numfree1
18452         local numfree2
18453
18454         mkdir -p $DIR/$tdir
18455
18456         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18457         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18458         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18459                 skip "not enough free inodes $numfree1 $numfree2"
18460         fi
18461
18462         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18463         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18464         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18465                 skip "not enough free space $numfree1 $numfree2"
18466         fi
18467
18468         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18469                 error "setdirstripe fails"
18470
18471         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18472                 error "create dirs fails"
18473
18474         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18475         ls $DIR/$tdir/striped_dir > /dev/null ||
18476                 error "ls striped dir fails"
18477         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18478                 error "unlink big striped dir fails"
18479 }
18480 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18481
18482 test_300p() {
18483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18484         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18485         remote_mds_nodsh && skip "remote MDS with nodsh"
18486
18487         mkdir -p $DIR/$tdir
18488
18489         #define OBD_FAIL_OUT_ENOSPC     0x1704
18490         do_facet mds2 lctl set_param fail_loc=0x80001704
18491         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18492                  && error "create striped directory should fail"
18493
18494         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18495
18496         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18497         true
18498 }
18499 run_test 300p "create striped directory without space"
18500
18501 test_300q() {
18502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18504
18505         local fd=$(free_fd)
18506         local cmd="exec $fd<$tdir"
18507         cd $DIR
18508         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18509         eval $cmd
18510         cmd="exec $fd<&-"
18511         trap "eval $cmd" EXIT
18512         cd $tdir || error "cd $tdir fails"
18513         rmdir  ../$tdir || error "rmdir $tdir fails"
18514         mkdir local_dir && error "create dir succeeds"
18515         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18516         eval $cmd
18517         return 0
18518 }
18519 run_test 300q "create remote directory under orphan directory"
18520
18521 test_300r() {
18522         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18523                 skip "Need MDS version at least 2.7.55" && return
18524         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18525
18526         mkdir $DIR/$tdir
18527
18528         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18529                 error "set striped dir error"
18530
18531         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18532                 error "getstripeddir fails"
18533
18534         local stripe_count
18535         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18536                       awk '/lmv_stripe_count:/ { print $2 }')
18537
18538         [ $MDSCOUNT -ne $stripe_count ] &&
18539                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18540
18541         rm -rf $DIR/$tdir/striped_dir ||
18542                 error "unlink striped dir fails"
18543 }
18544 run_test 300r "test -1 striped directory"
18545
18546 prepare_remote_file() {
18547         mkdir $DIR/$tdir/src_dir ||
18548                 error "create remote source failed"
18549
18550         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18551                  error "cp to remote source failed"
18552         touch $DIR/$tdir/src_dir/a
18553
18554         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18555                 error "create remote target dir failed"
18556
18557         touch $DIR/$tdir/tgt_dir/b
18558
18559         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18560                 error "rename dir cross MDT failed!"
18561
18562         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18563                 error "src_child still exists after rename"
18564
18565         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18566                 error "missing file(a) after rename"
18567
18568         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18569                 error "diff after rename"
18570 }
18571
18572 test_310a() {
18573         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18575
18576         local remote_file=$DIR/$tdir/tgt_dir/b
18577
18578         mkdir -p $DIR/$tdir
18579
18580         prepare_remote_file || error "prepare remote file failed"
18581
18582         #open-unlink file
18583         $OPENUNLINK $remote_file $remote_file ||
18584                 error "openunlink $remote_file failed"
18585         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18586 }
18587 run_test 310a "open unlink remote file"
18588
18589 test_310b() {
18590         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18592
18593         local remote_file=$DIR/$tdir/tgt_dir/b
18594
18595         mkdir -p $DIR/$tdir
18596
18597         prepare_remote_file || error "prepare remote file failed"
18598
18599         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18600         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18601         $CHECKSTAT -t file $remote_file || error "check file failed"
18602 }
18603 run_test 310b "unlink remote file with multiple links while open"
18604
18605 test_310c() {
18606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18607         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18608
18609         local remote_file=$DIR/$tdir/tgt_dir/b
18610
18611         mkdir -p $DIR/$tdir
18612
18613         prepare_remote_file || error "prepare remote file failed"
18614
18615         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18616         multiop_bg_pause $remote_file O_uc ||
18617                         error "mulitop failed for remote file"
18618         MULTIPID=$!
18619         $MULTIOP $DIR/$tfile Ouc
18620         kill -USR1 $MULTIPID
18621         wait $MULTIPID
18622 }
18623 run_test 310c "open-unlink remote file with multiple links"
18624
18625 #LU-4825
18626 test_311() {
18627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18628         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18629         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18630                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18631         remote_mds_nodsh && skip "remote MDS with nodsh"
18632
18633         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18634         local mdts=$(comma_list $(mdts_nodes))
18635
18636         mkdir -p $DIR/$tdir
18637         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18638         createmany -o $DIR/$tdir/$tfile. 1000
18639
18640         # statfs data is not real time, let's just calculate it
18641         old_iused=$((old_iused + 1000))
18642
18643         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18644                         osp.*OST0000*MDT0000.create_count")
18645         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18646                                 osp.*OST0000*MDT0000.max_create_count")
18647         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18648
18649         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18650         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18651         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18652
18653         unlinkmany $DIR/$tdir/$tfile. 1000
18654
18655         do_nodes $mdts "$LCTL set_param -n \
18656                         osp.*OST0000*.max_create_count=$max_count"
18657         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18658                 do_nodes $mdts "$LCTL set_param -n \
18659                                 osp.*OST0000*.create_count=$count"
18660         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18661                         grep "=0" && error "create_count is zero"
18662
18663         local new_iused
18664         for i in $(seq 120); do
18665                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18666                 # system may be too busy to destroy all objs in time, use
18667                 # a somewhat small value to not fail autotest
18668                 [ $((old_iused - new_iused)) -gt 400 ] && break
18669                 sleep 1
18670         done
18671
18672         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18673         [ $((old_iused - new_iused)) -gt 400 ] ||
18674                 error "objs not destroyed after unlink"
18675 }
18676 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18677
18678 zfs_oid_to_objid()
18679 {
18680         local ost=$1
18681         local objid=$2
18682
18683         local vdevdir=$(dirname $(facet_vdevice $ost))
18684         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18685         local zfs_zapid=$(do_facet $ost $cmd |
18686                           grep -w "/O/0/d$((objid%32))" -C 5 |
18687                           awk '/Object/{getline; print $1}')
18688         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18689                           awk "/$objid = /"'{printf $3}')
18690
18691         echo $zfs_objid
18692 }
18693
18694 zfs_object_blksz() {
18695         local ost=$1
18696         local objid=$2
18697
18698         local vdevdir=$(dirname $(facet_vdevice $ost))
18699         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18700         local blksz=$(do_facet $ost $cmd $objid |
18701                       awk '/dblk/{getline; printf $4}')
18702
18703         case "${blksz: -1}" in
18704                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18705                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18706                 *) ;;
18707         esac
18708
18709         echo $blksz
18710 }
18711
18712 test_312() { # LU-4856
18713         remote_ost_nodsh && skip "remote OST with nodsh"
18714         [ "$ost1_FSTYPE" = "zfs" ] ||
18715                 skip_env "the test only applies to zfs"
18716
18717         local max_blksz=$(do_facet ost1 \
18718                           $ZFS get -p recordsize $(facet_device ost1) |
18719                           awk '!/VALUE/{print $3}')
18720
18721         # to make life a little bit easier
18722         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18723         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18724
18725         local tf=$DIR/$tdir/$tfile
18726         touch $tf
18727         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18728
18729         # Get ZFS object id
18730         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18731         # block size change by sequential overwrite
18732         local bs
18733
18734         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18735                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18736
18737                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18738                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18739         done
18740         rm -f $tf
18741
18742         # block size change by sequential append write
18743         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18744         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18745         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18746         local count
18747
18748         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18749                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18750                         oflag=sync conv=notrunc
18751
18752                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18753                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18754                         error "blksz error, actual $blksz, " \
18755                                 "expected: 2 * $count * $PAGE_SIZE"
18756         done
18757         rm -f $tf
18758
18759         # random write
18760         touch $tf
18761         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18762         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18763
18764         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18765         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18766         [ $blksz -eq $PAGE_SIZE ] ||
18767                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18768
18769         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18770         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18771         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18772
18773         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18774         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18775         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18776 }
18777 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18778
18779 test_313() {
18780         remote_ost_nodsh && skip "remote OST with nodsh"
18781
18782         local file=$DIR/$tfile
18783
18784         rm -f $file
18785         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18786
18787         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18788         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18789         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18790                 error "write should failed"
18791         do_facet ost1 "$LCTL set_param fail_loc=0"
18792         rm -f $file
18793 }
18794 run_test 313 "io should fail after last_rcvd update fail"
18795
18796 test_314() {
18797         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18798
18799         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18800         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18801         rm -f $DIR/$tfile
18802         wait_delete_completed
18803         do_facet ost1 "$LCTL set_param fail_loc=0"
18804 }
18805 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18806
18807 test_315() { # LU-618
18808         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18809
18810         local file=$DIR/$tfile
18811         rm -f $file
18812
18813         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18814                 error "multiop file write failed"
18815         $MULTIOP $file oO_RDONLY:r4063232_c &
18816         PID=$!
18817
18818         sleep 2
18819
18820         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18821         kill -USR1 $PID
18822
18823         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18824         rm -f $file
18825 }
18826 run_test 315 "read should be accounted"
18827
18828 test_316() {
18829         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18830         large_xattr_enabled || skip_env "ea_inode feature disabled"
18831
18832         rm -rf $DIR/$tdir/d
18833         mkdir -p $DIR/$tdir/d
18834         chown nobody $DIR/$tdir/d
18835         touch $DIR/$tdir/d/file
18836
18837         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18838 }
18839 run_test 316 "lfs mv"
18840
18841 test_317() {
18842         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18843                 skip "Need MDS version at least 2.11.53"
18844         local trunc_sz
18845         local grant_blk_size
18846
18847         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18848                 skip "LU-10370: no implementation for ZFS" && return
18849         fi
18850
18851         stack_trap "rm -f $DIR/$tfile" EXIT
18852         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18853                         awk '/grant_block_size:/ { print $2; exit; }')
18854         #
18855         # Create File of size 5M. Truncate it to below size's and verify
18856         # blocks count.
18857         #
18858         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18859                 error "Create file : $DIR/$tfile"
18860
18861         for trunc_sz in 2097152 4097 4000 509 0; do
18862                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18863                         error "truncate $tfile to $trunc_sz failed"
18864                 local sz=$(stat --format=%s $DIR/$tfile)
18865                 local blk=$(stat --format=%b $DIR/$tfile)
18866                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18867                                      grant_blk_size) * 8))
18868
18869                 if [[ $blk -ne $trunc_blk ]]; then
18870                         $(which stat) $DIR/$tfile
18871                         error "Expected Block $trunc_blk got $blk for $tfile"
18872                 fi
18873
18874                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18875                         error "Expected Size $trunc_sz got $sz for $tfile"
18876         done
18877
18878         #
18879         # sparse file test
18880         # Create file with a hole and write actual two blocks. Block count
18881         # must be 16.
18882         #
18883         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18884                 conv=fsync || error "Create file : $DIR/$tfile"
18885
18886         # Calculate the final truncate size.
18887         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18888
18889         #
18890         # truncate to size $trunc_sz bytes. Strip the last block
18891         # The block count must drop to 8
18892         #
18893         $TRUNCATE $DIR/$tfile $trunc_sz ||
18894                 error "truncate $tfile to $trunc_sz failed"
18895
18896         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18897         sz=$(stat --format=%s $DIR/$tfile)
18898         blk=$(stat --format=%b $DIR/$tfile)
18899
18900         if [[ $blk -ne $trunc_bsz ]]; then
18901                 $(which stat) $DIR/$tfile
18902                 error "Expected Block $trunc_bsz got $blk for $tfile"
18903         fi
18904
18905         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18906                 error "Expected Size $trunc_sz got $sz for $tfile"
18907 }
18908 run_test 317 "Verify blocks get correctly update after truncate"
18909
18910 test_319() {
18911         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18912
18913         local before=$(date +%s)
18914         local evict
18915         local mdir=$DIR/$tdir
18916         local file=$mdir/xxx
18917
18918         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18919         touch $file
18920
18921 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18922         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18923         $LFS mv -m1 $file &
18924
18925         sleep 1
18926         dd if=$file of=/dev/null
18927         wait
18928         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18929           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18930
18931         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18932 }
18933 run_test 319 "lost lease lock on migrate error"
18934
18935 test_fake_rw() {
18936         local read_write=$1
18937         if [ "$read_write" = "write" ]; then
18938                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18939         elif [ "$read_write" = "read" ]; then
18940                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18941         else
18942                 error "argument error"
18943         fi
18944
18945         # turn off debug for performance testing
18946         local saved_debug=$($LCTL get_param -n debug)
18947         $LCTL set_param debug=0
18948
18949         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18950
18951         # get ost1 size - lustre-OST0000
18952         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18953         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18954         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18955
18956         if [ "$read_write" = "read" ]; then
18957                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18958         fi
18959
18960         local start_time=$(date +%s.%N)
18961         $dd_cmd bs=1M count=$blocks oflag=sync ||
18962                 error "real dd $read_write error"
18963         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18964
18965         if [ "$read_write" = "write" ]; then
18966                 rm -f $DIR/$tfile
18967         fi
18968
18969         # define OBD_FAIL_OST_FAKE_RW           0x238
18970         do_facet ost1 $LCTL set_param fail_loc=0x238
18971
18972         local start_time=$(date +%s.%N)
18973         $dd_cmd bs=1M count=$blocks oflag=sync ||
18974                 error "fake dd $read_write error"
18975         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18976
18977         if [ "$read_write" = "write" ]; then
18978                 # verify file size
18979                 cancel_lru_locks osc
18980                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18981                         error "$tfile size not $blocks MB"
18982         fi
18983         do_facet ost1 $LCTL set_param fail_loc=0
18984
18985         echo "fake $read_write $duration_fake vs. normal $read_write" \
18986                 "$duration in seconds"
18987         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18988                 error_not_in_vm "fake write is slower"
18989
18990         $LCTL set_param -n debug="$saved_debug"
18991         rm -f $DIR/$tfile
18992 }
18993 test_399a() { # LU-7655 for OST fake write
18994         remote_ost_nodsh && skip "remote OST with nodsh"
18995
18996         test_fake_rw write
18997 }
18998 run_test 399a "fake write should not be slower than normal write"
18999
19000 test_399b() { # LU-8726 for OST fake read
19001         remote_ost_nodsh && skip "remote OST with nodsh"
19002         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19003                 skip_env "ldiskfs only test"
19004         fi
19005
19006         test_fake_rw read
19007 }
19008 run_test 399b "fake read should not be slower than normal read"
19009
19010 test_400a() { # LU-1606, was conf-sanity test_74
19011         if ! which $CC > /dev/null 2>&1; then
19012                 skip_env "$CC is not installed"
19013         fi
19014
19015         local extra_flags=''
19016         local out=$TMP/$tfile
19017         local prefix=/usr/include/lustre
19018         local prog
19019
19020         if ! [[ -d $prefix ]]; then
19021                 # Assume we're running in tree and fixup the include path.
19022                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19023                 extra_flags+=" -L$LUSTRE/utils/.lib"
19024         fi
19025
19026         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19027                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19028                         error "client api broken"
19029         done
19030         rm -f $out
19031 }
19032 run_test 400a "Lustre client api program can compile and link"
19033
19034 test_400b() { # LU-1606, LU-5011
19035         local header
19036         local out=$TMP/$tfile
19037         local prefix=/usr/include/linux/lustre
19038
19039         # We use a hard coded prefix so that this test will not fail
19040         # when run in tree. There are headers in lustre/include/lustre/
19041         # that are not packaged (like lustre_idl.h) and have more
19042         # complicated include dependencies (like config.h and lnet/types.h).
19043         # Since this test about correct packaging we just skip them when
19044         # they don't exist (see below) rather than try to fixup cppflags.
19045
19046         if ! which $CC > /dev/null 2>&1; then
19047                 skip_env "$CC is not installed"
19048         fi
19049
19050         for header in $prefix/*.h; do
19051                 if ! [[ -f "$header" ]]; then
19052                         continue
19053                 fi
19054
19055                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19056                         continue # lustre_ioctl.h is internal header
19057                 fi
19058
19059                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19060                         error "cannot compile '$header'"
19061         done
19062         rm -f $out
19063 }
19064 run_test 400b "packaged headers can be compiled"
19065
19066 test_401a() { #LU-7437
19067         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19068         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19069
19070         #count the number of parameters by "list_param -R"
19071         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19072         #count the number of parameters by listing proc files
19073         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19074         echo "proc_dirs='$proc_dirs'"
19075         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19076         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19077                       sort -u | wc -l)
19078
19079         [ $params -eq $procs ] ||
19080                 error "found $params parameters vs. $procs proc files"
19081
19082         # test the list_param -D option only returns directories
19083         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19084         #count the number of parameters by listing proc directories
19085         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19086                 sort -u | wc -l)
19087
19088         [ $params -eq $procs ] ||
19089                 error "found $params parameters vs. $procs proc files"
19090 }
19091 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19092
19093 test_401b() {
19094         local save=$($LCTL get_param -n jobid_var)
19095         local tmp=testing
19096
19097         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19098                 error "no error returned when setting bad parameters"
19099
19100         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19101         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19102
19103         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19104         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19105         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19106 }
19107 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19108
19109 test_401c() {
19110         local jobid_var_old=$($LCTL get_param -n jobid_var)
19111         local jobid_var_new
19112
19113         $LCTL set_param jobid_var= &&
19114                 error "no error returned for 'set_param a='"
19115
19116         jobid_var_new=$($LCTL get_param -n jobid_var)
19117         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19118                 error "jobid_var was changed by setting without value"
19119
19120         $LCTL set_param jobid_var &&
19121                 error "no error returned for 'set_param a'"
19122
19123         jobid_var_new=$($LCTL get_param -n jobid_var)
19124         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19125                 error "jobid_var was changed by setting without value"
19126 }
19127 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19128
19129 test_401d() {
19130         local jobid_var_old=$($LCTL get_param -n jobid_var)
19131         local jobid_var_new
19132         local new_value="foo=bar"
19133
19134         $LCTL set_param jobid_var=$new_value ||
19135                 error "'set_param a=b' did not accept a value containing '='"
19136
19137         jobid_var_new=$($LCTL get_param -n jobid_var)
19138         [[ "$jobid_var_new" == "$new_value" ]] ||
19139                 error "'set_param a=b' failed on a value containing '='"
19140
19141         # Reset the jobid_var to test the other format
19142         $LCTL set_param jobid_var=$jobid_var_old
19143         jobid_var_new=$($LCTL get_param -n jobid_var)
19144         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19145                 error "failed to reset jobid_var"
19146
19147         $LCTL set_param jobid_var $new_value ||
19148                 error "'set_param a b' did not accept a value containing '='"
19149
19150         jobid_var_new=$($LCTL get_param -n jobid_var)
19151         [[ "$jobid_var_new" == "$new_value" ]] ||
19152                 error "'set_param a b' failed on a value containing '='"
19153
19154         $LCTL set_param jobid_var $jobid_var_old
19155         jobid_var_new=$($LCTL get_param -n jobid_var)
19156         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19157                 error "failed to reset jobid_var"
19158 }
19159 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19160
19161 test_402() {
19162         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19163         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19164                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19165         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19166                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19167                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19168         remote_mds_nodsh && skip "remote MDS with nodsh"
19169
19170         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19171 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19172         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19173         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19174                 echo "Touch failed - OK"
19175 }
19176 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19177
19178 test_403() {
19179         local file1=$DIR/$tfile.1
19180         local file2=$DIR/$tfile.2
19181         local tfile=$TMP/$tfile
19182
19183         rm -f $file1 $file2 $tfile
19184
19185         touch $file1
19186         ln $file1 $file2
19187
19188         # 30 sec OBD_TIMEOUT in ll_getattr()
19189         # right before populating st_nlink
19190         $LCTL set_param fail_loc=0x80001409
19191         stat -c %h $file1 > $tfile &
19192
19193         # create an alias, drop all locks and reclaim the dentry
19194         < $file2
19195         cancel_lru_locks mdc
19196         cancel_lru_locks osc
19197         sysctl -w vm.drop_caches=2
19198
19199         wait
19200
19201         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19202
19203         rm -f $tfile $file1 $file2
19204 }
19205 run_test 403 "i_nlink should not drop to zero due to aliasing"
19206
19207 test_404() { # LU-6601
19208         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19209                 skip "Need server version newer than 2.8.52"
19210         remote_mds_nodsh && skip "remote MDS with nodsh"
19211
19212         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19213                 awk '/osp .*-osc-MDT/ { print $4}')
19214
19215         local osp
19216         for osp in $mosps; do
19217                 echo "Deactivate: " $osp
19218                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19219                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19220                         awk -vp=$osp '$4 == p { print $2 }')
19221                 [ $stat = IN ] || {
19222                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19223                         error "deactivate error"
19224                 }
19225                 echo "Activate: " $osp
19226                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19227                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19228                         awk -vp=$osp '$4 == p { print $2 }')
19229                 [ $stat = UP ] || {
19230                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19231                         error "activate error"
19232                 }
19233         done
19234 }
19235 run_test 404 "validate manual {de}activated works properly for OSPs"
19236
19237 test_405() {
19238         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19239         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19240                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19241                         skip "Layout swap lock is not supported"
19242
19243         check_swap_layouts_support
19244
19245         test_mkdir $DIR/$tdir
19246         swap_lock_test -d $DIR/$tdir ||
19247                 error "One layout swap locked test failed"
19248 }
19249 run_test 405 "Various layout swap lock tests"
19250
19251 test_406() {
19252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19253         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19254         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19256         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19257                 skip "Need MDS version at least 2.8.50"
19258
19259         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19260         local test_pool=$TESTNAME
19261
19262         if ! combined_mgs_mds ; then
19263                 mount_mgs_client
19264         fi
19265         pool_add $test_pool || error "pool_add failed"
19266         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19267                 error "pool_add_targets failed"
19268
19269         save_layout_restore_at_exit $MOUNT
19270
19271         # parent set default stripe count only, child will stripe from both
19272         # parent and fs default
19273         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19274                 error "setstripe $MOUNT failed"
19275         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19276         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19277         for i in $(seq 10); do
19278                 local f=$DIR/$tdir/$tfile.$i
19279                 touch $f || error "touch failed"
19280                 local count=$($LFS getstripe -c $f)
19281                 [ $count -eq $OSTCOUNT ] ||
19282                         error "$f stripe count $count != $OSTCOUNT"
19283                 local offset=$($LFS getstripe -i $f)
19284                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19285                 local size=$($LFS getstripe -S $f)
19286                 [ $size -eq $((def_stripe_size * 2)) ] ||
19287                         error "$f stripe size $size != $((def_stripe_size * 2))"
19288                 local pool=$($LFS getstripe -p $f)
19289                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19290         done
19291
19292         # change fs default striping, delete parent default striping, now child
19293         # will stripe from new fs default striping only
19294         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19295                 error "change $MOUNT default stripe failed"
19296         $LFS setstripe -c 0 $DIR/$tdir ||
19297                 error "delete $tdir default stripe failed"
19298         for i in $(seq 11 20); do
19299                 local f=$DIR/$tdir/$tfile.$i
19300                 touch $f || error "touch $f failed"
19301                 local count=$($LFS getstripe -c $f)
19302                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19303                 local offset=$($LFS getstripe -i $f)
19304                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19305                 local size=$($LFS getstripe -S $f)
19306                 [ $size -eq $def_stripe_size ] ||
19307                         error "$f stripe size $size != $def_stripe_size"
19308                 local pool=$($LFS getstripe -p $f)
19309                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19310         done
19311
19312         unlinkmany $DIR/$tdir/$tfile. 1 20
19313
19314         local f=$DIR/$tdir/$tfile
19315         pool_remove_all_targets $test_pool $f
19316         pool_remove $test_pool $f
19317
19318         if ! combined_mgs_mds ; then
19319                 umount_mgs_client
19320         fi
19321 }
19322 run_test 406 "DNE support fs default striping"
19323
19324 test_407() {
19325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19326         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19327                 skip "Need MDS version at least 2.8.55"
19328         remote_mds_nodsh && skip "remote MDS with nodsh"
19329
19330         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19331                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19332         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19333                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19334         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19335
19336         #define OBD_FAIL_DT_TXN_STOP    0x2019
19337         for idx in $(seq $MDSCOUNT); do
19338                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19339         done
19340         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19342                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19343         true
19344 }
19345 run_test 407 "transaction fail should cause operation fail"
19346
19347 test_408() {
19348         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19349
19350         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19351         lctl set_param fail_loc=0x8000040a
19352         # let ll_prepare_partial_page() fail
19353         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19354
19355         rm -f $DIR/$tfile
19356
19357         # create at least 100 unused inodes so that
19358         # shrink_icache_memory(0) should not return 0
19359         touch $DIR/$tfile-{0..100}
19360         rm -f $DIR/$tfile-{0..100}
19361         sync
19362
19363         echo 2 > /proc/sys/vm/drop_caches
19364 }
19365 run_test 408 "drop_caches should not hang due to page leaks"
19366
19367 test_409()
19368 {
19369         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19370
19371         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19372         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19373         touch $DIR/$tdir/guard || error "(2) Fail to create"
19374
19375         local PREFIX=$(str_repeat 'A' 128)
19376         echo "Create 1K hard links start at $(date)"
19377         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19378                 error "(3) Fail to hard link"
19379
19380         echo "Links count should be right although linkEA overflow"
19381         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19382         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19383         [ $linkcount -eq 1001 ] ||
19384                 error "(5) Unexpected hard links count: $linkcount"
19385
19386         echo "List all links start at $(date)"
19387         ls -l $DIR/$tdir/foo > /dev/null ||
19388                 error "(6) Fail to list $DIR/$tdir/foo"
19389
19390         echo "Unlink hard links start at $(date)"
19391         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19392                 error "(7) Fail to unlink"
19393         echo "Unlink hard links finished at $(date)"
19394 }
19395 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19396
19397 test_410()
19398 {
19399         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19400                 skip "Need client version at least 2.9.59"
19401
19402         # Create a file, and stat it from the kernel
19403         local testfile=$DIR/$tfile
19404         touch $testfile
19405
19406         local run_id=$RANDOM
19407         local my_ino=$(stat --format "%i" $testfile)
19408
19409         # Try to insert the module. This will always fail as the
19410         # module is designed to not be inserted.
19411         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19412             &> /dev/null
19413
19414         # Anything but success is a test failure
19415         dmesg | grep -q \
19416             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19417             error "no inode match"
19418 }
19419 run_test 410 "Test inode number returned from kernel thread"
19420
19421 cleanup_test411_cgroup() {
19422         trap 0
19423         rmdir "$1"
19424 }
19425
19426 test_411() {
19427         local cg_basedir=/sys/fs/cgroup/memory
19428         # LU-9966
19429         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19430                 skip "no setup for cgroup"
19431
19432         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19433                 error "test file creation failed"
19434         cancel_lru_locks osc
19435
19436         # Create a very small memory cgroup to force a slab allocation error
19437         local cgdir=$cg_basedir/osc_slab_alloc
19438         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19439         trap "cleanup_test411_cgroup $cgdir" EXIT
19440         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19441         echo 1M > $cgdir/memory.limit_in_bytes
19442
19443         # Should not LBUG, just be killed by oom-killer
19444         # dd will return 0 even allocation failure in some environment.
19445         # So don't check return value
19446         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19447         cleanup_test411_cgroup $cgdir
19448
19449         return 0
19450 }
19451 run_test 411 "Slab allocation error with cgroup does not LBUG"
19452
19453 test_412() {
19454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19455         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19456                 skip "Need server version at least 2.10.55"
19457         fi
19458
19459         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19460                 error "mkdir failed"
19461         $LFS getdirstripe $DIR/$tdir
19462         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19463         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19464                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19465         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19466         [ $stripe_count -eq 2 ] ||
19467                 error "expect 2 get $stripe_count"
19468 }
19469 run_test 412 "mkdir on specific MDTs"
19470
19471 test_413() {
19472         [ $MDSCOUNT -lt 2 ] &&
19473                 skip "We need at least 2 MDTs for this test"
19474
19475         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19476                 skip "Need server version at least 2.10.55"
19477         fi
19478
19479         mkdir $DIR/$tdir || error "mkdir failed"
19480
19481         # find MDT that is the most full
19482         local max=$($LFS df | grep MDT |
19483                 awk 'BEGIN { a=0 }
19484                         { sub("%", "", $5)
19485                           if (0+$5 >= a)
19486                           {
19487                                 a = $5
19488                                 b = $6
19489                           }
19490                         }
19491                      END { split(b, c, ":")
19492                            sub("]", "", c[2])
19493                            print c[2]
19494                          }')
19495
19496         for i in $(seq $((MDSCOUNT - 1))); do
19497                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19498                         error "mkdir d$i failed"
19499                 $LFS getdirstripe $DIR/$tdir/d$i
19500                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19501                 [ $stripe_index -ne $max ] ||
19502                         error "don't expect $max"
19503         done
19504 }
19505 run_test 413 "mkdir on less full MDTs"
19506
19507 test_414() {
19508 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19509         $LCTL set_param fail_loc=0x80000521
19510         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19511         rm -f $DIR/$tfile
19512 }
19513 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19514
19515 test_415() {
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19518                 skip "Need server version at least 2.11.52"
19519
19520         # LU-11102
19521         local total
19522         local setattr_pid
19523         local start_time
19524         local end_time
19525         local duration
19526
19527         total=500
19528         # this test may be slow on ZFS
19529         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19530
19531         # though this test is designed for striped directory, let's test normal
19532         # directory too since lock is always saved as CoS lock.
19533         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19534         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19535
19536         (
19537                 while true; do
19538                         touch $DIR/$tdir
19539                 done
19540         ) &
19541         setattr_pid=$!
19542
19543         start_time=$(date +%s)
19544         for i in $(seq $total); do
19545                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19546                         > /dev/null
19547         done
19548         end_time=$(date +%s)
19549         duration=$((end_time - start_time))
19550
19551         kill -9 $setattr_pid
19552
19553         echo "rename $total files took $duration sec"
19554         [ $duration -lt 100 ] || error "rename took $duration sec"
19555 }
19556 run_test 415 "lock revoke is not missing"
19557
19558 test_416() {
19559         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19560                 skip "Need server version at least 2.11.55"
19561
19562         # define OBD_FAIL_OSD_TXN_START    0x19a
19563         do_facet mds1 lctl set_param fail_loc=0x19a
19564
19565         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19566
19567         true
19568 }
19569 run_test 416 "transaction start failure won't cause system hung"
19570
19571 cleanup_417() {
19572         trap 0
19573         do_nodes $(comma_list $(mdts_nodes)) \
19574                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19575         do_nodes $(comma_list $(mdts_nodes)) \
19576                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19577         do_nodes $(comma_list $(mdts_nodes)) \
19578                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19579 }
19580
19581 test_417() {
19582         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19583         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19584                 skip "Need MDS version at least 2.11.56"
19585
19586         trap cleanup_417 RETURN EXIT
19587
19588         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19589         do_nodes $(comma_list $(mdts_nodes)) \
19590                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19591         $LFS migrate -m 0 $DIR/$tdir.1 &&
19592                 error "migrate dir $tdir.1 should fail"
19593
19594         do_nodes $(comma_list $(mdts_nodes)) \
19595                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19596         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19597                 error "create remote dir $tdir.2 should fail"
19598
19599         do_nodes $(comma_list $(mdts_nodes)) \
19600                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19601         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19602                 error "create striped dir $tdir.3 should fail"
19603         true
19604 }
19605 run_test 417 "disable remote dir, striped dir and dir migration"
19606
19607 # Checks that the outputs of df [-i] and lfs df [-i] match
19608 #
19609 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19610 check_lfs_df() {
19611         local dir=$2
19612         local inodes
19613         local df_out
19614         local lfs_df_out
19615         local count
19616         local passed=false
19617
19618         # blocks or inodes
19619         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19620
19621         for count in {1..100}; do
19622                 cancel_lru_locks
19623                 sync; sleep 0.2
19624
19625                 # read the lines of interest
19626                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19627                         error "df $inodes $dir | tail -n +2 failed"
19628                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19629                         error "lfs df $inodes $dir | grep summary: failed"
19630
19631                 # skip first substrings of each output as they are different
19632                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19633                 # compare the two outputs
19634                 passed=true
19635                 for i in {1..5}; do
19636                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19637                 done
19638                 $passed && break
19639         done
19640
19641         if ! $passed; then
19642                 df -P $inodes $dir
19643                 echo
19644                 lfs df $inodes $dir
19645                 error "df and lfs df $1 output mismatch: "      \
19646                       "df ${inodes}: ${df_out[*]}, "            \
19647                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19648         fi
19649 }
19650
19651 test_418() {
19652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19653
19654         local dir=$DIR/$tdir
19655         local numfiles=$((RANDOM % 4096 + 2))
19656         local numblocks=$((RANDOM % 256 + 1))
19657
19658         wait_delete_completed
19659         test_mkdir $dir
19660
19661         # check block output
19662         check_lfs_df blocks $dir
19663         # check inode output
19664         check_lfs_df inodes $dir
19665
19666         # create a single file and retest
19667         echo "Creating a single file and testing"
19668         createmany -o $dir/$tfile- 1 &>/dev/null ||
19669                 error "creating 1 file in $dir failed"
19670         check_lfs_df blocks $dir
19671         check_lfs_df inodes $dir
19672
19673         # create a random number of files
19674         echo "Creating $((numfiles - 1)) files and testing"
19675         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19676                 error "creating $((numfiles - 1)) files in $dir failed"
19677
19678         # write a random number of blocks to the first test file
19679         echo "Writing $numblocks 4K blocks and testing"
19680         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19681                 count=$numblocks &>/dev/null ||
19682                 error "dd to $dir/${tfile}-0 failed"
19683
19684         # retest
19685         check_lfs_df blocks $dir
19686         check_lfs_df inodes $dir
19687
19688         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19689                 error "unlinking $numfiles files in $dir failed"
19690 }
19691 run_test 418 "df and lfs df outputs match"
19692
19693 test_419()
19694 {
19695         local dir=$DIR/$tdir
19696
19697         mkdir -p $dir
19698         touch $dir/file
19699
19700         cancel_lru_locks mdc
19701
19702         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19703         $LCTL set_param fail_loc=0x1410
19704         cat $dir/file
19705         $LCTL set_param fail_loc=0
19706         rm -rf $dir
19707 }
19708 run_test 419 "Verify open file by name doesn't crash kernel"
19709
19710 prep_801() {
19711         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19712         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19713                 skip "Need server version at least 2.9.55"
19714
19715         start_full_debug_logging
19716 }
19717
19718 post_801() {
19719         stop_full_debug_logging
19720 }
19721
19722 barrier_stat() {
19723         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19724                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19725                            awk '/The barrier for/ { print $7 }')
19726                 echo $st
19727         else
19728                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19729                 echo \'$st\'
19730         fi
19731 }
19732
19733 barrier_expired() {
19734         local expired
19735
19736         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19737                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19738                           awk '/will be expired/ { print $7 }')
19739         else
19740                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19741         fi
19742
19743         echo $expired
19744 }
19745
19746 test_801a() {
19747         prep_801
19748
19749         echo "Start barrier_freeze at: $(date)"
19750         #define OBD_FAIL_BARRIER_DELAY          0x2202
19751         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19752         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19753
19754         sleep 2
19755         local b_status=$(barrier_stat)
19756         echo "Got barrier status at: $(date)"
19757         [ "$b_status" = "'freezing_p1'" ] ||
19758                 error "(1) unexpected barrier status $b_status"
19759
19760         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19761         wait
19762         b_status=$(barrier_stat)
19763         [ "$b_status" = "'frozen'" ] ||
19764                 error "(2) unexpected barrier status $b_status"
19765
19766         local expired=$(barrier_expired)
19767         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19768         sleep $((expired + 3))
19769
19770         b_status=$(barrier_stat)
19771         [ "$b_status" = "'expired'" ] ||
19772                 error "(3) unexpected barrier status $b_status"
19773
19774         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19775                 error "(4) fail to freeze barrier"
19776
19777         b_status=$(barrier_stat)
19778         [ "$b_status" = "'frozen'" ] ||
19779                 error "(5) unexpected barrier status $b_status"
19780
19781         echo "Start barrier_thaw at: $(date)"
19782         #define OBD_FAIL_BARRIER_DELAY          0x2202
19783         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19784         do_facet mgs $LCTL barrier_thaw $FSNAME &
19785
19786         sleep 2
19787         b_status=$(barrier_stat)
19788         echo "Got barrier status at: $(date)"
19789         [ "$b_status" = "'thawing'" ] ||
19790                 error "(6) unexpected barrier status $b_status"
19791
19792         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19793         wait
19794         b_status=$(barrier_stat)
19795         [ "$b_status" = "'thawed'" ] ||
19796                 error "(7) unexpected barrier status $b_status"
19797
19798         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19799         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19800         do_facet mgs $LCTL barrier_freeze $FSNAME
19801
19802         b_status=$(barrier_stat)
19803         [ "$b_status" = "'failed'" ] ||
19804                 error "(8) unexpected barrier status $b_status"
19805
19806         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19807         do_facet mgs $LCTL barrier_thaw $FSNAME
19808
19809         post_801
19810 }
19811 run_test 801a "write barrier user interfaces and stat machine"
19812
19813 test_801b() {
19814         prep_801
19815
19816         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19817         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19818         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19819         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19820         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19821
19822         cancel_lru_locks mdc
19823
19824         # 180 seconds should be long enough
19825         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19826
19827         local b_status=$(barrier_stat)
19828         [ "$b_status" = "'frozen'" ] ||
19829                 error "(6) unexpected barrier status $b_status"
19830
19831         mkdir $DIR/$tdir/d0/d10 &
19832         mkdir_pid=$!
19833
19834         touch $DIR/$tdir/d1/f13 &
19835         touch_pid=$!
19836
19837         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19838         ln_pid=$!
19839
19840         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19841         mv_pid=$!
19842
19843         rm -f $DIR/$tdir/d4/f12 &
19844         rm_pid=$!
19845
19846         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19847
19848         # To guarantee taht the 'stat' is not blocked
19849         b_status=$(barrier_stat)
19850         [ "$b_status" = "'frozen'" ] ||
19851                 error "(8) unexpected barrier status $b_status"
19852
19853         # let above commands to run at background
19854         sleep 5
19855
19856         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19857         ps -p $touch_pid || error "(10) touch should be blocked"
19858         ps -p $ln_pid || error "(11) link should be blocked"
19859         ps -p $mv_pid || error "(12) rename should be blocked"
19860         ps -p $rm_pid || error "(13) unlink should be blocked"
19861
19862         b_status=$(barrier_stat)
19863         [ "$b_status" = "'frozen'" ] ||
19864                 error "(14) unexpected barrier status $b_status"
19865
19866         do_facet mgs $LCTL barrier_thaw $FSNAME
19867         b_status=$(barrier_stat)
19868         [ "$b_status" = "'thawed'" ] ||
19869                 error "(15) unexpected barrier status $b_status"
19870
19871         wait $mkdir_pid || error "(16) mkdir should succeed"
19872         wait $touch_pid || error "(17) touch should succeed"
19873         wait $ln_pid || error "(18) link should succeed"
19874         wait $mv_pid || error "(19) rename should succeed"
19875         wait $rm_pid || error "(20) unlink should succeed"
19876
19877         post_801
19878 }
19879 run_test 801b "modification will be blocked by write barrier"
19880
19881 test_801c() {
19882         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19883
19884         prep_801
19885
19886         stop mds2 || error "(1) Fail to stop mds2"
19887
19888         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19889
19890         local b_status=$(barrier_stat)
19891         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19892                 do_facet mgs $LCTL barrier_thaw $FSNAME
19893                 error "(2) unexpected barrier status $b_status"
19894         }
19895
19896         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19897                 error "(3) Fail to rescan barrier bitmap"
19898
19899         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19900
19901         b_status=$(barrier_stat)
19902         [ "$b_status" = "'frozen'" ] ||
19903                 error "(4) unexpected barrier status $b_status"
19904
19905         do_facet mgs $LCTL barrier_thaw $FSNAME
19906         b_status=$(barrier_stat)
19907         [ "$b_status" = "'thawed'" ] ||
19908                 error "(5) unexpected barrier status $b_status"
19909
19910         local devname=$(mdsdevname 2)
19911
19912         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19913
19914         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19915                 error "(7) Fail to rescan barrier bitmap"
19916
19917         post_801
19918 }
19919 run_test 801c "rescan barrier bitmap"
19920
19921 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19922 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19923 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19924
19925 cleanup_802a() {
19926         trap 0
19927
19928         stopall
19929         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19930         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19931         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19932         setupall
19933 }
19934
19935 test_802a() {
19936
19937         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19938         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19939                 skip "Need server version at least 2.9.55"
19940
19941         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19942
19943         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19944
19945         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19946                 error "(2) Fail to copy"
19947
19948         trap cleanup_802a EXIT
19949
19950         # sync by force before remount as readonly
19951         sync; sync_all_data; sleep 3; sync_all_data
19952
19953         stopall
19954
19955         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19956         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19957         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19958
19959         echo "Mount the server as read only"
19960         setupall server_only || error "(3) Fail to start servers"
19961
19962         echo "Mount client without ro should fail"
19963         mount_client $MOUNT &&
19964                 error "(4) Mount client without 'ro' should fail"
19965
19966         echo "Mount client with ro should succeed"
19967         mount_client $MOUNT ro ||
19968                 error "(5) Mount client with 'ro' should succeed"
19969
19970         echo "Modify should be refused"
19971         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19972
19973         echo "Read should be allowed"
19974         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19975                 error "(7) Read should succeed under ro mode"
19976
19977         cleanup_802a
19978 }
19979 run_test 802a "simulate readonly device"
19980
19981 test_802b() {
19982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19983         remote_mds_nodsh && skip "remote MDS with nodsh"
19984
19985         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19986                 skip "readonly option not available"
19987
19988         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19989
19990         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19991                 error "(2) Fail to copy"
19992
19993         # write back all cached data before setting MDT to readonly
19994         cancel_lru_locks
19995         sync_all_data
19996
19997         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19998         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19999
20000         echo "Modify should be refused"
20001         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20002
20003         echo "Read should be allowed"
20004         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20005                 error "(7) Read should succeed under ro mode"
20006
20007         # disable readonly
20008         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20009 }
20010 run_test 802b "be able to set MDTs to readonly"
20011
20012 test_803() {
20013         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20014         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20015                 skip "MDS needs to be newer than 2.10.54"
20016
20017         mkdir -p $DIR/$tdir
20018         # Create some objects on all MDTs to trigger related logs objects
20019         for idx in $(seq $MDSCOUNT); do
20020                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20021                         $DIR/$tdir/dir${idx} ||
20022                         error "Fail to create $DIR/$tdir/dir${idx}"
20023         done
20024
20025         sync; sleep 3
20026         wait_delete_completed # ensure old test cleanups are finished
20027         echo "before create:"
20028         $LFS df -i $MOUNT
20029         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20030
20031         for i in {1..10}; do
20032                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20033                         error "Fail to create $DIR/$tdir/foo$i"
20034         done
20035
20036         sync; sleep 3
20037         echo "after create:"
20038         $LFS df -i $MOUNT
20039         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20040
20041         # allow for an llog to be cleaned up during the test
20042         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20043                 error "before ($before_used) + 10 > after ($after_used)"
20044
20045         for i in {1..10}; do
20046                 rm -rf $DIR/$tdir/foo$i ||
20047                         error "Fail to remove $DIR/$tdir/foo$i"
20048         done
20049
20050         sleep 3 # avoid MDT return cached statfs
20051         wait_delete_completed
20052         echo "after unlink:"
20053         $LFS df -i $MOUNT
20054         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20055
20056         # allow for an llog to be created during the test
20057         [ $after_used -le $((before_used + 1)) ] ||
20058                 error "after ($after_used) > before ($before_used) + 1"
20059 }
20060 run_test 803 "verify agent object for remote object"
20061
20062 test_804() {
20063         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20064         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20065                 skip "MDS needs to be newer than 2.10.54"
20066         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20067
20068         mkdir -p $DIR/$tdir
20069         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20070                 error "Fail to create $DIR/$tdir/dir0"
20071
20072         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20073         local dev=$(mdsdevname 2)
20074
20075         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20076                 grep ${fid} || error "NOT found agent entry for dir0"
20077
20078         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20079                 error "Fail to create $DIR/$tdir/dir1"
20080
20081         touch $DIR/$tdir/dir1/foo0 ||
20082                 error "Fail to create $DIR/$tdir/dir1/foo0"
20083         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20084         local rc=0
20085
20086         for idx in $(seq $MDSCOUNT); do
20087                 dev=$(mdsdevname $idx)
20088                 do_facet mds${idx} \
20089                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20090                         grep ${fid} && rc=$idx
20091         done
20092
20093         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20094                 error "Fail to rename foo0 to foo1"
20095         if [ $rc -eq 0 ]; then
20096                 for idx in $(seq $MDSCOUNT); do
20097                         dev=$(mdsdevname $idx)
20098                         do_facet mds${idx} \
20099                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20100                         grep ${fid} && rc=$idx
20101                 done
20102         fi
20103
20104         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20105                 error "Fail to rename foo1 to foo2"
20106         if [ $rc -eq 0 ]; then
20107                 for idx in $(seq $MDSCOUNT); do
20108                         dev=$(mdsdevname $idx)
20109                         do_facet mds${idx} \
20110                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20111                         grep ${fid} && rc=$idx
20112                 done
20113         fi
20114
20115         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20116
20117         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20118                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20119         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20120                 error "Fail to rename foo2 to foo0"
20121         unlink $DIR/$tdir/dir1/foo0 ||
20122                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20123         rm -rf $DIR/$tdir/dir0 ||
20124                 error "Fail to rm $DIR/$tdir/dir0"
20125
20126         for idx in $(seq $MDSCOUNT); do
20127                 dev=$(mdsdevname $idx)
20128                 rc=0
20129
20130                 stop mds${idx}
20131                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20132                         rc=$?
20133                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20134                         error "mount mds$idx failed"
20135                 df $MOUNT > /dev/null 2>&1
20136
20137                 # e2fsck should not return error
20138                 [ $rc -eq 0 ] ||
20139                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20140         done
20141 }
20142 run_test 804 "verify agent entry for remote entry"
20143
20144 cleanup_805() {
20145         do_facet $SINGLEMDS zfs set quota=$old $fsset
20146         unlinkmany $DIR/$tdir/f- 1000000
20147         trap 0
20148 }
20149
20150 test_805() {
20151         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20152         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20153         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20154                 skip "netfree not implemented before 0.7"
20155         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20156                 skip "Need MDS version at least 2.10.57"
20157
20158         local fsset
20159         local freekb
20160         local usedkb
20161         local old
20162         local quota
20163         local pref="osd-zfs.lustre-MDT0000."
20164
20165         # limit available space on MDS dataset to meet nospace issue
20166         # quickly. then ZFS 0.7.2 can use reserved space if asked
20167         # properly (using netfree flag in osd_declare_destroy()
20168         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20169         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20170                 gawk '{print $3}')
20171         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20172         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20173         let "usedkb=usedkb-freekb"
20174         let "freekb=freekb/2"
20175         if let "freekb > 5000"; then
20176                 let "freekb=5000"
20177         fi
20178         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20179         trap cleanup_805 EXIT
20180         mkdir $DIR/$tdir
20181         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20182         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20183         rm -rf $DIR/$tdir || error "not able to remove"
20184         do_facet $SINGLEMDS zfs set quota=$old $fsset
20185         trap 0
20186 }
20187 run_test 805 "ZFS can remove from full fs"
20188
20189 # Size-on-MDS test
20190 check_lsom_data()
20191 {
20192         local file=$1
20193         local size=$($LFS getsom -s $file)
20194         local expect=$(stat -c %s $file)
20195
20196         [[ $size == $expect ]] ||
20197                 error "$file expected size: $expect, got: $size"
20198
20199         local blocks=$($LFS getsom -b $file)
20200         expect=$(stat -c %b $file)
20201         [[ $blocks == $expect ]] ||
20202                 error "$file expected blocks: $expect, got: $blocks"
20203 }
20204
20205 check_lsom_size()
20206 {
20207         local size=$($LFS getsom -s $1)
20208         local expect=$2
20209
20210         [[ $size == $expect ]] ||
20211                 error "$file expected size: $expect, got: $size"
20212 }
20213
20214 test_806() {
20215         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20216                 skip "Need MDS version at least 2.11.52"
20217
20218         local bs=1048576
20219
20220         touch $DIR/$tfile || error "touch $tfile failed"
20221
20222         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20223         save_lustre_params client "llite.*.xattr_cache" > $save
20224         lctl set_param llite.*.xattr_cache=0
20225         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20226
20227         # single-threaded write
20228         echo "Test SOM for single-threaded write"
20229         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20230                 error "write $tfile failed"
20231         check_lsom_size $DIR/$tfile $bs
20232
20233         local num=32
20234         local size=$(($num * $bs))
20235         local offset=0
20236         local i
20237
20238         echo "Test SOM for single client multi-threaded($num) write"
20239         $TRUNCATE $DIR/$tfile 0
20240         for ((i = 0; i < $num; i++)); do
20241                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20242                 local pids[$i]=$!
20243                 offset=$((offset + $bs))
20244         done
20245         for (( i=0; i < $num; i++ )); do
20246                 wait ${pids[$i]}
20247         done
20248         check_lsom_size $DIR/$tfile $size
20249
20250         $TRUNCATE $DIR/$tfile 0
20251         for ((i = 0; i < $num; i++)); do
20252                 offset=$((offset - $bs))
20253                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20254                 local pids[$i]=$!
20255         done
20256         for (( i=0; i < $num; i++ )); do
20257                 wait ${pids[$i]}
20258         done
20259         check_lsom_size $DIR/$tfile $size
20260
20261         # multi-client wirtes
20262         num=$(get_node_count ${CLIENTS//,/ })
20263         size=$(($num * $bs))
20264         offset=0
20265         i=0
20266
20267         echo "Test SOM for multi-client ($num) writes"
20268         $TRUNCATE $DIR/$tfile 0
20269         for client in ${CLIENTS//,/ }; do
20270                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20271                 local pids[$i]=$!
20272                 i=$((i + 1))
20273                 offset=$((offset + $bs))
20274         done
20275         for (( i=0; i < $num; i++ )); do
20276                 wait ${pids[$i]}
20277         done
20278         check_lsom_size $DIR/$tfile $offset
20279
20280         i=0
20281         $TRUNCATE $DIR/$tfile 0
20282         for client in ${CLIENTS//,/ }; do
20283                 offset=$((offset - $bs))
20284                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20285                 local pids[$i]=$!
20286                 i=$((i + 1))
20287         done
20288         for (( i=0; i < $num; i++ )); do
20289                 wait ${pids[$i]}
20290         done
20291         check_lsom_size $DIR/$tfile $size
20292
20293         # verify truncate
20294         echo "Test SOM for truncate"
20295         $TRUNCATE $DIR/$tfile 1048576
20296         check_lsom_size $DIR/$tfile 1048576
20297         $TRUNCATE $DIR/$tfile 1234
20298         check_lsom_size $DIR/$tfile 1234
20299
20300         # verify SOM blocks count
20301         echo "Verify SOM block count"
20302         $TRUNCATE $DIR/$tfile 0
20303         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20304                 error "failed to write file $tfile"
20305         check_lsom_data $DIR/$tfile
20306 }
20307 run_test 806 "Verify Lazy Size on MDS"
20308
20309 test_807() {
20310         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20311         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20312                 skip "Need MDS version at least 2.11.52"
20313
20314         # Registration step
20315         changelog_register || error "changelog_register failed"
20316         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20317         changelog_users $SINGLEMDS | grep -q $cl_user ||
20318                 error "User $cl_user not found in changelog_users"
20319
20320         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20321         save_lustre_params client "llite.*.xattr_cache" > $save
20322         lctl set_param llite.*.xattr_cache=0
20323         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20324
20325         rm -rf $DIR/$tdir || error "rm $tdir failed"
20326         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20327         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20328         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20329         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20330                 error "truncate $tdir/trunc failed"
20331
20332         local bs=1048576
20333         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20334                 error "write $tfile failed"
20335
20336         # multi-client wirtes
20337         local num=$(get_node_count ${CLIENTS//,/ })
20338         local offset=0
20339         local i=0
20340
20341         echo "Test SOM for multi-client ($num) writes"
20342         touch $DIR/$tfile || error "touch $tfile failed"
20343         $TRUNCATE $DIR/$tfile 0
20344         for client in ${CLIENTS//,/ }; do
20345                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20346                 local pids[$i]=$!
20347                 i=$((i + 1))
20348                 offset=$((offset + $bs))
20349         done
20350         for (( i=0; i < $num; i++ )); do
20351                 wait ${pids[$i]}
20352         done
20353
20354         sleep 5
20355         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20356         check_lsom_data $DIR/$tdir/trunc
20357         check_lsom_data $DIR/$tdir/single_dd
20358         check_lsom_data $DIR/$tfile
20359
20360         rm -rf $DIR/$tdir
20361         # Deregistration step
20362         changelog_deregister || error "changelog_deregister failed"
20363 }
20364 run_test 807 "verify LSOM syncing tool"
20365
20366 check_som_nologged()
20367 {
20368         local lines=$($LFS changelog $FSNAME-MDT0000 |
20369                 grep 'x=trusted.som' | wc -l)
20370         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20371 }
20372
20373 test_808() {
20374         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20375                 skip "Need MDS version at least 2.11.55"
20376
20377         # Registration step
20378         changelog_register || error "changelog_register failed"
20379
20380         touch $DIR/$tfile || error "touch $tfile failed"
20381         check_som_nologged
20382
20383         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20384                 error "write $tfile failed"
20385         check_som_nologged
20386
20387         $TRUNCATE $DIR/$tfile 1234
20388         check_som_nologged
20389
20390         $TRUNCATE $DIR/$tfile 1048576
20391         check_som_nologged
20392
20393         # Deregistration step
20394         changelog_deregister || error "changelog_deregister failed"
20395 }
20396 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20397
20398 check_som_nodata()
20399 {
20400         $LFS getsom $1
20401         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20402 }
20403
20404 test_809() {
20405         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20406                 skip "Need MDS version at least 2.11.56"
20407
20408         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20409                 error "failed to create DoM-only file $DIR/$tfile"
20410         touch $DIR/$tfile || error "touch $tfile failed"
20411         check_som_nodata $DIR/$tfile
20412
20413         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20414                 error "write $tfile failed"
20415         check_som_nodata $DIR/$tfile
20416
20417         $TRUNCATE $DIR/$tfile 1234
20418         check_som_nodata $DIR/$tfile
20419
20420         $TRUNCATE $DIR/$tfile 4097
20421         check_som_nodata $DIR/$file
20422 }
20423 run_test 809 "Verify no SOM xattr store for DoM-only files"
20424
20425 test_810() {
20426         local ORIG
20427         local CSUM
20428
20429         # t10 seem to dislike partial pages
20430         lctl set_param osc.*.checksum_type=adler
20431         lctl set_param fail_loc=0x411
20432         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20433         ORIG=$(md5sum $DIR/$tfile)
20434         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20435         CSUM=$(md5sum $DIR/$tfile)
20436         set_checksum_type adler
20437         if [ "$ORIG" != "$CSUM" ]; then
20438                 error "$ORIG != $CSUM"
20439         fi
20440 }
20441 run_test 810 "partial page writes on ZFS (LU-11663)"
20442
20443 test_811() {
20444         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20445                 skip "Need MDS version at least 2.11.56"
20446
20447         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20448         do_facet mds1 $LCTL set_param fail_loc=0x165
20449         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20450
20451         stop mds1
20452         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20453
20454         sleep 5
20455         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20456                 error "MDD orphan cleanup thread not quit"
20457 }
20458 run_test 811 "orphan name stub can be cleaned up in startup"
20459
20460 test_812() {
20461         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20462                 skip "OST < 2.12.51 doesn't support this fail_loc"
20463
20464         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20465         # ensure ost1 is connected
20466         stat $DIR/$tfile >/dev/null || error "can't stat"
20467         wait_osc_import_state client ost1 FULL
20468         # no locks, no reqs to let the connection idle
20469         cancel_lru_locks osc
20470
20471         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20472 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20473         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20474         wait_osc_import_state client ost1 CONNECTING
20475         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20476
20477         stat $DIR/$tfile >/dev/null || error "can't stat file"
20478 }
20479 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20480
20481 test_813() {
20482         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20483         [ -z "$file_heat_sav" ] && skip "no file heat support"
20484
20485         local readsample
20486         local writesample
20487         local readbyte
20488         local writebyte
20489         local readsample1
20490         local writesample1
20491         local readbyte1
20492         local writebyte1
20493
20494         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20495         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20496
20497         $LCTL set_param -n llite.*.file_heat=1
20498         echo "Turn on file heat"
20499         echo "Period second: $period_second, Decay percentage: $decay_pct"
20500
20501         echo "QQQQ" > $DIR/$tfile
20502         echo "QQQQ" > $DIR/$tfile
20503         echo "QQQQ" > $DIR/$tfile
20504         cat $DIR/$tfile > /dev/null
20505         cat $DIR/$tfile > /dev/null
20506         cat $DIR/$tfile > /dev/null
20507         cat $DIR/$tfile > /dev/null
20508
20509         local out=$($LFS heat_get $DIR/$tfile)
20510
20511         $LFS heat_get $DIR/$tfile
20512         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20513         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20514         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20515         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20516
20517         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20518         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20519         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20520         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20521
20522         sleep $((period_second + 3))
20523         echo "Sleep $((period_second + 3)) seconds..."
20524         # The recursion formula to calculate the heat of the file f is as
20525         # follow:
20526         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20527         # Where Hi is the heat value in the period between time points i*I and
20528         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20529         # to the weight of Ci.
20530         out=$($LFS heat_get $DIR/$tfile)
20531         $LFS heat_get $DIR/$tfile
20532         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20533         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20534         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20535         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20536
20537         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20538                 error "read sample ($readsample) is wrong"
20539         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20540                 error "write sample ($writesample) is wrong"
20541         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20542                 error "read bytes ($readbyte) is wrong"
20543         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20544                 error "write bytes ($writebyte) is wrong"
20545
20546         echo "QQQQ" > $DIR/$tfile
20547         echo "QQQQ" > $DIR/$tfile
20548         echo "QQQQ" > $DIR/$tfile
20549         cat $DIR/$tfile > /dev/null
20550         cat $DIR/$tfile > /dev/null
20551         cat $DIR/$tfile > /dev/null
20552         cat $DIR/$tfile > /dev/null
20553
20554         sleep $((period_second + 3))
20555         echo "Sleep $((period_second + 3)) seconds..."
20556
20557         out=$($LFS heat_get $DIR/$tfile)
20558         $LFS heat_get $DIR/$tfile
20559         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20560         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20561         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20562         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20563
20564         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20565                 4 * $decay_pct) / 100") -eq 1 ] ||
20566                 error "read sample ($readsample1) is wrong"
20567         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20568                 3 * $decay_pct) / 100") -eq 1 ] ||
20569                 error "write sample ($writesample1) is wrong"
20570         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20571                 20 * $decay_pct) / 100") -eq 1 ] ||
20572                 error "read bytes ($readbyte1) is wrong"
20573         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20574                 15 * $decay_pct) / 100") -eq 1 ] ||
20575                 error "write bytes ($writebyte1) is wrong"
20576
20577         echo "Turn off file heat for the file $DIR/$tfile"
20578         $LFS heat_set -o $DIR/$tfile
20579
20580         echo "QQQQ" > $DIR/$tfile
20581         echo "QQQQ" > $DIR/$tfile
20582         echo "QQQQ" > $DIR/$tfile
20583         cat $DIR/$tfile > /dev/null
20584         cat $DIR/$tfile > /dev/null
20585         cat $DIR/$tfile > /dev/null
20586         cat $DIR/$tfile > /dev/null
20587
20588         out=$($LFS heat_get $DIR/$tfile)
20589         $LFS heat_get $DIR/$tfile
20590         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20591         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20592         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20593         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20594
20595         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20596         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20597         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20598         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20599
20600         echo "Trun on file heat for the file $DIR/$tfile"
20601         $LFS heat_set -O $DIR/$tfile
20602
20603         echo "QQQQ" > $DIR/$tfile
20604         echo "QQQQ" > $DIR/$tfile
20605         echo "QQQQ" > $DIR/$tfile
20606         cat $DIR/$tfile > /dev/null
20607         cat $DIR/$tfile > /dev/null
20608         cat $DIR/$tfile > /dev/null
20609         cat $DIR/$tfile > /dev/null
20610
20611         out=$($LFS heat_get $DIR/$tfile)
20612         $LFS heat_get $DIR/$tfile
20613         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20614         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20615         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20616         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20617
20618         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20619         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20620         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20621         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20622
20623         $LFS heat_set -c $DIR/$tfile
20624         $LCTL set_param -n llite.*.file_heat=0
20625         echo "Turn off file heat support for the Lustre filesystem"
20626
20627         echo "QQQQ" > $DIR/$tfile
20628         echo "QQQQ" > $DIR/$tfile
20629         echo "QQQQ" > $DIR/$tfile
20630         cat $DIR/$tfile > /dev/null
20631         cat $DIR/$tfile > /dev/null
20632         cat $DIR/$tfile > /dev/null
20633         cat $DIR/$tfile > /dev/null
20634
20635         out=$($LFS heat_get $DIR/$tfile)
20636         $LFS heat_get $DIR/$tfile
20637         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20638         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20639         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20640         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20641
20642         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20643         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20644         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20645         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20646
20647         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20648         rm -f $DIR/$tfile
20649 }
20650 run_test 813 "File heat verfication"
20651
20652 #
20653 # tests that do cleanup/setup should be run at the end
20654 #
20655
20656 test_900() {
20657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20658         local ls
20659
20660         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20661         $LCTL set_param fail_loc=0x903
20662
20663         cancel_lru_locks MGC
20664
20665         FAIL_ON_ERROR=true cleanup
20666         FAIL_ON_ERROR=true setup
20667 }
20668 run_test 900 "umount should not race with any mgc requeue thread"
20669
20670 complete $SECONDS
20671 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20672 check_and_cleanup_lustre
20673 if [ "$I_MOUNTED" != "yes" ]; then
20674         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20675 fi
20676 exit_status