Whamcloud - gitweb
LU-6951 tests: sanity test_27m failure
[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         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1615                 skip_env "multiple clients -- skipping"
1616
1617         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1618                    head -n1)
1619         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1620                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1621         fi
1622         trap simple_cleanup_common EXIT
1623         test_mkdir $DIR/$tdir
1624         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1625         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1626                 error "dd should fill OST0"
1627         i=2
1628         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1629                 i=$((i + 1))
1630                 [ $i -gt 256 ] && break
1631         done
1632         i=$((i + 1))
1633         touch $DIR/$tdir/$tfile.$i
1634         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1635             awk '{print $1}'| grep -w "0") ] &&
1636                 error "OST0 was full but new created file still use it"
1637         i=$((i + 1))
1638         touch $DIR/$tdir/$tfile.$i
1639         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1640             awk '{print $1}'| grep -w "0") ] &&
1641                 error "OST0 was full but new created file still use it"
1642         simple_cleanup_common
1643 }
1644 run_test 27m "create file while OST0 was full"
1645
1646 sleep_maxage() {
1647         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1648                       awk '{ print $1 * 2; exit; }')
1649         sleep $delay
1650 }
1651
1652 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1653 # if the OST isn't full anymore.
1654 reset_enospc() {
1655         local OSTIDX=${1:-""}
1656
1657         local list=$(comma_list $(osts_nodes))
1658         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1659
1660         do_nodes $list lctl set_param fail_loc=0
1661         sync    # initiate all OST_DESTROYs from MDS to OST
1662         sleep_maxage
1663 }
1664
1665 exhaust_precreations() {
1666         local OSTIDX=$1
1667         local FAILLOC=$2
1668         local FAILIDX=${3:-$OSTIDX}
1669         local ofacet=ost$((OSTIDX + 1))
1670
1671         test_mkdir -p -c1 $DIR/$tdir
1672         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1673         local mfacet=mds$((mdtidx + 1))
1674         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1675
1676         local OST=$(ostname_from_index $OSTIDX)
1677
1678         # on the mdt's osc
1679         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1680         local last_id=$(do_facet $mfacet lctl get_param -n \
1681                         osc.$mdtosc_proc1.prealloc_last_id)
1682         local next_id=$(do_facet $mfacet lctl get_param -n \
1683                         osc.$mdtosc_proc1.prealloc_next_id)
1684
1685         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1686         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1687
1688         test_mkdir -p $DIR/$tdir/${OST}
1689         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1690 #define OBD_FAIL_OST_ENOSPC              0x215
1691         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1692         echo "Creating to objid $last_id on ost $OST..."
1693         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1694         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1695         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1696         sleep_maxage
1697 }
1698
1699 exhaust_all_precreations() {
1700         local i
1701         for (( i=0; i < OSTCOUNT; i++ )) ; do
1702                 exhaust_precreations $i $1 -1
1703         done
1704 }
1705
1706 test_27n() {
1707         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1709         remote_mds_nodsh && skip "remote MDS with nodsh"
1710         remote_ost_nodsh && skip "remote OST with nodsh"
1711
1712         reset_enospc
1713         rm -f $DIR/$tdir/$tfile
1714         exhaust_precreations 0 0x80000215
1715         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1716         touch $DIR/$tdir/$tfile || error "touch failed"
1717         $LFS getstripe $DIR/$tdir/$tfile
1718         reset_enospc
1719 }
1720 run_test 27n "create file with some full OSTs"
1721
1722 test_27o() {
1723         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1725         remote_mds_nodsh && skip "remote MDS with nodsh"
1726         remote_ost_nodsh && skip "remote OST with nodsh"
1727
1728         reset_enospc
1729         rm -f $DIR/$tdir/$tfile
1730         exhaust_all_precreations 0x215
1731
1732         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1733
1734         reset_enospc
1735         rm -rf $DIR/$tdir/*
1736 }
1737 run_test 27o "create file with all full OSTs (should error)"
1738
1739 test_27p() {
1740         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1742         remote_mds_nodsh && skip "remote MDS with nodsh"
1743         remote_ost_nodsh && skip "remote OST with nodsh"
1744
1745         reset_enospc
1746         rm -f $DIR/$tdir/$tfile
1747         test_mkdir $DIR/$tdir
1748
1749         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1750         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1751         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1752
1753         exhaust_precreations 0 0x80000215
1754         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1755         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1756         $LFS getstripe $DIR/$tdir/$tfile
1757
1758         reset_enospc
1759 }
1760 run_test 27p "append to a truncated file with some full OSTs"
1761
1762 test_27q() {
1763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1765         remote_mds_nodsh && skip "remote MDS with nodsh"
1766         remote_ost_nodsh && skip "remote OST with nodsh"
1767
1768         reset_enospc
1769         rm -f $DIR/$tdir/$tfile
1770
1771         test_mkdir $DIR/$tdir
1772         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1773         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1774                 error "truncate $DIR/$tdir/$tfile failed"
1775         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1776
1777         exhaust_all_precreations 0x215
1778
1779         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1780         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1781
1782         reset_enospc
1783 }
1784 run_test 27q "append to truncated file with all OSTs full (should error)"
1785
1786 test_27r() {
1787         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1789         remote_mds_nodsh && skip "remote MDS with nodsh"
1790         remote_ost_nodsh && skip "remote OST with nodsh"
1791
1792         reset_enospc
1793         rm -f $DIR/$tdir/$tfile
1794         exhaust_precreations 0 0x80000215
1795
1796         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1797
1798         reset_enospc
1799 }
1800 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1801
1802 test_27s() { # bug 10725
1803         test_mkdir $DIR/$tdir
1804         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1805         local stripe_count=0
1806         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1807         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1808                 error "stripe width >= 2^32 succeeded" || true
1809
1810 }
1811 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1812
1813 test_27t() { # bug 10864
1814         WDIR=$(pwd)
1815         WLFS=$(which lfs)
1816         cd $DIR
1817         touch $tfile
1818         $WLFS getstripe $tfile
1819         cd $WDIR
1820 }
1821 run_test 27t "check that utils parse path correctly"
1822
1823 test_27u() { # bug 4900
1824         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1825         remote_mds_nodsh && skip "remote MDS with nodsh"
1826
1827         local index
1828         local list=$(comma_list $(mdts_nodes))
1829
1830 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1831         do_nodes $list $LCTL set_param fail_loc=0x139
1832         test_mkdir -p $DIR/$tdir
1833         trap simple_cleanup_common EXIT
1834         createmany -o $DIR/$tdir/t- 1000
1835         do_nodes $list $LCTL set_param fail_loc=0
1836
1837         TLOG=$TMP/$tfile.getstripe
1838         $LFS getstripe $DIR/$tdir > $TLOG
1839         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1840         unlinkmany $DIR/$tdir/t- 1000
1841         trap 0
1842         [[ $OBJS -gt 0 ]] &&
1843                 error "$OBJS objects created on OST-0. See $TLOG" ||
1844                 rm -f $TLOG
1845 }
1846 run_test 27u "skip object creation on OSC w/o objects"
1847
1848 test_27v() { # bug 4900
1849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1851         remote_mds_nodsh && skip "remote MDS with nodsh"
1852         remote_ost_nodsh && skip "remote OST with nodsh"
1853
1854         exhaust_all_precreations 0x215
1855         reset_enospc
1856
1857         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1858
1859         touch $DIR/$tdir/$tfile
1860         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1861         # all except ost1
1862         for (( i=1; i < OSTCOUNT; i++ )); do
1863                 do_facet ost$i lctl set_param fail_loc=0x705
1864         done
1865         local START=`date +%s`
1866         createmany -o $DIR/$tdir/$tfile 32
1867
1868         local FINISH=`date +%s`
1869         local TIMEOUT=`lctl get_param -n timeout`
1870         local PROCESS=$((FINISH - START))
1871         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1872                error "$FINISH - $START >= $TIMEOUT / 2"
1873         sleep $((TIMEOUT / 2 - PROCESS))
1874         reset_enospc
1875 }
1876 run_test 27v "skip object creation on slow OST"
1877
1878 test_27w() { # bug 10997
1879         test_mkdir $DIR/$tdir
1880         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1881         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1882                 error "stripe size $size != 65536" || true
1883         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1884                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1885 }
1886 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1887
1888 test_27wa() {
1889         [[ $OSTCOUNT -lt 2 ]] &&
1890                 skip_env "skipping multiple stripe count/offset test"
1891
1892         test_mkdir $DIR/$tdir
1893         for i in $(seq 1 $OSTCOUNT); do
1894                 offset=$((i - 1))
1895                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1896                         error "setstripe -c $i -i $offset failed"
1897                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1898                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1899                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1900                 [ $index -ne $offset ] &&
1901                         error "stripe offset $index != $offset" || true
1902         done
1903 }
1904 run_test 27wa "check $LFS setstripe -c -i options"
1905
1906 test_27x() {
1907         remote_ost_nodsh && skip "remote OST with nodsh"
1908         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1910
1911         OFFSET=$(($OSTCOUNT - 1))
1912         OSTIDX=0
1913         local OST=$(ostname_from_index $OSTIDX)
1914
1915         test_mkdir $DIR/$tdir
1916         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1917         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1918         sleep_maxage
1919         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1920         for i in $(seq 0 $OFFSET); do
1921                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1922                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1923                 error "OST0 was degraded but new created file still use it"
1924         done
1925         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1926 }
1927 run_test 27x "create files while OST0 is degraded"
1928
1929 test_27y() {
1930         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1931         remote_mds_nodsh && skip "remote MDS with nodsh"
1932         remote_ost_nodsh && skip "remote OST with nodsh"
1933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1934
1935         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1936         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1937                 osc.$mdtosc.prealloc_last_id)
1938         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1939                 osc.$mdtosc.prealloc_next_id)
1940         local fcount=$((last_id - next_id))
1941         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1942         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1943
1944         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1945                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1946         local OST_DEACTIVE_IDX=-1
1947         local OSC
1948         local OSTIDX
1949         local OST
1950
1951         for OSC in $MDS_OSCS; do
1952                 OST=$(osc_to_ost $OSC)
1953                 OSTIDX=$(index_from_ostuuid $OST)
1954                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1955                         OST_DEACTIVE_IDX=$OSTIDX
1956                 fi
1957                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1958                         echo $OSC "is Deactivated:"
1959                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1960                 fi
1961         done
1962
1963         OSTIDX=$(index_from_ostuuid $OST)
1964         test_mkdir $DIR/$tdir
1965         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1966
1967         for OSC in $MDS_OSCS; do
1968                 OST=$(osc_to_ost $OSC)
1969                 OSTIDX=$(index_from_ostuuid $OST)
1970                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1971                         echo $OST "is degraded:"
1972                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1973                                                 obdfilter.$OST.degraded=1
1974                 fi
1975         done
1976
1977         sleep_maxage
1978         createmany -o $DIR/$tdir/$tfile $fcount
1979
1980         for OSC in $MDS_OSCS; do
1981                 OST=$(osc_to_ost $OSC)
1982                 OSTIDX=$(index_from_ostuuid $OST)
1983                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1984                         echo $OST "is recovered from degraded:"
1985                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1986                                                 obdfilter.$OST.degraded=0
1987                 else
1988                         do_facet $SINGLEMDS lctl --device %$OSC activate
1989                 fi
1990         done
1991
1992         # all osp devices get activated, hence -1 stripe count restored
1993         local stripe_count=0
1994
1995         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1996         # devices get activated.
1997         sleep_maxage
1998         $LFS setstripe -c -1 $DIR/$tfile
1999         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2000         rm -f $DIR/$tfile
2001         [ $stripe_count -ne $OSTCOUNT ] &&
2002                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2003         return 0
2004 }
2005 run_test 27y "create files while OST0 is degraded and the rest inactive"
2006
2007 check_seq_oid()
2008 {
2009         log "check file $1"
2010
2011         lmm_count=$($LFS getstripe -c $1)
2012         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2013         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2014
2015         local old_ifs="$IFS"
2016         IFS=$'[:]'
2017         fid=($($LFS path2fid $1))
2018         IFS="$old_ifs"
2019
2020         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2021         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2022
2023         # compare lmm_seq and lu_fid->f_seq
2024         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2025         # compare lmm_object_id and lu_fid->oid
2026         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2027
2028         # check the trusted.fid attribute of the OST objects of the file
2029         local have_obdidx=false
2030         local stripe_nr=0
2031         $LFS getstripe $1 | while read obdidx oid hex seq; do
2032                 # skip lines up to and including "obdidx"
2033                 [ -z "$obdidx" ] && break
2034                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2035                 $have_obdidx || continue
2036
2037                 local ost=$((obdidx + 1))
2038                 local dev=$(ostdevname $ost)
2039                 local oid_hex
2040
2041                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2042
2043                 seq=$(echo $seq | sed -e "s/^0x//g")
2044                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2045                         oid_hex=$(echo $oid)
2046                 else
2047                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2048                 fi
2049                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2050
2051                 local ff=""
2052                 #
2053                 # Don't unmount/remount the OSTs if we don't need to do that.
2054                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2055                 # update too, until that use mount/ll_decode_filter_fid/mount.
2056                 # Re-enable when debugfs will understand new filter_fid.
2057                 #
2058                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2059                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2060                                 $dev 2>/dev/null" | grep "parent=")
2061                 fi
2062                 if [ -z "$ff" ]; then
2063                         stop ost$ost
2064                         mount_fstype ost$ost
2065                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2066                                 $(facet_mntpt ost$ost)/$obj_file)
2067                         unmount_fstype ost$ost
2068                         start ost$ost $dev $OST_MOUNT_OPTS
2069                         clients_up
2070                 fi
2071
2072                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2073
2074                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2075
2076                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2077                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2078                 #
2079                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2080                 #       stripe_size=1048576 component_id=1 component_start=0 \
2081                 #       component_end=33554432
2082                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2083                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2084                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2085                 local ff_pstripe
2086                 if grep -q 'stripe=' <<<$ff; then
2087                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2088                 else
2089                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2090                         # into f_ver in this case.  See comment on ff_parent.
2091                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2092                 fi
2093
2094                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2095                 [ $ff_pseq = $lmm_seq ] ||
2096                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2097                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2098                 [ $ff_poid = $lmm_oid ] ||
2099                         error "FF parent OID $ff_poid != $lmm_oid"
2100                 (($ff_pstripe == $stripe_nr)) ||
2101                         error "FF stripe $ff_pstripe != $stripe_nr"
2102
2103                 stripe_nr=$((stripe_nr + 1))
2104                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2105                         continue
2106                 if grep -q 'stripe_count=' <<<$ff; then
2107                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2108                                             -e 's/ .*//' <<<$ff)
2109                         [ $lmm_count = $ff_scnt ] ||
2110                                 error "FF stripe count $lmm_count != $ff_scnt"
2111                 fi
2112         done
2113 }
2114
2115 test_27z() {
2116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2117         remote_ost_nodsh && skip "remote OST with nodsh"
2118
2119         test_mkdir $DIR/$tdir
2120         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2121                 { error "setstripe -c -1 failed"; return 1; }
2122         # We need to send a write to every object to get parent FID info set.
2123         # This _should_ also work for setattr, but does not currently.
2124         # touch $DIR/$tdir/$tfile-1 ||
2125         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2126                 { error "dd $tfile-1 failed"; return 2; }
2127         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2128                 { error "setstripe -c -1 failed"; return 3; }
2129         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2130                 { error "dd $tfile-2 failed"; return 4; }
2131
2132         # make sure write RPCs have been sent to OSTs
2133         sync; sleep 5; sync
2134
2135         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2136         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2137 }
2138 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2139
2140 test_27A() { # b=19102
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         save_layout_restore_at_exit $MOUNT
2144         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2145         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2146                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2147         local default_size=$($LFS getstripe -S $MOUNT)
2148         local default_offset=$($LFS getstripe -i $MOUNT)
2149         local dsize=$(do_facet $SINGLEMDS \
2150                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2151         [ $default_size -eq $dsize ] ||
2152                 error "stripe size $default_size != $dsize"
2153         [ $default_offset -eq -1 ] ||
2154                 error "stripe offset $default_offset != -1"
2155 }
2156 run_test 27A "check filesystem-wide default LOV EA values"
2157
2158 test_27B() { # LU-2523
2159         test_mkdir $DIR/$tdir
2160         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2161         touch $DIR/$tdir/f0
2162         # open f1 with O_LOV_DELAY_CREATE
2163         # rename f0 onto f1
2164         # call setstripe ioctl on open file descriptor for f1
2165         # close
2166         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2167                 $DIR/$tdir/f0
2168
2169         rm -f $DIR/$tdir/f1
2170         # open f1 with O_LOV_DELAY_CREATE
2171         # unlink f1
2172         # call setstripe ioctl on open file descriptor for f1
2173         # close
2174         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2175
2176         # Allow multiop to fail in imitation of NFS's busted semantics.
2177         true
2178 }
2179 run_test 27B "call setstripe on open unlinked file/rename victim"
2180
2181 test_27C() { #LU-2871
2182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2183
2184         declare -a ost_idx
2185         local index
2186         local found
2187         local i
2188         local j
2189
2190         test_mkdir $DIR/$tdir
2191         cd $DIR/$tdir
2192         for i in $(seq 0 $((OSTCOUNT - 1))); do
2193                 # set stripe across all OSTs starting from OST$i
2194                 $LFS setstripe -i $i -c -1 $tfile$i
2195                 # get striping information
2196                 ost_idx=($($LFS getstripe $tfile$i |
2197                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2198                 echo ${ost_idx[@]}
2199
2200                 # check the layout
2201                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2202                         error "${#ost_idx[@]} != $OSTCOUNT"
2203
2204                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2205                         found=0
2206                         for j in $(echo ${ost_idx[@]}); do
2207                                 if [ $index -eq $j ]; then
2208                                         found=1
2209                                         break
2210                                 fi
2211                         done
2212                         [ $found = 1 ] ||
2213                                 error "Can not find $index in ${ost_idx[@]}"
2214                 done
2215         done
2216 }
2217 run_test 27C "check full striping across all OSTs"
2218
2219 test_27D() {
2220         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2221         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2222         remote_mds_nodsh && skip "remote MDS with nodsh"
2223
2224         local POOL=${POOL:-testpool}
2225         local first_ost=0
2226         local last_ost=$(($OSTCOUNT - 1))
2227         local ost_step=1
2228         local ost_list=$(seq $first_ost $ost_step $last_ost)
2229         local ost_range="$first_ost $last_ost $ost_step"
2230
2231         if ! combined_mgs_mds ; then
2232                 mount_mgs_client
2233         fi
2234
2235         test_mkdir $DIR/$tdir
2236         pool_add $POOL || error "pool_add failed"
2237         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2238
2239         local skip27D
2240         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2241                 skip27D+="-s 29"
2242         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2243                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2244                         skip27D+=" -s 30,31"
2245         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2246                 error "llapi_layout_test failed"
2247
2248         destroy_test_pools || error "destroy test pools failed"
2249
2250         if ! combined_mgs_mds ; then
2251                 umount_mgs_client
2252         fi
2253 }
2254 run_test 27D "validate llapi_layout API"
2255
2256 # Verify that default_easize is increased from its initial value after
2257 # accessing a widely striped file.
2258 test_27E() {
2259         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2260         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2261                 skip "client does not have LU-3338 fix"
2262
2263         # 72 bytes is the minimum space required to store striping
2264         # information for a file striped across one OST:
2265         # (sizeof(struct lov_user_md_v3) +
2266         #  sizeof(struct lov_user_ost_data_v1))
2267         local min_easize=72
2268         $LCTL set_param -n llite.*.default_easize $min_easize ||
2269                 error "lctl set_param failed"
2270         local easize=$($LCTL get_param -n llite.*.default_easize)
2271
2272         [ $easize -eq $min_easize ] ||
2273                 error "failed to set default_easize"
2274
2275         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2276                 error "setstripe failed"
2277         cat $DIR/$tfile
2278         rm $DIR/$tfile
2279
2280         easize=$($LCTL get_param -n llite.*.default_easize)
2281
2282         [ $easize -gt $min_easize ] ||
2283                 error "default_easize not updated"
2284 }
2285 run_test 27E "check that default extended attribute size properly increases"
2286
2287 test_27F() { # LU-5346/LU-7975
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2290         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2291                 skip "Need MDS version at least 2.8.51"
2292         remote_ost_nodsh && skip "remote OST with nodsh"
2293
2294         test_mkdir $DIR/$tdir
2295         rm -f $DIR/$tdir/f0
2296         $LFS setstripe -c 2 $DIR/$tdir
2297
2298         # stop all OSTs to reproduce situation for LU-7975 ticket
2299         for num in $(seq $OSTCOUNT); do
2300                 stop ost$num
2301         done
2302
2303         # open/create f0 with O_LOV_DELAY_CREATE
2304         # truncate f0 to a non-0 size
2305         # close
2306         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2307
2308         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2309         # open/write it again to force delayed layout creation
2310         cat /etc/hosts > $DIR/$tdir/f0 &
2311         catpid=$!
2312
2313         # restart OSTs
2314         for num in $(seq $OSTCOUNT); do
2315                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2316                         error "ost$num failed to start"
2317         done
2318
2319         wait $catpid || error "cat failed"
2320
2321         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2322         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2323                 error "wrong stripecount"
2324
2325 }
2326 run_test 27F "Client resend delayed layout creation with non-zero size"
2327
2328 test_27G() { #LU-10629
2329         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2330                 skip "Need MDS version at least 2.11.51"
2331         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2332         remote_mds_nodsh && skip "remote MDS with nodsh"
2333         local POOL=${POOL:-testpool}
2334         local ostrange="0 0 1"
2335
2336         test_mkdir $DIR/$tdir
2337         pool_add $POOL || error "pool_add failed"
2338         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2339         $LFS setstripe -p $POOL $DIR/$tdir
2340
2341         local pool=$($LFS getstripe -p $DIR/$tdir)
2342
2343         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2344
2345         $LFS setstripe -d $DIR/$tdir
2346
2347         pool=$($LFS getstripe -p $DIR/$tdir)
2348
2349         rmdir $DIR/$tdir
2350
2351         [ -z "$pool" ] || error "'$pool' is not empty"
2352 }
2353 run_test 27G "Clear OST pool from stripe"
2354
2355 test_27H() {
2356         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2357                 skip "Need MDS version newer than 2.11.54"
2358         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2359         test_mkdir $DIR/$tdir
2360         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2361         touch $DIR/$tdir/$tfile
2362         $LFS getstripe -c $DIR/$tdir/$tfile
2363         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2364                 error "two-stripe file doesn't have two stripes"
2365
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2367         $LFS getstripe -y $DIR/$tdir/$tfile
2368         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2369              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2370                 error "expected l_ost_idx: [02]$ not matched"
2371
2372         # make sure ost list has been cleared
2373         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2374         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2375                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2376         touch $DIR/$tdir/f3
2377         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2378 }
2379 run_test 27H "Set specific OSTs stripe"
2380
2381 test_27I() {
2382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2383         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2384         local pool=$TESTNAME
2385         local ostrange="1 1 1"
2386
2387         save_layout_restore_at_exit $MOUNT
2388         $LFS setstripe -c 2 -i 0 $MOUNT
2389         pool_add $pool || error "pool_add failed"
2390         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2391         test_mkdir $DIR/$tdir
2392         $LFS setstripe -p $pool $DIR/$tdir
2393         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2394         $LFS getstripe $DIR/$tdir/$tfile
2395 }
2396 run_test 27I "check that root dir striping does not break parent dir one"
2397
2398 # createtest also checks that device nodes are created and
2399 # then visible correctly (#2091)
2400 test_28() { # bug 2091
2401         test_mkdir $DIR/d28
2402         $CREATETEST $DIR/d28/ct || error "createtest failed"
2403 }
2404 run_test 28 "create/mknod/mkdir with bad file types ============"
2405
2406 test_29() {
2407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2408
2409         sync; sleep 1; sync # flush out any dirty pages from previous tests
2410         cancel_lru_locks
2411         test_mkdir $DIR/d29
2412         touch $DIR/d29/foo
2413         log 'first d29'
2414         ls -l $DIR/d29
2415
2416         declare -i LOCKCOUNTORIG=0
2417         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2418                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2419         done
2420         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2421
2422         declare -i LOCKUNUSEDCOUNTORIG=0
2423         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2424                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2425         done
2426
2427         log 'second d29'
2428         ls -l $DIR/d29
2429         log 'done'
2430
2431         declare -i LOCKCOUNTCURRENT=0
2432         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2433                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2434         done
2435
2436         declare -i LOCKUNUSEDCOUNTCURRENT=0
2437         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2438                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2439         done
2440
2441         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2442                 $LCTL set_param -n ldlm.dump_namespaces ""
2443                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2444                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2445                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2446                 return 2
2447         fi
2448         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2449                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2450                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2451                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2452                 return 3
2453         fi
2454 }
2455 run_test 29 "IT_GETATTR regression  ============================"
2456
2457 test_30a() { # was test_30
2458         cp $(which ls) $DIR || cp /bin/ls $DIR
2459         $DIR/ls / || error "Can't execute binary from lustre"
2460         rm $DIR/ls
2461 }
2462 run_test 30a "execute binary from Lustre (execve) =============="
2463
2464 test_30b() {
2465         cp `which ls` $DIR || cp /bin/ls $DIR
2466         chmod go+rx $DIR/ls
2467         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2468         rm $DIR/ls
2469 }
2470 run_test 30b "execute binary from Lustre as non-root ==========="
2471
2472 test_30c() { # b=22376
2473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2474
2475         cp `which ls` $DIR || cp /bin/ls $DIR
2476         chmod a-rw $DIR/ls
2477         cancel_lru_locks mdc
2478         cancel_lru_locks osc
2479         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2480         rm -f $DIR/ls
2481 }
2482 run_test 30c "execute binary from Lustre without read perms ===="
2483
2484 test_31a() {
2485         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2486         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2487 }
2488 run_test 31a "open-unlink file =================================="
2489
2490 test_31b() {
2491         touch $DIR/f31 || error "touch $DIR/f31 failed"
2492         ln $DIR/f31 $DIR/f31b || error "ln failed"
2493         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2494         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2495 }
2496 run_test 31b "unlink file with multiple links while open ======="
2497
2498 test_31c() {
2499         touch $DIR/f31 || error "touch $DIR/f31 failed"
2500         ln $DIR/f31 $DIR/f31c || error "ln failed"
2501         multiop_bg_pause $DIR/f31 O_uc ||
2502                 error "multiop_bg_pause for $DIR/f31 failed"
2503         MULTIPID=$!
2504         $MULTIOP $DIR/f31c Ouc
2505         kill -USR1 $MULTIPID
2506         wait $MULTIPID
2507 }
2508 run_test 31c "open-unlink file with multiple links ============="
2509
2510 test_31d() {
2511         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2512         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2513 }
2514 run_test 31d "remove of open directory ========================="
2515
2516 test_31e() { # bug 2904
2517         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2518 }
2519 run_test 31e "remove of open non-empty directory ==============="
2520
2521 test_31f() { # bug 4554
2522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2523
2524         set -vx
2525         test_mkdir $DIR/d31f
2526         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2527         cp /etc/hosts $DIR/d31f
2528         ls -l $DIR/d31f
2529         $LFS getstripe $DIR/d31f/hosts
2530         multiop_bg_pause $DIR/d31f D_c || return 1
2531         MULTIPID=$!
2532
2533         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2534         test_mkdir $DIR/d31f
2535         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2536         cp /etc/hosts $DIR/d31f
2537         ls -l $DIR/d31f
2538         $LFS getstripe $DIR/d31f/hosts
2539         multiop_bg_pause $DIR/d31f D_c || return 1
2540         MULTIPID2=$!
2541
2542         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2543         wait $MULTIPID || error "first opendir $MULTIPID failed"
2544
2545         sleep 6
2546
2547         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2548         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2549         set +vx
2550 }
2551 run_test 31f "remove of open directory with open-unlink file ==="
2552
2553 test_31g() {
2554         echo "-- cross directory link --"
2555         test_mkdir -c1 $DIR/${tdir}ga
2556         test_mkdir -c1 $DIR/${tdir}gb
2557         touch $DIR/${tdir}ga/f
2558         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2559         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2560         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2561         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2562         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2563 }
2564 run_test 31g "cross directory link==============="
2565
2566 test_31h() {
2567         echo "-- cross directory link --"
2568         test_mkdir -c1 $DIR/${tdir}
2569         test_mkdir -c1 $DIR/${tdir}/dir
2570         touch $DIR/${tdir}/f
2571         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2572         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2573         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2574         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2575         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2576 }
2577 run_test 31h "cross directory link under child==============="
2578
2579 test_31i() {
2580         echo "-- cross directory link --"
2581         test_mkdir -c1 $DIR/$tdir
2582         test_mkdir -c1 $DIR/$tdir/dir
2583         touch $DIR/$tdir/dir/f
2584         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2585         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2586         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2587         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2588         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2589 }
2590 run_test 31i "cross directory link under parent==============="
2591
2592 test_31j() {
2593         test_mkdir -c1 -p $DIR/$tdir
2594         test_mkdir -c1 -p $DIR/$tdir/dir1
2595         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2596         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2597         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2598         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2599         return 0
2600 }
2601 run_test 31j "link for directory==============="
2602
2603 test_31k() {
2604         test_mkdir -c1 -p $DIR/$tdir
2605         touch $DIR/$tdir/s
2606         touch $DIR/$tdir/exist
2607         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2608         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2609         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2610         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2611         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2612         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2613         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2614         return 0
2615 }
2616 run_test 31k "link to file: the same, non-existing, dir==============="
2617
2618 test_31m() {
2619         mkdir $DIR/d31m
2620         touch $DIR/d31m/s
2621         mkdir $DIR/d31m2
2622         touch $DIR/d31m2/exist
2623         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2624         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2625         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2626         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2627         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2628         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2629         return 0
2630 }
2631 run_test 31m "link to file: the same, non-existing, dir==============="
2632
2633 test_31n() {
2634         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2635         nlink=$(stat --format=%h $DIR/$tfile)
2636         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2637         local fd=$(free_fd)
2638         local cmd="exec $fd<$DIR/$tfile"
2639         eval $cmd
2640         cmd="exec $fd<&-"
2641         trap "eval $cmd" EXIT
2642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2643         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2644         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2645         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2646         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2647         eval $cmd
2648 }
2649 run_test 31n "check link count of unlinked file"
2650
2651 link_one() {
2652         local TEMPNAME=$(mktemp $1_XXXXXX)
2653         mlink $TEMPNAME $1 2> /dev/null &&
2654                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2655         munlink $TEMPNAME
2656 }
2657
2658 test_31o() { # LU-2901
2659         test_mkdir $DIR/$tdir
2660         for LOOP in $(seq 100); do
2661                 rm -f $DIR/$tdir/$tfile*
2662                 for THREAD in $(seq 8); do
2663                         link_one $DIR/$tdir/$tfile.$LOOP &
2664                 done
2665                 wait
2666                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2667                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2668                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2669                         break || true
2670         done
2671 }
2672 run_test 31o "duplicate hard links with same filename"
2673
2674 test_31p() {
2675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2676
2677         test_mkdir $DIR/$tdir
2678         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2679         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2680
2681         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2682                 error "open unlink test1 failed"
2683         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2684                 error "open unlink test2 failed"
2685
2686         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2687                 error "test1 still exists"
2688         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2689                 error "test2 still exists"
2690 }
2691 run_test 31p "remove of open striped directory"
2692
2693 cleanup_test32_mount() {
2694         local rc=0
2695         trap 0
2696         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2697         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2698         losetup -d $loopdev || true
2699         rm -rf $DIR/$tdir
2700         return $rc
2701 }
2702
2703 test_32a() {
2704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2705
2706         echo "== more mountpoints and symlinks ================="
2707         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2708         trap cleanup_test32_mount EXIT
2709         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2710         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2711                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2712         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2713                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2714         cleanup_test32_mount
2715 }
2716 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2717
2718 test_32b() {
2719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2720
2721         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2722         trap cleanup_test32_mount EXIT
2723         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2724         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2725                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2726         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2727                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2728         cleanup_test32_mount
2729 }
2730 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2731
2732 test_32c() {
2733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2734
2735         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2736         trap cleanup_test32_mount EXIT
2737         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2738         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2739                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2740         test_mkdir -p $DIR/$tdir/d2/test_dir
2741         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2742                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2743         cleanup_test32_mount
2744 }
2745 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2746
2747 test_32d() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749
2750         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2751         trap cleanup_test32_mount EXIT
2752         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2753         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2754                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2755         test_mkdir -p $DIR/$tdir/d2/test_dir
2756         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2757                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2758         cleanup_test32_mount
2759 }
2760 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2761
2762 test_32e() {
2763         rm -fr $DIR/$tdir
2764         test_mkdir -p $DIR/$tdir/tmp
2765         local tmp_dir=$DIR/$tdir/tmp
2766         ln -s $DIR/$tdir $tmp_dir/symlink11
2767         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2768         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2769         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2770 }
2771 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2772
2773 test_32f() {
2774         rm -fr $DIR/$tdir
2775         test_mkdir -p $DIR/$tdir/tmp
2776         local tmp_dir=$DIR/$tdir/tmp
2777         ln -s $DIR/$tdir $tmp_dir/symlink11
2778         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2779         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2780         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2781 }
2782 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2783
2784 test_32g() {
2785         local tmp_dir=$DIR/$tdir/tmp
2786         test_mkdir -p $tmp_dir
2787         test_mkdir $DIR/${tdir}2
2788         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2789         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2790         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2791         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2792         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2793         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2794 }
2795 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2796
2797 test_32h() {
2798         rm -fr $DIR/$tdir $DIR/${tdir}2
2799         tmp_dir=$DIR/$tdir/tmp
2800         test_mkdir -p $tmp_dir
2801         test_mkdir $DIR/${tdir}2
2802         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2803         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2804         ls $tmp_dir/symlink12 || error "listing symlink12"
2805         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2806 }
2807 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2808
2809 test_32i() {
2810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2811
2812         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2813         trap cleanup_test32_mount EXIT
2814         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2815         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2816                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2817         touch $DIR/$tdir/test_file
2818         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2819                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2820         cleanup_test32_mount
2821 }
2822 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2823
2824 test_32j() {
2825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2826
2827         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2828         trap cleanup_test32_mount EXIT
2829         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2830         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2831                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2832         touch $DIR/$tdir/test_file
2833         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2834                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2835         cleanup_test32_mount
2836 }
2837 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2838
2839 test_32k() {
2840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2841
2842         rm -fr $DIR/$tdir
2843         trap cleanup_test32_mount EXIT
2844         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2845         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2846                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2847         test_mkdir -p $DIR/$tdir/d2
2848         touch $DIR/$tdir/d2/test_file || error "touch failed"
2849         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2850                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2851         cleanup_test32_mount
2852 }
2853 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2854
2855 test_32l() {
2856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2857
2858         rm -fr $DIR/$tdir
2859         trap cleanup_test32_mount EXIT
2860         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2861         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2862                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2863         test_mkdir -p $DIR/$tdir/d2
2864         touch $DIR/$tdir/d2/test_file || error "touch failed"
2865         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2866                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2867         cleanup_test32_mount
2868 }
2869 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2870
2871 test_32m() {
2872         rm -fr $DIR/d32m
2873         test_mkdir -p $DIR/d32m/tmp
2874         TMP_DIR=$DIR/d32m/tmp
2875         ln -s $DIR $TMP_DIR/symlink11
2876         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2877         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2878                 error "symlink11 not a link"
2879         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2880                 error "symlink01 not a link"
2881 }
2882 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2883
2884 test_32n() {
2885         rm -fr $DIR/d32n
2886         test_mkdir -p $DIR/d32n/tmp
2887         TMP_DIR=$DIR/d32n/tmp
2888         ln -s $DIR $TMP_DIR/symlink11
2889         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2890         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2891         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2892 }
2893 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2894
2895 test_32o() {
2896         touch $DIR/$tfile
2897         test_mkdir -p $DIR/d32o/tmp
2898         TMP_DIR=$DIR/d32o/tmp
2899         ln -s $DIR/$tfile $TMP_DIR/symlink12
2900         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2901         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2902                 error "symlink12 not a link"
2903         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2904         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2905                 error "$DIR/d32o/tmp/symlink12 not file type"
2906         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2907                 error "$DIR/d32o/symlink02 not file type"
2908 }
2909 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2910
2911 test_32p() {
2912         log 32p_1
2913         rm -fr $DIR/d32p
2914         log 32p_2
2915         rm -f $DIR/$tfile
2916         log 32p_3
2917         touch $DIR/$tfile
2918         log 32p_4
2919         test_mkdir -p $DIR/d32p/tmp
2920         log 32p_5
2921         TMP_DIR=$DIR/d32p/tmp
2922         log 32p_6
2923         ln -s $DIR/$tfile $TMP_DIR/symlink12
2924         log 32p_7
2925         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2926         log 32p_8
2927         cat $DIR/d32p/tmp/symlink12 ||
2928                 error "Can't open $DIR/d32p/tmp/symlink12"
2929         log 32p_9
2930         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2931         log 32p_10
2932 }
2933 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2934
2935 test_32q() {
2936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2937
2938         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2939         trap cleanup_test32_mount EXIT
2940         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2941         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2942         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2943                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2944         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2945         cleanup_test32_mount
2946 }
2947 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2948
2949 test_32r() {
2950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2951
2952         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2953         trap cleanup_test32_mount EXIT
2954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2955         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2956         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2957                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2958         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2959         cleanup_test32_mount
2960 }
2961 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2962
2963 test_33aa() {
2964         rm -f $DIR/$tfile
2965         touch $DIR/$tfile
2966         chmod 444 $DIR/$tfile
2967         chown $RUNAS_ID $DIR/$tfile
2968         log 33_1
2969         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2970         log 33_2
2971 }
2972 run_test 33aa "write file with mode 444 (should return error)"
2973
2974 test_33a() {
2975         rm -fr $DIR/$tdir
2976         test_mkdir $DIR/$tdir
2977         chown $RUNAS_ID $DIR/$tdir
2978         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2979                 error "$RUNAS create $tdir/$tfile failed"
2980         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2981                 error "open RDWR" || true
2982 }
2983 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2984
2985 test_33b() {
2986         rm -fr $DIR/$tdir
2987         test_mkdir $DIR/$tdir
2988         chown $RUNAS_ID $DIR/$tdir
2989         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2990 }
2991 run_test 33b "test open file with malformed flags (No panic)"
2992
2993 test_33c() {
2994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2995         remote_ost_nodsh && skip "remote OST with nodsh"
2996
2997         local ostnum
2998         local ostname
2999         local write_bytes
3000         local all_zeros
3001
3002         all_zeros=:
3003         rm -fr $DIR/$tdir
3004         test_mkdir $DIR/$tdir
3005         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3006
3007         sync
3008         for ostnum in $(seq $OSTCOUNT); do
3009                 # test-framework's OST numbering is one-based, while Lustre's
3010                 # is zero-based
3011                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3012                 # Parsing llobdstat's output sucks; we could grep the /proc
3013                 # path, but that's likely to not be as portable as using the
3014                 # llobdstat utility.  So we parse lctl output instead.
3015                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3016                         obdfilter/$ostname/stats |
3017                         awk '/^write_bytes/ {print $7}' )
3018                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3019                 if (( ${write_bytes:-0} > 0 ))
3020                 then
3021                         all_zeros=false
3022                         break;
3023                 fi
3024         done
3025
3026         $all_zeros || return 0
3027
3028         # Write four bytes
3029         echo foo > $DIR/$tdir/bar
3030         # Really write them
3031         sync
3032
3033         # Total up write_bytes after writing.  We'd better find non-zeros.
3034         for ostnum in $(seq $OSTCOUNT); do
3035                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3036                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3037                         obdfilter/$ostname/stats |
3038                         awk '/^write_bytes/ {print $7}' )
3039                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3040                 if (( ${write_bytes:-0} > 0 ))
3041                 then
3042                         all_zeros=false
3043                         break;
3044                 fi
3045         done
3046
3047         if $all_zeros
3048         then
3049                 for ostnum in $(seq $OSTCOUNT); do
3050                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3051                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3052                         do_facet ost$ostnum lctl get_param -n \
3053                                 obdfilter/$ostname/stats
3054                 done
3055                 error "OST not keeping write_bytes stats (b22312)"
3056         fi
3057 }
3058 run_test 33c "test llobdstat and write_bytes"
3059
3060 test_33d() {
3061         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3063
3064         local MDTIDX=1
3065         local remote_dir=$DIR/$tdir/remote_dir
3066
3067         test_mkdir $DIR/$tdir
3068         $LFS mkdir -i $MDTIDX $remote_dir ||
3069                 error "create remote directory failed"
3070
3071         touch $remote_dir/$tfile
3072         chmod 444 $remote_dir/$tfile
3073         chown $RUNAS_ID $remote_dir/$tfile
3074
3075         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3076
3077         chown $RUNAS_ID $remote_dir
3078         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3079                                         error "create" || true
3080         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3081                                     error "open RDWR" || true
3082         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3083 }
3084 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3085
3086 test_33e() {
3087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3088
3089         mkdir $DIR/$tdir
3090
3091         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3092         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3093         mkdir $DIR/$tdir/local_dir
3094
3095         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3096         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3097         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3098
3099         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3100                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3101
3102         rmdir $DIR/$tdir/* || error "rmdir failed"
3103
3104         umask 777
3105         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3106         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3107         mkdir $DIR/$tdir/local_dir
3108
3109         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3110         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3111         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3112
3113         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3114                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3115
3116         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3117
3118         umask 000
3119         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3120         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3121         mkdir $DIR/$tdir/local_dir
3122
3123         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3124         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3125         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3126
3127         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3128                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3129 }
3130 run_test 33e "mkdir and striped directory should have same mode"
3131
3132 cleanup_33f() {
3133         trap 0
3134         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3135 }
3136
3137 test_33f() {
3138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3139         remote_mds_nodsh && skip "remote MDS with nodsh"
3140
3141         mkdir $DIR/$tdir
3142         chmod go+rwx $DIR/$tdir
3143         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3144         trap cleanup_33f EXIT
3145
3146         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3147                 error "cannot create striped directory"
3148
3149         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3150                 error "cannot create files in striped directory"
3151
3152         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3153                 error "cannot remove files in striped directory"
3154
3155         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3156                 error "cannot remove striped directory"
3157
3158         cleanup_33f
3159 }
3160 run_test 33f "nonroot user can create, access, and remove a striped directory"
3161
3162 test_33g() {
3163         mkdir -p $DIR/$tdir/dir2
3164
3165         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3166         echo $err
3167         [[ $err =~ "exists" ]] || error "Not exists error"
3168 }
3169 run_test 33g "nonroot user create already existing root created file"
3170
3171 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3172 test_34a() {
3173         rm -f $DIR/f34
3174         $MCREATE $DIR/f34 || error "mcreate failed"
3175         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3176                 error "getstripe failed"
3177         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3178         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3179                 error "getstripe failed"
3180         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3181                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3182 }
3183 run_test 34a "truncate file that has not been opened ==========="
3184
3185 test_34b() {
3186         [ ! -f $DIR/f34 ] && test_34a
3187         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3188                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3189         $OPENFILE -f O_RDONLY $DIR/f34
3190         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3191                 error "getstripe failed"
3192         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3193                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3194 }
3195 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3196
3197 test_34c() {
3198         [ ! -f $DIR/f34 ] && test_34a
3199         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3200                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3201         $OPENFILE -f O_RDWR $DIR/f34
3202         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3203                 error "$LFS getstripe failed"
3204         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3205                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3206 }
3207 run_test 34c "O_RDWR opening file-with-size works =============="
3208
3209 test_34d() {
3210         [ ! -f $DIR/f34 ] && test_34a
3211         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3212                 error "dd failed"
3213         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3214                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3215         rm $DIR/f34
3216 }
3217 run_test 34d "write to sparse file ============================="
3218
3219 test_34e() {
3220         rm -f $DIR/f34e
3221         $MCREATE $DIR/f34e || error "mcreate failed"
3222         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3223         $CHECKSTAT -s 1000 $DIR/f34e ||
3224                 error "Size of $DIR/f34e not equal to 1000 bytes"
3225         $OPENFILE -f O_RDWR $DIR/f34e
3226         $CHECKSTAT -s 1000 $DIR/f34e ||
3227                 error "Size of $DIR/f34e not equal to 1000 bytes"
3228 }
3229 run_test 34e "create objects, some with size and some without =="
3230
3231 test_34f() { # bug 6242, 6243
3232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3233
3234         SIZE34F=48000
3235         rm -f $DIR/f34f
3236         $MCREATE $DIR/f34f || error "mcreate failed"
3237         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3238         dd if=$DIR/f34f of=$TMP/f34f
3239         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3240         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3241         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3242         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3243         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3244 }
3245 run_test 34f "read from a file with no objects until EOF ======="
3246
3247 test_34g() {
3248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3249
3250         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3251                 error "dd failed"
3252         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3253         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3254                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3255         cancel_lru_locks osc
3256         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3257                 error "wrong size after lock cancel"
3258
3259         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3260         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3261                 error "expanding truncate failed"
3262         cancel_lru_locks osc
3263         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3264                 error "wrong expanded size after lock cancel"
3265 }
3266 run_test 34g "truncate long file ==============================="
3267
3268 test_34h() {
3269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3270
3271         local gid=10
3272         local sz=1000
3273
3274         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3275         sync # Flush the cache so that multiop below does not block on cache
3276              # flush when getting the group lock
3277         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3278         MULTIPID=$!
3279
3280         # Since just timed wait is not good enough, let's do a sync write
3281         # that way we are sure enough time for a roundtrip + processing
3282         # passed + 2 seconds of extra margin.
3283         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3284         rm $DIR/${tfile}-1
3285         sleep 2
3286
3287         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3288                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3289                 kill -9 $MULTIPID
3290         fi
3291         wait $MULTIPID
3292         local nsz=`stat -c %s $DIR/$tfile`
3293         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3294 }
3295 run_test 34h "ftruncate file under grouplock should not block"
3296
3297 test_35a() {
3298         cp /bin/sh $DIR/f35a
3299         chmod 444 $DIR/f35a
3300         chown $RUNAS_ID $DIR/f35a
3301         $RUNAS $DIR/f35a && error || true
3302         rm $DIR/f35a
3303 }
3304 run_test 35a "exec file with mode 444 (should return and not leak)"
3305
3306 test_36a() {
3307         rm -f $DIR/f36
3308         utime $DIR/f36 || error "utime failed for MDS"
3309 }
3310 run_test 36a "MDS utime check (mknod, utime)"
3311
3312 test_36b() {
3313         echo "" > $DIR/f36
3314         utime $DIR/f36 || error "utime failed for OST"
3315 }
3316 run_test 36b "OST utime check (open, utime)"
3317
3318 test_36c() {
3319         rm -f $DIR/d36/f36
3320         test_mkdir $DIR/d36
3321         chown $RUNAS_ID $DIR/d36
3322         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3323 }
3324 run_test 36c "non-root MDS utime check (mknod, utime)"
3325
3326 test_36d() {
3327         [ ! -d $DIR/d36 ] && test_36c
3328         echo "" > $DIR/d36/f36
3329         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3330 }
3331 run_test 36d "non-root OST utime check (open, utime)"
3332
3333 test_36e() {
3334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3335
3336         test_mkdir $DIR/$tdir
3337         touch $DIR/$tdir/$tfile
3338         $RUNAS utime $DIR/$tdir/$tfile &&
3339                 error "utime worked, expected failure" || true
3340 }
3341 run_test 36e "utime on non-owned file (should return error)"
3342
3343 subr_36fh() {
3344         local fl="$1"
3345         local LANG_SAVE=$LANG
3346         local LC_LANG_SAVE=$LC_LANG
3347         export LANG=C LC_LANG=C # for date language
3348
3349         DATESTR="Dec 20  2000"
3350         test_mkdir $DIR/$tdir
3351         lctl set_param fail_loc=$fl
3352         date; date +%s
3353         cp /etc/hosts $DIR/$tdir/$tfile
3354         sync & # write RPC generated with "current" inode timestamp, but delayed
3355         sleep 1
3356         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3357         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3358         cancel_lru_locks $OSC
3359         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3360         date; date +%s
3361         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3362                 echo "BEFORE: $LS_BEFORE" && \
3363                 echo "AFTER : $LS_AFTER" && \
3364                 echo "WANT  : $DATESTR" && \
3365                 error "$DIR/$tdir/$tfile timestamps changed" || true
3366
3367         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3368 }
3369
3370 test_36f() {
3371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3372
3373         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3374         subr_36fh "0x80000214"
3375 }
3376 run_test 36f "utime on file racing with OST BRW write =========="
3377
3378 test_36g() {
3379         remote_ost_nodsh && skip "remote OST with nodsh"
3380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3381         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3382                 skip "Need MDS version at least 2.12.51"
3383
3384         local fmd_max_age
3385         local fmd
3386         local facet="ost1"
3387         local tgt="obdfilter"
3388
3389         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3390
3391         test_mkdir $DIR/$tdir
3392         fmd_max_age=$(do_facet $facet \
3393                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3394                 head -n 1")
3395
3396         echo "FMD max age: ${fmd_max_age}s"
3397         touch $DIR/$tdir/$tfile
3398         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3399                 gawk '{cnt=cnt+$1}  END{print cnt}')
3400         echo "FMD before: $fmd"
3401         [[ $fmd == 0 ]] &&
3402                 error "FMD wasn't create by touch"
3403         sleep $((fmd_max_age + 12))
3404         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3405                 gawk '{cnt=cnt+$1}  END{print cnt}')
3406         echo "FMD after: $fmd"
3407         [[ $fmd == 0 ]] ||
3408                 error "FMD wasn't expired by ping"
3409 }
3410 run_test 36g "FMD cache expiry ====================="
3411
3412 test_36h() {
3413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3414
3415         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3416         subr_36fh "0x80000227"
3417 }
3418 run_test 36h "utime on file racing with OST BRW write =========="
3419
3420 test_36i() {
3421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3422
3423         test_mkdir $DIR/$tdir
3424         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3425
3426         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3427         local new_mtime=$((mtime + 200))
3428
3429         #change Modify time of striped dir
3430         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3431                         error "change mtime failed"
3432
3433         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3434
3435         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3436 }
3437 run_test 36i "change mtime on striped directory"
3438
3439 # test_37 - duplicate with tests 32q 32r
3440
3441 test_38() {
3442         local file=$DIR/$tfile
3443         touch $file
3444         openfile -f O_DIRECTORY $file
3445         local RC=$?
3446         local ENOTDIR=20
3447         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3448         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3449 }
3450 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3451
3452 test_39a() { # was test_39
3453         touch $DIR/$tfile
3454         touch $DIR/${tfile}2
3455 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3456 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3457 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3458         sleep 2
3459         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3460         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3461                 echo "mtime"
3462                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3463                 echo "atime"
3464                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3465                 echo "ctime"
3466                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3467                 error "O_TRUNC didn't change timestamps"
3468         fi
3469 }
3470 run_test 39a "mtime changed on create"
3471
3472 test_39b() {
3473         test_mkdir -c1 $DIR/$tdir
3474         cp -p /etc/passwd $DIR/$tdir/fopen
3475         cp -p /etc/passwd $DIR/$tdir/flink
3476         cp -p /etc/passwd $DIR/$tdir/funlink
3477         cp -p /etc/passwd $DIR/$tdir/frename
3478         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3479
3480         sleep 1
3481         echo "aaaaaa" >> $DIR/$tdir/fopen
3482         echo "aaaaaa" >> $DIR/$tdir/flink
3483         echo "aaaaaa" >> $DIR/$tdir/funlink
3484         echo "aaaaaa" >> $DIR/$tdir/frename
3485
3486         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3487         local link_new=`stat -c %Y $DIR/$tdir/flink`
3488         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3489         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3490
3491         cat $DIR/$tdir/fopen > /dev/null
3492         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3493         rm -f $DIR/$tdir/funlink2
3494         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3495
3496         for (( i=0; i < 2; i++ )) ; do
3497                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3498                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3499                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3500                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3501
3502                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3503                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3504                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3505                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3506
3507                 cancel_lru_locks $OSC
3508                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3509         done
3510 }
3511 run_test 39b "mtime change on open, link, unlink, rename  ======"
3512
3513 # this should be set to past
3514 TEST_39_MTIME=`date -d "1 year ago" +%s`
3515
3516 # bug 11063
3517 test_39c() {
3518         touch $DIR1/$tfile
3519         sleep 2
3520         local mtime0=`stat -c %Y $DIR1/$tfile`
3521
3522         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3523         local mtime1=`stat -c %Y $DIR1/$tfile`
3524         [ "$mtime1" = $TEST_39_MTIME ] || \
3525                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3526
3527         local d1=`date +%s`
3528         echo hello >> $DIR1/$tfile
3529         local d2=`date +%s`
3530         local mtime2=`stat -c %Y $DIR1/$tfile`
3531         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3532                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3533
3534         mv $DIR1/$tfile $DIR1/$tfile-1
3535
3536         for (( i=0; i < 2; i++ )) ; do
3537                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3538                 [ "$mtime2" = "$mtime3" ] || \
3539                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3540
3541                 cancel_lru_locks $OSC
3542                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3543         done
3544 }
3545 run_test 39c "mtime change on rename ==========================="
3546
3547 # bug 21114
3548 test_39d() {
3549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3550
3551         touch $DIR1/$tfile
3552         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3553
3554         for (( i=0; i < 2; i++ )) ; do
3555                 local mtime=`stat -c %Y $DIR1/$tfile`
3556                 [ $mtime = $TEST_39_MTIME ] || \
3557                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3558
3559                 cancel_lru_locks $OSC
3560                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3561         done
3562 }
3563 run_test 39d "create, utime, stat =============================="
3564
3565 # bug 21114
3566 test_39e() {
3567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3568
3569         touch $DIR1/$tfile
3570         local mtime1=`stat -c %Y $DIR1/$tfile`
3571
3572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3573
3574         for (( i=0; i < 2; i++ )) ; do
3575                 local mtime2=`stat -c %Y $DIR1/$tfile`
3576                 [ $mtime2 = $TEST_39_MTIME ] || \
3577                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3578
3579                 cancel_lru_locks $OSC
3580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3581         done
3582 }
3583 run_test 39e "create, stat, utime, stat ========================"
3584
3585 # bug 21114
3586 test_39f() {
3587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3588
3589         touch $DIR1/$tfile
3590         mtime1=`stat -c %Y $DIR1/$tfile`
3591
3592         sleep 2
3593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3594
3595         for (( i=0; i < 2; i++ )) ; do
3596                 local mtime2=`stat -c %Y $DIR1/$tfile`
3597                 [ $mtime2 = $TEST_39_MTIME ] || \
3598                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3599
3600                 cancel_lru_locks $OSC
3601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3602         done
3603 }
3604 run_test 39f "create, stat, sleep, utime, stat ================="
3605
3606 # bug 11063
3607 test_39g() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         echo hello >> $DIR1/$tfile
3611         local mtime1=`stat -c %Y $DIR1/$tfile`
3612
3613         sleep 2
3614         chmod o+r $DIR1/$tfile
3615
3616         for (( i=0; i < 2; i++ )) ; do
3617                 local mtime2=`stat -c %Y $DIR1/$tfile`
3618                 [ "$mtime1" = "$mtime2" ] || \
3619                         error "lost mtime: $mtime2, should be $mtime1"
3620
3621                 cancel_lru_locks $OSC
3622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3623         done
3624 }
3625 run_test 39g "write, chmod, stat ==============================="
3626
3627 # bug 11063
3628 test_39h() {
3629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3630
3631         touch $DIR1/$tfile
3632         sleep 1
3633
3634         local d1=`date`
3635         echo hello >> $DIR1/$tfile
3636         local mtime1=`stat -c %Y $DIR1/$tfile`
3637
3638         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3639         local d2=`date`
3640         if [ "$d1" != "$d2" ]; then
3641                 echo "write and touch not within one second"
3642         else
3643                 for (( i=0; i < 2; i++ )) ; do
3644                         local mtime2=`stat -c %Y $DIR1/$tfile`
3645                         [ "$mtime2" = $TEST_39_MTIME ] || \
3646                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3647
3648                         cancel_lru_locks $OSC
3649                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3650                 done
3651         fi
3652 }
3653 run_test 39h "write, utime within one second, stat ============="
3654
3655 test_39i() {
3656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3657
3658         touch $DIR1/$tfile
3659         sleep 1
3660
3661         echo hello >> $DIR1/$tfile
3662         local mtime1=`stat -c %Y $DIR1/$tfile`
3663
3664         mv $DIR1/$tfile $DIR1/$tfile-1
3665
3666         for (( i=0; i < 2; i++ )) ; do
3667                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3668
3669                 [ "$mtime1" = "$mtime2" ] || \
3670                         error "lost mtime: $mtime2, should be $mtime1"
3671
3672                 cancel_lru_locks $OSC
3673                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3674         done
3675 }
3676 run_test 39i "write, rename, stat =============================="
3677
3678 test_39j() {
3679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3680
3681         start_full_debug_logging
3682         touch $DIR1/$tfile
3683         sleep 1
3684
3685         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3686         lctl set_param fail_loc=0x80000412
3687         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3688                 error "multiop failed"
3689         local multipid=$!
3690         local mtime1=`stat -c %Y $DIR1/$tfile`
3691
3692         mv $DIR1/$tfile $DIR1/$tfile-1
3693
3694         kill -USR1 $multipid
3695         wait $multipid || error "multiop close failed"
3696
3697         for (( i=0; i < 2; i++ )) ; do
3698                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3699                 [ "$mtime1" = "$mtime2" ] ||
3700                         error "mtime is lost on close: $mtime2, " \
3701                               "should be $mtime1"
3702
3703                 cancel_lru_locks $OSC
3704                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3705         done
3706         lctl set_param fail_loc=0
3707         stop_full_debug_logging
3708 }
3709 run_test 39j "write, rename, close, stat ======================="
3710
3711 test_39k() {
3712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3713
3714         touch $DIR1/$tfile
3715         sleep 1
3716
3717         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3718         local multipid=$!
3719         local mtime1=`stat -c %Y $DIR1/$tfile`
3720
3721         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3722
3723         kill -USR1 $multipid
3724         wait $multipid || error "multiop close failed"
3725
3726         for (( i=0; i < 2; i++ )) ; do
3727                 local mtime2=`stat -c %Y $DIR1/$tfile`
3728
3729                 [ "$mtime2" = $TEST_39_MTIME ] || \
3730                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3731
3732                 cancel_lru_locks osc
3733                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3734         done
3735 }
3736 run_test 39k "write, utime, close, stat ========================"
3737
3738 # this should be set to future
3739 TEST_39_ATIME=`date -d "1 year" +%s`
3740
3741 test_39l() {
3742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3743         remote_mds_nodsh && skip "remote MDS with nodsh"
3744
3745         local atime_diff=$(do_facet $SINGLEMDS \
3746                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3747         rm -rf $DIR/$tdir
3748         mkdir -p $DIR/$tdir
3749
3750         # test setting directory atime to future
3751         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3752         local atime=$(stat -c %X $DIR/$tdir)
3753         [ "$atime" = $TEST_39_ATIME ] ||
3754                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3755
3756         # test setting directory atime from future to now
3757         local now=$(date +%s)
3758         touch -a -d @$now $DIR/$tdir
3759
3760         atime=$(stat -c %X $DIR/$tdir)
3761         [ "$atime" -eq "$now"  ] ||
3762                 error "atime is not updated from future: $atime, $now"
3763
3764         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3765         sleep 3
3766
3767         # test setting directory atime when now > dir atime + atime_diff
3768         local d1=$(date +%s)
3769         ls $DIR/$tdir
3770         local d2=$(date +%s)
3771         cancel_lru_locks mdc
3772         atime=$(stat -c %X $DIR/$tdir)
3773         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3774                 error "atime is not updated  : $atime, should be $d2"
3775
3776         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3777         sleep 3
3778
3779         # test not setting directory atime when now < dir atime + atime_diff
3780         ls $DIR/$tdir
3781         cancel_lru_locks mdc
3782         atime=$(stat -c %X $DIR/$tdir)
3783         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3784                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3785
3786         do_facet $SINGLEMDS \
3787                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3788 }
3789 run_test 39l "directory atime update ==========================="
3790
3791 test_39m() {
3792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3793
3794         touch $DIR1/$tfile
3795         sleep 2
3796         local far_past_mtime=$(date -d "May 29 1953" +%s)
3797         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3798
3799         touch -m -d @$far_past_mtime $DIR1/$tfile
3800         touch -a -d @$far_past_atime $DIR1/$tfile
3801
3802         for (( i=0; i < 2; i++ )) ; do
3803                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3804                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3805                         error "atime or mtime set incorrectly"
3806
3807                 cancel_lru_locks $OSC
3808                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3809         done
3810 }
3811 run_test 39m "test atime and mtime before 1970"
3812
3813 test_39n() { # LU-3832
3814         remote_mds_nodsh && skip "remote MDS with nodsh"
3815
3816         local atime_diff=$(do_facet $SINGLEMDS \
3817                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3818         local atime0
3819         local atime1
3820         local atime2
3821
3822         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3823
3824         rm -rf $DIR/$tfile
3825         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3826         atime0=$(stat -c %X $DIR/$tfile)
3827
3828         sleep 5
3829         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3830         atime1=$(stat -c %X $DIR/$tfile)
3831
3832         sleep 5
3833         cancel_lru_locks mdc
3834         cancel_lru_locks osc
3835         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3836         atime2=$(stat -c %X $DIR/$tfile)
3837
3838         do_facet $SINGLEMDS \
3839                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3840
3841         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3842         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3843 }
3844 run_test 39n "check that O_NOATIME is honored"
3845
3846 test_39o() {
3847         TESTDIR=$DIR/$tdir/$tfile
3848         [ -e $TESTDIR ] && rm -rf $TESTDIR
3849         mkdir -p $TESTDIR
3850         cd $TESTDIR
3851         links1=2
3852         ls
3853         mkdir a b
3854         ls
3855         links2=$(stat -c %h .)
3856         [ $(($links1 + 2)) != $links2 ] &&
3857                 error "wrong links count $(($links1 + 2)) != $links2"
3858         rmdir b
3859         links3=$(stat -c %h .)
3860         [ $(($links1 + 1)) != $links3 ] &&
3861                 error "wrong links count $links1 != $links3"
3862         return 0
3863 }
3864 run_test 39o "directory cached attributes updated after create"
3865
3866 test_39p() {
3867         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3868
3869         local MDTIDX=1
3870         TESTDIR=$DIR/$tdir/$tdir
3871         [ -e $TESTDIR ] && rm -rf $TESTDIR
3872         test_mkdir -p $TESTDIR
3873         cd $TESTDIR
3874         links1=2
3875         ls
3876         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3877         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3878         ls
3879         links2=$(stat -c %h .)
3880         [ $(($links1 + 2)) != $links2 ] &&
3881                 error "wrong links count $(($links1 + 2)) != $links2"
3882         rmdir remote_dir2
3883         links3=$(stat -c %h .)
3884         [ $(($links1 + 1)) != $links3 ] &&
3885                 error "wrong links count $links1 != $links3"
3886         return 0
3887 }
3888 run_test 39p "remote directory cached attributes updated after create ========"
3889
3890
3891 test_39q() { # LU-8041
3892         local testdir=$DIR/$tdir
3893         mkdir -p $testdir
3894         multiop_bg_pause $testdir D_c || error "multiop failed"
3895         local multipid=$!
3896         cancel_lru_locks mdc
3897         kill -USR1 $multipid
3898         local atime=$(stat -c %X $testdir)
3899         [ "$atime" -ne 0 ] || error "atime is zero"
3900 }
3901 run_test 39q "close won't zero out atime"
3902
3903 test_40() {
3904         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3905         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3906                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3907         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3908                 error "$tfile is not 4096 bytes in size"
3909 }
3910 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3911
3912 test_41() {
3913         # bug 1553
3914         small_write $DIR/f41 18
3915 }
3916 run_test 41 "test small file write + fstat ====================="
3917
3918 count_ost_writes() {
3919         lctl get_param -n ${OSC}.*.stats |
3920                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3921                         END { printf("%0.0f", writes) }'
3922 }
3923
3924 # decent default
3925 WRITEBACK_SAVE=500
3926 DIRTY_RATIO_SAVE=40
3927 MAX_DIRTY_RATIO=50
3928 BG_DIRTY_RATIO_SAVE=10
3929 MAX_BG_DIRTY_RATIO=25
3930
3931 start_writeback() {
3932         trap 0
3933         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3934         # dirty_ratio, dirty_background_ratio
3935         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3936                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3937                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3938                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3939         else
3940                 # if file not here, we are a 2.4 kernel
3941                 kill -CONT `pidof kupdated`
3942         fi
3943 }
3944
3945 stop_writeback() {
3946         # setup the trap first, so someone cannot exit the test at the
3947         # exact wrong time and mess up a machine
3948         trap start_writeback EXIT
3949         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3950         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3951                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3952                 sysctl -w vm.dirty_writeback_centisecs=0
3953                 sysctl -w vm.dirty_writeback_centisecs=0
3954                 # save and increase /proc/sys/vm/dirty_ratio
3955                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3956                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3957                 # save and increase /proc/sys/vm/dirty_background_ratio
3958                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3959                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3960         else
3961                 # if file not here, we are a 2.4 kernel
3962                 kill -STOP `pidof kupdated`
3963         fi
3964 }
3965
3966 # ensure that all stripes have some grant before we test client-side cache
3967 setup_test42() {
3968         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3969                 dd if=/dev/zero of=$i bs=4k count=1
3970                 rm $i
3971         done
3972 }
3973
3974 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3975 # file truncation, and file removal.
3976 test_42a() {
3977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3978
3979         setup_test42
3980         cancel_lru_locks $OSC
3981         stop_writeback
3982         sync; sleep 1; sync # just to be safe
3983         BEFOREWRITES=`count_ost_writes`
3984         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3985         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3986         AFTERWRITES=`count_ost_writes`
3987         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3988                 error "$BEFOREWRITES < $AFTERWRITES"
3989         start_writeback
3990 }
3991 run_test 42a "ensure that we don't flush on close"
3992
3993 test_42b() {
3994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3995
3996         setup_test42
3997         cancel_lru_locks $OSC
3998         stop_writeback
3999         sync
4000         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4001         BEFOREWRITES=$(count_ost_writes)
4002         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4003         AFTERWRITES=$(count_ost_writes)
4004         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4005                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4006         fi
4007         BEFOREWRITES=$(count_ost_writes)
4008         sync || error "sync: $?"
4009         AFTERWRITES=$(count_ost_writes)
4010         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4011                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4012         fi
4013         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4014         start_writeback
4015         return 0
4016 }
4017 run_test 42b "test destroy of file with cached dirty data ======"
4018
4019 # if these tests just want to test the effect of truncation,
4020 # they have to be very careful.  consider:
4021 # - the first open gets a {0,EOF}PR lock
4022 # - the first write conflicts and gets a {0, count-1}PW
4023 # - the rest of the writes are under {count,EOF}PW
4024 # - the open for truncate tries to match a {0,EOF}PR
4025 #   for the filesize and cancels the PWs.
4026 # any number of fixes (don't get {0,EOF} on open, match
4027 # composite locks, do smarter file size management) fix
4028 # this, but for now we want these tests to verify that
4029 # the cancellation with truncate intent works, so we
4030 # start the file with a full-file pw lock to match against
4031 # until the truncate.
4032 trunc_test() {
4033         test=$1
4034         file=$DIR/$test
4035         offset=$2
4036         cancel_lru_locks $OSC
4037         stop_writeback
4038         # prime the file with 0,EOF PW to match
4039         touch $file
4040         $TRUNCATE $file 0
4041         sync; sync
4042         # now the real test..
4043         dd if=/dev/zero of=$file bs=1024 count=100
4044         BEFOREWRITES=`count_ost_writes`
4045         $TRUNCATE $file $offset
4046         cancel_lru_locks $OSC
4047         AFTERWRITES=`count_ost_writes`
4048         start_writeback
4049 }
4050
4051 test_42c() {
4052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4053
4054         trunc_test 42c 1024
4055         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4056                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4057         rm $file
4058 }
4059 run_test 42c "test partial truncate of file with cached dirty data"
4060
4061 test_42d() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         trunc_test 42d 0
4065         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4066                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4067         rm $file
4068 }
4069 run_test 42d "test complete truncate of file with cached dirty data"
4070
4071 test_42e() { # bug22074
4072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4073
4074         local TDIR=$DIR/${tdir}e
4075         local pages=16 # hardcoded 16 pages, don't change it.
4076         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4077         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4078         local max_dirty_mb
4079         local warmup_files
4080
4081         test_mkdir $DIR/${tdir}e
4082         $LFS setstripe -c 1 $TDIR
4083         createmany -o $TDIR/f $files
4084
4085         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4086
4087         # we assume that with $OSTCOUNT files, at least one of them will
4088         # be allocated on OST0.
4089         warmup_files=$((OSTCOUNT * max_dirty_mb))
4090         createmany -o $TDIR/w $warmup_files
4091
4092         # write a large amount of data into one file and sync, to get good
4093         # avail_grant number from OST.
4094         for ((i=0; i<$warmup_files; i++)); do
4095                 idx=$($LFS getstripe -i $TDIR/w$i)
4096                 [ $idx -ne 0 ] && continue
4097                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4098                 break
4099         done
4100         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4101         sync
4102         $LCTL get_param $proc_osc0/cur_dirty_bytes
4103         $LCTL get_param $proc_osc0/cur_grant_bytes
4104
4105         # create as much dirty pages as we can while not to trigger the actual
4106         # RPCs directly. but depends on the env, VFS may trigger flush during this
4107         # period, hopefully we are good.
4108         for ((i=0; i<$warmup_files; i++)); do
4109                 idx=$($LFS getstripe -i $TDIR/w$i)
4110                 [ $idx -ne 0 ] && continue
4111                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4112         done
4113         $LCTL get_param $proc_osc0/cur_dirty_bytes
4114         $LCTL get_param $proc_osc0/cur_grant_bytes
4115
4116         # perform the real test
4117         $LCTL set_param $proc_osc0/rpc_stats 0
4118         for ((;i<$files; i++)); do
4119                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4120                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4121         done
4122         sync
4123         $LCTL get_param $proc_osc0/rpc_stats
4124
4125         local percent=0
4126         local have_ppr=false
4127         $LCTL get_param $proc_osc0/rpc_stats |
4128                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4129                         # skip lines until we are at the RPC histogram data
4130                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4131                         $have_ppr || continue
4132
4133                         # we only want the percent stat for < 16 pages
4134                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4135
4136                         percent=$((percent + WPCT))
4137                         if [[ $percent -gt 15 ]]; then
4138                                 error "less than 16-pages write RPCs" \
4139                                       "$percent% > 15%"
4140                                 break
4141                         fi
4142                 done
4143         rm -rf $TDIR
4144 }
4145 run_test 42e "verify sub-RPC writes are not done synchronously"
4146
4147 test_43A() { # was test_43
4148         test_mkdir $DIR/$tdir
4149         cp -p /bin/ls $DIR/$tdir/$tfile
4150         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4151         pid=$!
4152         # give multiop a chance to open
4153         sleep 1
4154
4155         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4156         kill -USR1 $pid
4157 }
4158 run_test 43A "execution of file opened for write should return -ETXTBSY"
4159
4160 test_43a() {
4161         test_mkdir $DIR/$tdir
4162         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4163         $DIR/$tdir/sleep 60 &
4164         SLEEP_PID=$!
4165         # Make sure exec of $tdir/sleep wins race with truncate
4166         sleep 1
4167         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4168         kill $SLEEP_PID
4169 }
4170 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4171
4172 test_43b() {
4173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4174
4175         test_mkdir $DIR/$tdir
4176         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4177         $DIR/$tdir/sleep 60 &
4178         SLEEP_PID=$!
4179         # Make sure exec of $tdir/sleep wins race with truncate
4180         sleep 1
4181         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4182         kill $SLEEP_PID
4183 }
4184 run_test 43b "truncate of file being executed should return -ETXTBSY"
4185
4186 test_43c() {
4187         local testdir="$DIR/$tdir"
4188         test_mkdir $testdir
4189         cp $SHELL $testdir/
4190         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4191                 ( cd $testdir && md5sum -c )
4192 }
4193 run_test 43c "md5sum of copy into lustre"
4194
4195 test_44A() { # was test_44
4196         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4197
4198         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4199         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4200 }
4201 run_test 44A "zero length read from a sparse stripe"
4202
4203 test_44a() {
4204         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4205                 awk '{ print $2 }')
4206         [ -z "$nstripe" ] && skip "can't get stripe info"
4207         [[ $nstripe -gt $OSTCOUNT ]] &&
4208                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4209
4210         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4211                 awk '{ print $2 }')
4212         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4213                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4214                         awk '{ print $2 }')
4215         fi
4216
4217         OFFSETS="0 $((stride/2)) $((stride-1))"
4218         for offset in $OFFSETS; do
4219                 for i in $(seq 0 $((nstripe-1))); do
4220                         local GLOBALOFFSETS=""
4221                         # size in Bytes
4222                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4223                         local myfn=$DIR/d44a-$size
4224                         echo "--------writing $myfn at $size"
4225                         ll_sparseness_write $myfn $size ||
4226                                 error "ll_sparseness_write"
4227                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4228                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4229                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4230
4231                         for j in $(seq 0 $((nstripe-1))); do
4232                                 # size in Bytes
4233                                 size=$((((j + $nstripe )*$stride + $offset)))
4234                                 ll_sparseness_write $myfn $size ||
4235                                         error "ll_sparseness_write"
4236                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4237                         done
4238                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4239                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4240                         rm -f $myfn
4241                 done
4242         done
4243 }
4244 run_test 44a "test sparse pwrite ==============================="
4245
4246 dirty_osc_total() {
4247         tot=0
4248         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4249                 tot=$(($tot + $d))
4250         done
4251         echo $tot
4252 }
4253 do_dirty_record() {
4254         before=`dirty_osc_total`
4255         echo executing "\"$*\""
4256         eval $*
4257         after=`dirty_osc_total`
4258         echo before $before, after $after
4259 }
4260 test_45() {
4261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4262
4263         f="$DIR/f45"
4264         # Obtain grants from OST if it supports it
4265         echo blah > ${f}_grant
4266         stop_writeback
4267         sync
4268         do_dirty_record "echo blah > $f"
4269         [[ $before -eq $after ]] && error "write wasn't cached"
4270         do_dirty_record "> $f"
4271         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4272         do_dirty_record "echo blah > $f"
4273         [[ $before -eq $after ]] && error "write wasn't cached"
4274         do_dirty_record "sync"
4275         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4276         do_dirty_record "echo blah > $f"
4277         [[ $before -eq $after ]] && error "write wasn't cached"
4278         do_dirty_record "cancel_lru_locks osc"
4279         [[ $before -gt $after ]] ||
4280                 error "lock cancellation didn't lower dirty count"
4281         start_writeback
4282 }
4283 run_test 45 "osc io page accounting ============================"
4284
4285 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4286 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4287 # objects offset and an assert hit when an rpc was built with 1023's mapped
4288 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4289 test_46() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         f="$DIR/f46"
4293         stop_writeback
4294         sync
4295         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4296         sync
4297         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4298         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4299         sync
4300         start_writeback
4301 }
4302 run_test 46 "dirtying a previously written page ================"
4303
4304 # test_47 is removed "Device nodes check" is moved to test_28
4305
4306 test_48a() { # bug 2399
4307         [ "$mds1_FSTYPE" = "zfs" ] &&
4308         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4309                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4310
4311         test_mkdir $DIR/$tdir
4312         cd $DIR/$tdir
4313         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4314         test_mkdir $DIR/$tdir
4315         touch foo || error "'touch foo' failed after recreating cwd"
4316         test_mkdir bar
4317         touch .foo || error "'touch .foo' failed after recreating cwd"
4318         test_mkdir .bar
4319         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4320         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4321         cd . || error "'cd .' failed after recreating cwd"
4322         mkdir . && error "'mkdir .' worked after recreating cwd"
4323         rmdir . && error "'rmdir .' worked after recreating cwd"
4324         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4325         cd .. || error "'cd ..' failed after recreating cwd"
4326 }
4327 run_test 48a "Access renamed working dir (should return errors)="
4328
4329 test_48b() { # bug 2399
4330         rm -rf $DIR/$tdir
4331         test_mkdir $DIR/$tdir
4332         cd $DIR/$tdir
4333         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4334         touch foo && error "'touch foo' worked after removing cwd"
4335         mkdir foo && error "'mkdir foo' worked after removing cwd"
4336         touch .foo && error "'touch .foo' worked after removing cwd"
4337         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4338         ls . > /dev/null && error "'ls .' worked after removing cwd"
4339         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4340         mkdir . && error "'mkdir .' worked after removing cwd"
4341         rmdir . && error "'rmdir .' worked after removing cwd"
4342         ln -s . foo && error "'ln -s .' worked after removing cwd"
4343         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4344 }
4345 run_test 48b "Access removed working dir (should return errors)="
4346
4347 test_48c() { # bug 2350
4348         #lctl set_param debug=-1
4349         #set -vx
4350         rm -rf $DIR/$tdir
4351         test_mkdir -p $DIR/$tdir/dir
4352         cd $DIR/$tdir/dir
4353         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4354         $TRACE touch foo && error "touch foo worked after removing cwd"
4355         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4356         touch .foo && error "touch .foo worked after removing cwd"
4357         mkdir .foo && error "mkdir .foo worked after removing cwd"
4358         $TRACE ls . && error "'ls .' worked after removing cwd"
4359         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4360         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4361         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4362         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4363         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4364 }
4365 run_test 48c "Access removed working subdir (should return errors)"
4366
4367 test_48d() { # bug 2350
4368         #lctl set_param debug=-1
4369         #set -vx
4370         rm -rf $DIR/$tdir
4371         test_mkdir -p $DIR/$tdir/dir
4372         cd $DIR/$tdir/dir
4373         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4374         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4375         $TRACE touch foo && error "'touch foo' worked after removing parent"
4376         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4377         touch .foo && error "'touch .foo' worked after removing parent"
4378         mkdir .foo && error "mkdir .foo worked after removing parent"
4379         $TRACE ls . && error "'ls .' worked after removing parent"
4380         $TRACE ls .. && error "'ls ..' worked after removing parent"
4381         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4382         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4383         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4384         true
4385 }
4386 run_test 48d "Access removed parent subdir (should return errors)"
4387
4388 test_48e() { # bug 4134
4389         #lctl set_param debug=-1
4390         #set -vx
4391         rm -rf $DIR/$tdir
4392         test_mkdir -p $DIR/$tdir/dir
4393         cd $DIR/$tdir/dir
4394         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4395         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4396         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4397         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4398         # On a buggy kernel addition of "touch foo" after cd .. will
4399         # produce kernel oops in lookup_hash_it
4400         touch ../foo && error "'cd ..' worked after recreate parent"
4401         cd $DIR
4402         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4403 }
4404 run_test 48e "Access to recreated parent subdir (should return errors)"
4405
4406 test_49() { # LU-1030
4407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4408         remote_ost_nodsh && skip "remote OST with nodsh"
4409
4410         # get ost1 size - lustre-OST0000
4411         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4412                 awk '{ print $4 }')
4413         # write 800M at maximum
4414         [[ $ost1_size -lt 2 ]] && ost1_size=2
4415         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4416
4417         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4418         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4419         local dd_pid=$!
4420
4421         # change max_pages_per_rpc while writing the file
4422         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4423         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4424         # loop until dd process exits
4425         while ps ax -opid | grep -wq $dd_pid; do
4426                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4427                 sleep $((RANDOM % 5 + 1))
4428         done
4429         # restore original max_pages_per_rpc
4430         $LCTL set_param $osc1_mppc=$orig_mppc
4431         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4432 }
4433 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4434
4435 test_50() {
4436         # bug 1485
4437         test_mkdir $DIR/$tdir
4438         cd $DIR/$tdir
4439         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4440 }
4441 run_test 50 "special situations: /proc symlinks  ==============="
4442
4443 test_51a() {    # was test_51
4444         # bug 1516 - create an empty entry right after ".." then split dir
4445         test_mkdir -c1 $DIR/$tdir
4446         touch $DIR/$tdir/foo
4447         $MCREATE $DIR/$tdir/bar
4448         rm $DIR/$tdir/foo
4449         createmany -m $DIR/$tdir/longfile 201
4450         FNUM=202
4451         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4452                 $MCREATE $DIR/$tdir/longfile$FNUM
4453                 FNUM=$(($FNUM + 1))
4454                 echo -n "+"
4455         done
4456         echo
4457         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4458 }
4459 run_test 51a "special situations: split htree with empty entry =="
4460
4461 cleanup_print_lfs_df () {
4462         trap 0
4463         $LFS df
4464         $LFS df -i
4465 }
4466
4467 test_51b() {
4468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4469
4470         local dir=$DIR/$tdir
4471         local nrdirs=$((65536 + 100))
4472
4473         # cleanup the directory
4474         rm -fr $dir
4475
4476         test_mkdir -c1 $dir
4477
4478         $LFS df
4479         $LFS df -i
4480         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4481         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4482         [[ $numfree -lt $nrdirs ]] &&
4483                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4484
4485         # need to check free space for the directories as well
4486         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4487         numfree=$(( blkfree / $(fs_inode_ksize) ))
4488         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4489
4490         trap cleanup_print_lfs_df EXIT
4491
4492         # create files
4493         createmany -d $dir/d $nrdirs || {
4494                 unlinkmany $dir/d $nrdirs
4495                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4496         }
4497
4498         # really created :
4499         nrdirs=$(ls -U $dir | wc -l)
4500
4501         # unlink all but 100 subdirectories, then check it still works
4502         local left=100
4503         local delete=$((nrdirs - left))
4504
4505         $LFS df
4506         $LFS df -i
4507
4508         # for ldiskfs the nlink count should be 1, but this is OSD specific
4509         # and so this is listed for informational purposes only
4510         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4511         unlinkmany -d $dir/d $delete ||
4512                 error "unlink of first $delete subdirs failed"
4513
4514         echo "nlink between: $(stat -c %h $dir)"
4515         local found=$(ls -U $dir | wc -l)
4516         [ $found -ne $left ] &&
4517                 error "can't find subdirs: found only $found, expected $left"
4518
4519         unlinkmany -d $dir/d $delete $left ||
4520                 error "unlink of second $left subdirs failed"
4521         # regardless of whether the backing filesystem tracks nlink accurately
4522         # or not, the nlink count shouldn't be more than "." and ".." here
4523         local after=$(stat -c %h $dir)
4524         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4525                 echo "nlink after: $after"
4526
4527         cleanup_print_lfs_df
4528 }
4529 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4530
4531 test_51d() {
4532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4533         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4534
4535         test_mkdir $DIR/$tdir
4536         createmany -o $DIR/$tdir/t- 1000
4537         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4538         for N in $(seq 0 $((OSTCOUNT - 1))); do
4539                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4540                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4541                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4542                         '($1 == '$N') { objs += 1 } \
4543                         END { printf("%0.0f", objs) }')
4544                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4545         done
4546         unlinkmany $DIR/$tdir/t- 1000
4547
4548         NLAST=0
4549         for N in $(seq 1 $((OSTCOUNT - 1))); do
4550                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4551                         error "OST $N has less objects vs OST $NLAST" \
4552                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4553                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4554                         error "OST $N has less objects vs OST $NLAST" \
4555                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4556
4557                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4558                         error "OST $N has less #0 objects vs OST $NLAST" \
4559                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4560                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4561                         error "OST $N has less #0 objects vs OST $NLAST" \
4562                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4563                 NLAST=$N
4564         done
4565         rm -f $TMP/$tfile
4566 }
4567 run_test 51d "check object distribution"
4568
4569 test_51e() {
4570         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4571                 skip_env "ldiskfs only test"
4572         fi
4573
4574         test_mkdir -c1 $DIR/$tdir
4575         test_mkdir -c1 $DIR/$tdir/d0
4576
4577         touch $DIR/$tdir/d0/foo
4578         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4579                 error "file exceed 65000 nlink limit!"
4580         unlinkmany $DIR/$tdir/d0/f- 65001
4581         return 0
4582 }
4583 run_test 51e "check file nlink limit"
4584
4585 test_51f() {
4586         test_mkdir $DIR/$tdir
4587
4588         local max=100000
4589         local ulimit_old=$(ulimit -n)
4590         local spare=20 # number of spare fd's for scripts/libraries, etc.
4591         local mdt=$($LFS getstripe -m $DIR/$tdir)
4592         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4593
4594         echo "MDT$mdt numfree=$numfree, max=$max"
4595         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4596         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4597                 while ! ulimit -n $((numfree + spare)); do
4598                         numfree=$((numfree * 3 / 4))
4599                 done
4600                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4601         else
4602                 echo "left ulimit at $ulimit_old"
4603         fi
4604
4605         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4606                 unlinkmany $DIR/$tdir/f $numfree
4607                 error "create+open $numfree files in $DIR/$tdir failed"
4608         }
4609         ulimit -n $ulimit_old
4610
4611         # if createmany exits at 120s there will be fewer than $numfree files
4612         unlinkmany $DIR/$tdir/f $numfree || true
4613 }
4614 run_test 51f "check many open files limit"
4615
4616 test_52a() {
4617         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4618         test_mkdir $DIR/$tdir
4619         touch $DIR/$tdir/foo
4620         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4621         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4622         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4623         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4624         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4625                                         error "link worked"
4626         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4627         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4628         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4629                                                      error "lsattr"
4630         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4631         cp -r $DIR/$tdir $TMP/
4632         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4633 }
4634 run_test 52a "append-only flag test (should return errors)"
4635
4636 test_52b() {
4637         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4638         test_mkdir $DIR/$tdir
4639         touch $DIR/$tdir/foo
4640         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4641         cat test > $DIR/$tdir/foo && error "cat test worked"
4642         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4643         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4644         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4645                                         error "link worked"
4646         echo foo >> $DIR/$tdir/foo && error "echo worked"
4647         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4648         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4649         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4650         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4651                                                         error "lsattr"
4652         chattr -i $DIR/$tdir/foo || error "chattr failed"
4653
4654         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4655 }
4656 run_test 52b "immutable flag test (should return errors) ======="
4657
4658 test_53() {
4659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4660         remote_mds_nodsh && skip "remote MDS with nodsh"
4661         remote_ost_nodsh && skip "remote OST with nodsh"
4662
4663         local param
4664         local param_seq
4665         local ostname
4666         local mds_last
4667         local mds_last_seq
4668         local ost_last
4669         local ost_last_seq
4670         local ost_last_id
4671         local ostnum
4672         local node
4673         local found=false
4674         local support_last_seq=true
4675
4676         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4677                 support_last_seq=false
4678
4679         # only test MDT0000
4680         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4681         local value
4682         for value in $(do_facet $SINGLEMDS \
4683                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4684                 param=$(echo ${value[0]} | cut -d "=" -f1)
4685                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4686
4687                 if $support_last_seq; then
4688                         param_seq=$(echo $param |
4689                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4690                         mds_last_seq=$(do_facet $SINGLEMDS \
4691                                        $LCTL get_param -n $param_seq)
4692                 fi
4693                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4694
4695                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4696                 node=$(facet_active_host ost$((ostnum+1)))
4697                 param="obdfilter.$ostname.last_id"
4698                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4699                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4700                         ost_last_id=$ost_last
4701
4702                         if $support_last_seq; then
4703                                 ost_last_id=$(echo $ost_last |
4704                                               awk -F':' '{print $2}' |
4705                                               sed -e "s/^0x//g")
4706                                 ost_last_seq=$(echo $ost_last |
4707                                                awk -F':' '{print $1}')
4708                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4709                         fi
4710
4711                         if [[ $ost_last_id != $mds_last ]]; then
4712                                 error "$ost_last_id != $mds_last"
4713                         else
4714                                 found=true
4715                                 break
4716                         fi
4717                 done
4718         done
4719         $found || error "can not match last_seq/last_id for $mdtosc"
4720         return 0
4721 }
4722 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4723
4724 test_54a() {
4725         perl -MSocket -e ';' || skip "no Socket perl module installed"
4726
4727         $SOCKETSERVER $DIR/socket ||
4728                 error "$SOCKETSERVER $DIR/socket failed: $?"
4729         $SOCKETCLIENT $DIR/socket ||
4730                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4731         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4732 }
4733 run_test 54a "unix domain socket test =========================="
4734
4735 test_54b() {
4736         f="$DIR/f54b"
4737         mknod $f c 1 3
4738         chmod 0666 $f
4739         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4740 }
4741 run_test 54b "char device works in lustre ======================"
4742
4743 find_loop_dev() {
4744         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4745         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4746         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4747
4748         for i in $(seq 3 7); do
4749                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4750                 LOOPDEV=$LOOPBASE$i
4751                 LOOPNUM=$i
4752                 break
4753         done
4754 }
4755
4756 cleanup_54c() {
4757         local rc=0
4758         loopdev="$DIR/loop54c"
4759
4760         trap 0
4761         $UMOUNT $DIR/$tdir || rc=$?
4762         losetup -d $loopdev || true
4763         losetup -d $LOOPDEV || true
4764         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4765         return $rc
4766 }
4767
4768 test_54c() {
4769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4770
4771         loopdev="$DIR/loop54c"
4772
4773         find_loop_dev
4774         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4775         trap cleanup_54c EXIT
4776         mknod $loopdev b 7 $LOOPNUM
4777         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4778         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4779         losetup $loopdev $DIR/$tfile ||
4780                 error "can't set up $loopdev for $DIR/$tfile"
4781         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4782         test_mkdir $DIR/$tdir
4783         mount -t ext2 $loopdev $DIR/$tdir ||
4784                 error "error mounting $loopdev on $DIR/$tdir"
4785         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4786                 error "dd write"
4787         df $DIR/$tdir
4788         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4789                 error "dd read"
4790         cleanup_54c
4791 }
4792 run_test 54c "block device works in lustre ====================="
4793
4794 test_54d() {
4795         f="$DIR/f54d"
4796         string="aaaaaa"
4797         mknod $f p
4798         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4799 }
4800 run_test 54d "fifo device works in lustre ======================"
4801
4802 test_54e() {
4803         f="$DIR/f54e"
4804         string="aaaaaa"
4805         cp -aL /dev/console $f
4806         echo $string > $f || error "echo $string to $f failed"
4807 }
4808 run_test 54e "console/tty device works in lustre ======================"
4809
4810 test_56a() {
4811         local numfiles=3
4812         local dir=$DIR/$tdir
4813
4814         rm -rf $dir
4815         test_mkdir -p $dir/dir
4816         for i in $(seq $numfiles); do
4817                 touch $dir/file$i
4818                 touch $dir/dir/file$i
4819         done
4820
4821         local numcomp=$($LFS getstripe --component-count $dir)
4822
4823         [[ $numcomp == 0 ]] && numcomp=1
4824
4825         # test lfs getstripe with --recursive
4826         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4827
4828         [[ $filenum -eq $((numfiles * 2)) ]] ||
4829                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4830         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4831         [[ $filenum -eq $numfiles ]] ||
4832                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4833         echo "$LFS getstripe showed obdidx or l_ost_idx"
4834
4835         # test lfs getstripe with file instead of dir
4836         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4837         [[ $filenum -eq 1 ]] ||
4838                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4839         echo "$LFS getstripe file1 passed"
4840
4841         #test lfs getstripe with --verbose
4842         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4843         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4844                 error "$LFS getstripe --verbose $dir: "\
4845                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4846         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4847                 error "$LFS getstripe $dir: showed lmm_magic"
4848
4849         #test lfs getstripe with -v prints lmm_fid
4850         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4851         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4852                 error "$LFS getstripe -v $dir: "\
4853                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4854         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4855                 error "$LFS getstripe $dir: showed lmm_fid by default"
4856         echo "$LFS getstripe --verbose passed"
4857
4858         #check for FID information
4859         local fid1=$($LFS getstripe --fid $dir/file1)
4860         local fid2=$($LFS getstripe --verbose $dir/file1 |
4861                      awk '/lmm_fid: / { print $2; exit; }')
4862         local fid3=$($LFS path2fid $dir/file1)
4863
4864         [ "$fid1" != "$fid2" ] &&
4865                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4866         [ "$fid1" != "$fid3" ] &&
4867                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4868         echo "$LFS getstripe --fid passed"
4869
4870         #test lfs getstripe with --obd
4871         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4872                 error "$LFS getstripe --obd wrong_uuid: should return error"
4873
4874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4875
4876         local ostidx=1
4877         local obduuid=$(ostuuid_from_index $ostidx)
4878         local found=$($LFS getstripe -r --obd $obduuid $dir |
4879                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4880
4881         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4882         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4883                 ((filenum--))
4884         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4885                 ((filenum--))
4886
4887         [[ $found -eq $filenum ]] ||
4888                 error "$LFS getstripe --obd: found $found expect $filenum"
4889         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4890                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4891                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4892                 error "$LFS getstripe --obd: should not show file on other obd"
4893         echo "$LFS getstripe --obd passed"
4894 }
4895 run_test 56a "check $LFS getstripe"
4896
4897 test_56b() {
4898         local dir=$DIR/$tdir
4899         local numdirs=3
4900
4901         test_mkdir $dir
4902         for i in $(seq $numdirs); do
4903                 test_mkdir $dir/dir$i
4904         done
4905
4906         # test lfs getdirstripe default mode is non-recursion, which is
4907         # different from lfs getstripe
4908         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4909
4910         [[ $dircnt -eq 1 ]] ||
4911                 error "$LFS getdirstripe: found $dircnt, not 1"
4912         dircnt=$($LFS getdirstripe --recursive $dir |
4913                 grep -c lmv_stripe_count)
4914         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4915                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4916 }
4917 run_test 56b "check $LFS getdirstripe"
4918
4919 test_56c() {
4920         remote_ost_nodsh && skip "remote OST with nodsh"
4921
4922         local ost_idx=0
4923         local ost_name=$(ostname_from_index $ost_idx)
4924         local old_status=$(ost_dev_status $ost_idx)
4925
4926         [[ -z "$old_status" ]] ||
4927                 skip_env "OST $ost_name is in $old_status status"
4928
4929         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4930         sleep_maxage
4931
4932         local new_status=$(ost_dev_status $ost_idx)
4933
4934         [[ "$new_status" = "D" ]] ||
4935                 error "OST $ost_name is in status of '$new_status', not 'D'"
4936
4937         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4938         sleep_maxage
4939
4940         new_status=$(ost_dev_status $ost_idx)
4941         [[ -z "$new_status" ]] ||
4942                 error "OST $ost_name is in status of '$new_status', not ''"
4943 }
4944 run_test 56c "check 'lfs df' showing device status"
4945
4946 NUMFILES=3
4947 NUMDIRS=3
4948 setup_56() {
4949         local local_tdir="$1"
4950         local local_numfiles="$2"
4951         local local_numdirs="$3"
4952         local dir_params="$4"
4953         local dir_stripe_params="$5"
4954
4955         if [ ! -d "$local_tdir" ] ; then
4956                 test_mkdir -p $dir_stripe_params $local_tdir
4957                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4958                 for i in $(seq $local_numfiles) ; do
4959                         touch $local_tdir/file$i
4960                 done
4961                 for i in $(seq $local_numdirs) ; do
4962                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4963                         for j in $(seq $local_numfiles) ; do
4964                                 touch $local_tdir/dir$i/file$j
4965                         done
4966                 done
4967         fi
4968 }
4969
4970 setup_56_special() {
4971         local local_tdir=$1
4972         local local_numfiles=$2
4973         local local_numdirs=$3
4974
4975         setup_56 $local_tdir $local_numfiles $local_numdirs
4976
4977         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4978                 for i in $(seq $local_numfiles) ; do
4979                         mknod $local_tdir/loop${i}b b 7 $i
4980                         mknod $local_tdir/null${i}c c 1 3
4981                         ln -s $local_tdir/file1 $local_tdir/link${i}
4982                 done
4983                 for i in $(seq $local_numdirs) ; do
4984                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4985                         mknod $local_tdir/dir$i/null${i}c c 1 3
4986                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4987                 done
4988         fi
4989 }
4990
4991 test_56g() {
4992         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4993         local expected=$(($NUMDIRS + 2))
4994
4995         setup_56 $dir $NUMFILES $NUMDIRS
4996
4997         # test lfs find with -name
4998         for i in $(seq $NUMFILES) ; do
4999                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5000
5001                 [ $nums -eq $expected ] ||
5002                         error "lfs find -name '*$i' $dir wrong: "\
5003                               "found $nums, expected $expected"
5004         done
5005 }
5006 run_test 56g "check lfs find -name"
5007
5008 test_56h() {
5009         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5010         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5011
5012         setup_56 $dir $NUMFILES $NUMDIRS
5013
5014         # test lfs find with ! -name
5015         for i in $(seq $NUMFILES) ; do
5016                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5017
5018                 [ $nums -eq $expected ] ||
5019                         error "lfs find ! -name '*$i' $dir wrong: "\
5020                               "found $nums, expected $expected"
5021         done
5022 }
5023 run_test 56h "check lfs find ! -name"
5024
5025 test_56i() {
5026         local dir=$DIR/$tdir
5027
5028         test_mkdir $dir
5029
5030         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5031         local out=$($cmd)
5032
5033         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5034 }
5035 run_test 56i "check 'lfs find -ost UUID' skips directories"
5036
5037 test_56j() {
5038         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5039
5040         setup_56_special $dir $NUMFILES $NUMDIRS
5041
5042         local expected=$((NUMDIRS + 1))
5043         local cmd="$LFS find -type d $dir"
5044         local nums=$($cmd | wc -l)
5045
5046         [ $nums -eq $expected ] ||
5047                 error "'$cmd' wrong: found $nums, expected $expected"
5048 }
5049 run_test 56j "check lfs find -type d"
5050
5051 test_56k() {
5052         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5053
5054         setup_56_special $dir $NUMFILES $NUMDIRS
5055
5056         local expected=$(((NUMDIRS + 1) * NUMFILES))
5057         local cmd="$LFS find -type f $dir"
5058         local nums=$($cmd | wc -l)
5059
5060         [ $nums -eq $expected ] ||
5061                 error "'$cmd' wrong: found $nums, expected $expected"
5062 }
5063 run_test 56k "check lfs find -type f"
5064
5065 test_56l() {
5066         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5067
5068         setup_56_special $dir $NUMFILES $NUMDIRS
5069
5070         local expected=$((NUMDIRS + NUMFILES))
5071         local cmd="$LFS find -type b $dir"
5072         local nums=$($cmd | wc -l)
5073
5074         [ $nums -eq $expected ] ||
5075                 error "'$cmd' wrong: found $nums, expected $expected"
5076 }
5077 run_test 56l "check lfs find -type b"
5078
5079 test_56m() {
5080         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5081
5082         setup_56_special $dir $NUMFILES $NUMDIRS
5083
5084         local expected=$((NUMDIRS + NUMFILES))
5085         local cmd="$LFS find -type c $dir"
5086         local nums=$($cmd | wc -l)
5087         [ $nums -eq $expected ] ||
5088                 error "'$cmd' wrong: found $nums, expected $expected"
5089 }
5090 run_test 56m "check lfs find -type c"
5091
5092 test_56n() {
5093         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5094         setup_56_special $dir $NUMFILES $NUMDIRS
5095
5096         local expected=$((NUMDIRS + NUMFILES))
5097         local cmd="$LFS find -type l $dir"
5098         local nums=$($cmd | wc -l)
5099
5100         [ $nums -eq $expected ] ||
5101                 error "'$cmd' wrong: found $nums, expected $expected"
5102 }
5103 run_test 56n "check lfs find -type l"
5104
5105 test_56o() {
5106         local dir=$DIR/$tdir
5107
5108         setup_56 $dir $NUMFILES $NUMDIRS
5109         utime $dir/file1 > /dev/null || error "utime (1)"
5110         utime $dir/file2 > /dev/null || error "utime (2)"
5111         utime $dir/dir1 > /dev/null || error "utime (3)"
5112         utime $dir/dir2 > /dev/null || error "utime (4)"
5113         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5114         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5115
5116         local expected=4
5117         local nums=$($LFS find -mtime +0 $dir | wc -l)
5118
5119         [ $nums -eq $expected ] ||
5120                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5121
5122         expected=12
5123         cmd="$LFS find -mtime 0 $dir"
5124         nums=$($cmd | wc -l)
5125         [ $nums -eq $expected ] ||
5126                 error "'$cmd' wrong: found $nums, expected $expected"
5127 }
5128 run_test 56o "check lfs find -mtime for old files"
5129
5130 test_56ob() {
5131         local dir=$DIR/$tdir
5132         local expected=1
5133         local count=0
5134
5135         # just to make sure there is something that won't be found
5136         test_mkdir $dir
5137         touch $dir/$tfile.now
5138
5139         for age in year week day hour min; do
5140                 count=$((count + 1))
5141
5142                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5143                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5144                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5145
5146                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5147                 local nums=$($cmd | wc -l)
5148                 [ $nums -eq $expected ] ||
5149                         error "'$cmd' wrong: found $nums, expected $expected"
5150
5151                 cmd="$LFS find $dir -atime $count${age:0:1}"
5152                 nums=$($cmd | wc -l)
5153                 [ $nums -eq $expected ] ||
5154                         error "'$cmd' wrong: found $nums, expected $expected"
5155         done
5156
5157         sleep 2
5158         cmd="$LFS find $dir -ctime +1s -type f"
5159         nums=$($cmd | wc -l)
5160         (( $nums == $count * 2 + 1)) ||
5161                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5162 }
5163 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5164
5165 test_56p() {
5166         [ $RUNAS_ID -eq $UID ] &&
5167                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5168
5169         local dir=$DIR/$tdir
5170
5171         setup_56 $dir $NUMFILES $NUMDIRS
5172         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5173
5174         local expected=$NUMFILES
5175         local cmd="$LFS find -uid $RUNAS_ID $dir"
5176         local nums=$($cmd | wc -l)
5177
5178         [ $nums -eq $expected ] ||
5179                 error "'$cmd' wrong: found $nums, expected $expected"
5180
5181         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5182         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5183         nums=$($cmd | wc -l)
5184         [ $nums -eq $expected ] ||
5185                 error "'$cmd' wrong: found $nums, expected $expected"
5186 }
5187 run_test 56p "check lfs find -uid and ! -uid"
5188
5189 test_56q() {
5190         [ $RUNAS_ID -eq $UID ] &&
5191                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5192
5193         local dir=$DIR/$tdir
5194
5195         setup_56 $dir $NUMFILES $NUMDIRS
5196         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5197
5198         local expected=$NUMFILES
5199         local cmd="$LFS find -gid $RUNAS_GID $dir"
5200         local nums=$($cmd | wc -l)
5201
5202         [ $nums -eq $expected ] ||
5203                 error "'$cmd' wrong: found $nums, expected $expected"
5204
5205         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5206         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5207         nums=$($cmd | wc -l)
5208         [ $nums -eq $expected ] ||
5209                 error "'$cmd' wrong: found $nums, expected $expected"
5210 }
5211 run_test 56q "check lfs find -gid and ! -gid"
5212
5213 test_56r() {
5214         local dir=$DIR/$tdir
5215
5216         setup_56 $dir $NUMFILES $NUMDIRS
5217
5218         local expected=12
5219         local cmd="$LFS find -size 0 -type f $dir"
5220         local nums=$($cmd | wc -l)
5221
5222         [ $nums -eq $expected ] ||
5223                 error "'$cmd' wrong: found $nums, expected $expected"
5224         expected=0
5225         cmd="$LFS find ! -size 0 -type f $dir"
5226         nums=$($cmd | wc -l)
5227         [ $nums -eq $expected ] ||
5228                 error "'$cmd' wrong: found $nums, expected $expected"
5229         echo "test" > $dir/$tfile
5230         echo "test2" > $dir/$tfile.2 && sync
5231         expected=1
5232         cmd="$LFS find -size 5 -type f $dir"
5233         nums=$($cmd | wc -l)
5234         [ $nums -eq $expected ] ||
5235                 error "'$cmd' wrong: found $nums, expected $expected"
5236         expected=1
5237         cmd="$LFS find -size +5 -type f $dir"
5238         nums=$($cmd | wc -l)
5239         [ $nums -eq $expected ] ||
5240                 error "'$cmd' wrong: found $nums, expected $expected"
5241         expected=2
5242         cmd="$LFS find -size +0 -type f $dir"
5243         nums=$($cmd | wc -l)
5244         [ $nums -eq $expected ] ||
5245                 error "'$cmd' wrong: found $nums, expected $expected"
5246         expected=2
5247         cmd="$LFS find ! -size -5 -type f $dir"
5248         nums=$($cmd | wc -l)
5249         [ $nums -eq $expected ] ||
5250                 error "'$cmd' wrong: found $nums, expected $expected"
5251         expected=12
5252         cmd="$LFS find -size -5 -type f $dir"
5253         nums=$($cmd | wc -l)
5254         [ $nums -eq $expected ] ||
5255                 error "'$cmd' wrong: found $nums, expected $expected"
5256 }
5257 run_test 56r "check lfs find -size works"
5258
5259 test_56s() { # LU-611 #LU-9369
5260         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5261
5262         local dir=$DIR/$tdir
5263         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5264
5265         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5266         for i in $(seq $NUMDIRS); do
5267                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5268         done
5269
5270         local expected=$NUMDIRS
5271         local cmd="$LFS find -c $OSTCOUNT $dir"
5272         local nums=$($cmd | wc -l)
5273
5274         [ $nums -eq $expected ] || {
5275                 $LFS getstripe -R $dir
5276                 error "'$cmd' wrong: found $nums, expected $expected"
5277         }
5278
5279         expected=$((NUMDIRS + onestripe))
5280         cmd="$LFS find -stripe-count +0 -type f $dir"
5281         nums=$($cmd | wc -l)
5282         [ $nums -eq $expected ] || {
5283                 $LFS getstripe -R $dir
5284                 error "'$cmd' wrong: found $nums, expected $expected"
5285         }
5286
5287         expected=$onestripe
5288         cmd="$LFS find -stripe-count 1 -type f $dir"
5289         nums=$($cmd | wc -l)
5290         [ $nums -eq $expected ] || {
5291                 $LFS getstripe -R $dir
5292                 error "'$cmd' wrong: found $nums, expected $expected"
5293         }
5294
5295         cmd="$LFS find -stripe-count -2 -type f $dir"
5296         nums=$($cmd | wc -l)
5297         [ $nums -eq $expected ] || {
5298                 $LFS getstripe -R $dir
5299                 error "'$cmd' wrong: found $nums, expected $expected"
5300         }
5301
5302         expected=0
5303         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5304         nums=$($cmd | wc -l)
5305         [ $nums -eq $expected ] || {
5306                 $LFS getstripe -R $dir
5307                 error "'$cmd' wrong: found $nums, expected $expected"
5308         }
5309 }
5310 run_test 56s "check lfs find -stripe-count works"
5311
5312 test_56t() { # LU-611 #LU-9369
5313         local dir=$DIR/$tdir
5314
5315         setup_56 $dir 0 $NUMDIRS
5316         for i in $(seq $NUMDIRS); do
5317                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5318         done
5319
5320         local expected=$NUMDIRS
5321         local cmd="$LFS find -S 8M $dir"
5322         local nums=$($cmd | wc -l)
5323
5324         [ $nums -eq $expected ] || {
5325                 $LFS getstripe -R $dir
5326                 error "'$cmd' wrong: found $nums, expected $expected"
5327         }
5328         rm -rf $dir
5329
5330         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5331
5332         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5333
5334         expected=$(((NUMDIRS + 1) * NUMFILES))
5335         cmd="$LFS find -stripe-size 512k -type f $dir"
5336         nums=$($cmd | wc -l)
5337         [ $nums -eq $expected ] ||
5338                 error "'$cmd' wrong: found $nums, expected $expected"
5339
5340         cmd="$LFS find -stripe-size +320k -type f $dir"
5341         nums=$($cmd | wc -l)
5342         [ $nums -eq $expected ] ||
5343                 error "'$cmd' wrong: found $nums, expected $expected"
5344
5345         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5346         cmd="$LFS find -stripe-size +200k -type f $dir"
5347         nums=$($cmd | wc -l)
5348         [ $nums -eq $expected ] ||
5349                 error "'$cmd' wrong: found $nums, expected $expected"
5350
5351         cmd="$LFS find -stripe-size -640k -type f $dir"
5352         nums=$($cmd | wc -l)
5353         [ $nums -eq $expected ] ||
5354                 error "'$cmd' wrong: found $nums, expected $expected"
5355
5356         expected=4
5357         cmd="$LFS find -stripe-size 256k -type f $dir"
5358         nums=$($cmd | wc -l)
5359         [ $nums -eq $expected ] ||
5360                 error "'$cmd' wrong: found $nums, expected $expected"
5361
5362         cmd="$LFS find -stripe-size -320k -type f $dir"
5363         nums=$($cmd | wc -l)
5364         [ $nums -eq $expected ] ||
5365                 error "'$cmd' wrong: found $nums, expected $expected"
5366
5367         expected=0
5368         cmd="$LFS find -stripe-size 1024k -type f $dir"
5369         nums=$($cmd | wc -l)
5370         [ $nums -eq $expected ] ||
5371                 error "'$cmd' wrong: found $nums, expected $expected"
5372 }
5373 run_test 56t "check lfs find -stripe-size works"
5374
5375 test_56u() { # LU-611
5376         local dir=$DIR/$tdir
5377
5378         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5379
5380         if [[ $OSTCOUNT -gt 1 ]]; then
5381                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5382                 onestripe=4
5383         else
5384                 onestripe=0
5385         fi
5386
5387         local expected=$(((NUMDIRS + 1) * NUMFILES))
5388         local cmd="$LFS find -stripe-index 0 -type f $dir"
5389         local nums=$($cmd | wc -l)
5390
5391         [ $nums -eq $expected ] ||
5392                 error "'$cmd' wrong: found $nums, expected $expected"
5393
5394         expected=$onestripe
5395         cmd="$LFS find -stripe-index 1 -type f $dir"
5396         nums=$($cmd | wc -l)
5397         [ $nums -eq $expected ] ||
5398                 error "'$cmd' wrong: found $nums, expected $expected"
5399
5400         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5401         nums=$($cmd | wc -l)
5402         [ $nums -eq $expected ] ||
5403                 error "'$cmd' wrong: found $nums, expected $expected"
5404
5405         expected=0
5406         # This should produce an error and not return any files
5407         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5408         nums=$($cmd 2>/dev/null | wc -l)
5409         [ $nums -eq $expected ] ||
5410                 error "'$cmd' wrong: found $nums, expected $expected"
5411
5412         if [[ $OSTCOUNT -gt 1 ]]; then
5413                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5414                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5415                 nums=$($cmd | wc -l)
5416                 [ $nums -eq $expected ] ||
5417                         error "'$cmd' wrong: found $nums, expected $expected"
5418         fi
5419 }
5420 run_test 56u "check lfs find -stripe-index works"
5421
5422 test_56v() {
5423         local mdt_idx=0
5424         local dir=$DIR/$tdir
5425
5426         setup_56 $dir $NUMFILES $NUMDIRS
5427
5428         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5429         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5430
5431         for file in $($LFS find -m $UUID $dir); do
5432                 file_midx=$($LFS getstripe -m $file)
5433                 [ $file_midx -eq $mdt_idx ] ||
5434                         error "lfs find -m $UUID != getstripe -m $file_midx"
5435         done
5436 }
5437 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5438
5439 test_56w() {
5440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5442
5443         local dir=$DIR/$tdir
5444
5445         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5446
5447         local stripe_size=$($LFS getstripe -S -d $dir) ||
5448                 error "$LFS getstripe -S -d $dir failed"
5449         stripe_size=${stripe_size%% *}
5450
5451         local file_size=$((stripe_size * OSTCOUNT))
5452         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5453         local required_space=$((file_num * file_size))
5454         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5455                            head -n1)
5456         [[ $free_space -le $((required_space / 1024)) ]] &&
5457                 skip_env "need $required_space, have $free_space kbytes"
5458
5459         local dd_bs=65536
5460         local dd_count=$((file_size / dd_bs))
5461
5462         # write data into the files
5463         local i
5464         local j
5465         local file
5466
5467         for i in $(seq $NUMFILES); do
5468                 file=$dir/file$i
5469                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5470                         error "write data into $file failed"
5471         done
5472         for i in $(seq $NUMDIRS); do
5473                 for j in $(seq $NUMFILES); do
5474                         file=$dir/dir$i/file$j
5475                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5476                                 error "write data into $file failed"
5477                 done
5478         done
5479
5480         # $LFS_MIGRATE will fail if hard link migration is unsupported
5481         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5482                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5483                         error "creating links to $dir/dir1/file1 failed"
5484         fi
5485
5486         local expected=-1
5487
5488         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5489
5490         # lfs_migrate file
5491         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5492
5493         echo "$cmd"
5494         eval $cmd || error "$cmd failed"
5495
5496         check_stripe_count $dir/file1 $expected
5497
5498         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5499         then
5500                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5501                 # OST 1 if it is on OST 0. This file is small enough to
5502                 # be on only one stripe.
5503                 file=$dir/migr_1_ost
5504                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5505                         error "write data into $file failed"
5506                 local obdidx=$($LFS getstripe -i $file)
5507                 local oldmd5=$(md5sum $file)
5508                 local newobdidx=0
5509
5510                 [[ $obdidx -eq 0 ]] && newobdidx=1
5511                 cmd="$LFS migrate -i $newobdidx $file"
5512                 echo $cmd
5513                 eval $cmd || error "$cmd failed"
5514
5515                 local realobdix=$($LFS getstripe -i $file)
5516                 local newmd5=$(md5sum $file)
5517
5518                 [[ $newobdidx -ne $realobdix ]] &&
5519                         error "new OST is different (was=$obdidx, "\
5520                               "wanted=$newobdidx, got=$realobdix)"
5521                 [[ "$oldmd5" != "$newmd5" ]] &&
5522                         error "md5sum differ: $oldmd5, $newmd5"
5523         fi
5524
5525         # lfs_migrate dir
5526         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5527         echo "$cmd"
5528         eval $cmd || error "$cmd failed"
5529
5530         for j in $(seq $NUMFILES); do
5531                 check_stripe_count $dir/dir1/file$j $expected
5532         done
5533
5534         # lfs_migrate works with lfs find
5535         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5536              $LFS_MIGRATE -y -c $expected"
5537         echo "$cmd"
5538         eval $cmd || error "$cmd failed"
5539
5540         for i in $(seq 2 $NUMFILES); do
5541                 check_stripe_count $dir/file$i $expected
5542         done
5543         for i in $(seq 2 $NUMDIRS); do
5544                 for j in $(seq $NUMFILES); do
5545                 check_stripe_count $dir/dir$i/file$j $expected
5546                 done
5547         done
5548 }
5549 run_test 56w "check lfs_migrate -c stripe_count works"
5550
5551 test_56wb() {
5552         local file1=$DIR/$tdir/file1
5553         local create_pool=false
5554         local initial_pool=$($LFS getstripe -p $DIR)
5555         local pool_list=()
5556         local pool=""
5557
5558         echo -n "Creating test dir..."
5559         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5560         echo "done."
5561
5562         echo -n "Creating test file..."
5563         touch $file1 || error "cannot create file"
5564         echo "done."
5565
5566         echo -n "Detecting existing pools..."
5567         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5568
5569         if [ ${#pool_list[@]} -gt 0 ]; then
5570                 echo "${pool_list[@]}"
5571                 for thispool in "${pool_list[@]}"; do
5572                         if [[ -z "$initial_pool" ||
5573                               "$initial_pool" != "$thispool" ]]; then
5574                                 pool="$thispool"
5575                                 echo "Using existing pool '$pool'"
5576                                 break
5577                         fi
5578                 done
5579         else
5580                 echo "none detected."
5581         fi
5582         if [ -z "$pool" ]; then
5583                 pool=${POOL:-testpool}
5584                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5585                 echo -n "Creating pool '$pool'..."
5586                 create_pool=true
5587                 pool_add $pool &> /dev/null ||
5588                         error "pool_add failed"
5589                 echo "done."
5590
5591                 echo -n "Adding target to pool..."
5592                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5593                         error "pool_add_targets failed"
5594                 echo "done."
5595         fi
5596
5597         echo -n "Setting pool using -p option..."
5598         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5599                 error "migrate failed rc = $?"
5600         echo "done."
5601
5602         echo -n "Verifying test file is in pool after migrating..."
5603         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5604                 error "file was not migrated to pool $pool"
5605         echo "done."
5606
5607         echo -n "Removing test file from pool '$pool'..."
5608         $LFS migrate $file1 &> /dev/null ||
5609                 error "cannot remove from pool"
5610         [ "$($LFS getstripe -p $file1)" ] &&
5611                 error "pool still set"
5612         echo "done."
5613
5614         echo -n "Setting pool using --pool option..."
5615         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5616                 error "migrate failed rc = $?"
5617         echo "done."
5618
5619         # Clean up
5620         rm -f $file1
5621         if $create_pool; then
5622                 destroy_test_pools 2> /dev/null ||
5623                         error "destroy test pools failed"
5624         fi
5625 }
5626 run_test 56wb "check lfs_migrate pool support"
5627
5628 test_56wc() {
5629         local file1="$DIR/$tdir/file1"
5630
5631         echo -n "Creating test dir..."
5632         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5633         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5634         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5635                 error "cannot set stripe"
5636         echo "done"
5637
5638         echo -n "Setting initial stripe for test file..."
5639         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5640                 error "cannot set stripe"
5641         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5642                 error "stripe size not set"
5643         echo "done."
5644
5645         # File currently set to -S 512K -c 1
5646
5647         # Ensure -c and -S options are rejected when -R is set
5648         echo -n "Verifying incompatible options are detected..."
5649         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5650                 error "incompatible -c and -R options not detected"
5651         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5652                 error "incompatible -S and -R options not detected"
5653         echo "done."
5654
5655         # Ensure unrecognized options are passed through to 'lfs migrate'
5656         echo -n "Verifying -S option is passed through to lfs migrate..."
5657         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5658                 error "migration failed"
5659         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5660                 error "file was not restriped"
5661         echo "done."
5662
5663         # File currently set to -S 1M -c 1
5664
5665         # Ensure long options are supported
5666         echo -n "Verifying long options supported..."
5667         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5668                 error "long option without argument not supported"
5669         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5670                 error "long option with argument not supported"
5671         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5672                 error "file not restriped with --stripe-size option"
5673         echo "done."
5674
5675         # File currently set to -S 512K -c 1
5676
5677         if [ "$OSTCOUNT" -gt 1 ]; then
5678                 echo -n "Verifying explicit stripe count can be set..."
5679                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5680                         error "migrate failed"
5681                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5682                         error "file not restriped to explicit count"
5683                 echo "done."
5684         fi
5685
5686         # File currently set to -S 512K -c 1 or -S 512K -c 2
5687
5688         # Ensure parent striping is used if -R is set, and no stripe
5689         # count or size is specified
5690         echo -n "Setting stripe for parent directory..."
5691         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5692                 error "cannot set stripe"
5693         echo "done."
5694
5695         echo -n "Verifying restripe option uses parent stripe settings..."
5696         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5697                 error "migrate failed"
5698         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5699                 error "file not restriped to parent settings"
5700         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5701                 error "file not restriped to parent settings"
5702         echo "done."
5703
5704         # File currently set to -S 1M -c 1
5705
5706         # Ensure striping is preserved if -R is not set, and no stripe
5707         # count or size is specified
5708         echo -n "Verifying striping size preserved when not specified..."
5709         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5710         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5711                 error "cannot set stripe on parent directory"
5712         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5713                 error "migrate failed"
5714         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5715                 error "file was restriped"
5716         echo "done."
5717
5718         # Ensure file name properly detected when final option has no argument
5719         echo -n "Verifying file name properly detected..."
5720         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5721                 error "file name interpreted as option argument"
5722         echo "done."
5723
5724         # Clean up
5725         rm -f "$file1"
5726 }
5727 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5728
5729 test_56wd() {
5730         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5731
5732         local file1=$DIR/$tdir/file1
5733
5734         echo -n "Creating test dir..."
5735         test_mkdir $DIR/$tdir || error "cannot create dir"
5736         echo "done."
5737
5738         echo -n "Creating test file..."
5739         touch $file1
5740         echo "done."
5741
5742         # Ensure 'lfs migrate' will fail by using a non-existent option,
5743         # and make sure rsync is not called to recover
5744         echo -n "Make sure --no-rsync option works..."
5745         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5746                 grep -q 'refusing to fall back to rsync' ||
5747                 error "rsync was called with --no-rsync set"
5748         echo "done."
5749
5750         # Ensure rsync is called without trying 'lfs migrate' first
5751         echo -n "Make sure --rsync option works..."
5752         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5753                 grep -q 'falling back to rsync' &&
5754                 error "lfs migrate was called with --rsync set"
5755         echo "done."
5756
5757         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5758         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5759                 grep -q 'at the same time' ||
5760                 error "--rsync and --no-rsync accepted concurrently"
5761         echo "done."
5762
5763         # Clean up
5764         rm -f $file1
5765 }
5766 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5767
5768 test_56x() {
5769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5770         check_swap_layouts_support
5771
5772         local dir=$DIR/$tdir
5773         local ref1=/etc/passwd
5774         local file1=$dir/file1
5775
5776         test_mkdir $dir || error "creating dir $dir"
5777         $LFS setstripe -c 2 $file1
5778         cp $ref1 $file1
5779         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5780         stripe=$($LFS getstripe -c $file1)
5781         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5782         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5783
5784         # clean up
5785         rm -f $file1
5786 }
5787 run_test 56x "lfs migration support"
5788
5789 test_56xa() {
5790         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5791         check_swap_layouts_support
5792
5793         local dir=$DIR/$tdir/$testnum
5794
5795         test_mkdir -p $dir
5796
5797         local ref1=/etc/passwd
5798         local file1=$dir/file1
5799
5800         $LFS setstripe -c 2 $file1
5801         cp $ref1 $file1
5802         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5803
5804         local stripe=$($LFS getstripe -c $file1)
5805
5806         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5807         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5808
5809         # clean up
5810         rm -f $file1
5811 }
5812 run_test 56xa "lfs migration --block support"
5813
5814 check_migrate_links() {
5815         local dir="$1"
5816         local file1="$dir/file1"
5817         local begin="$2"
5818         local count="$3"
5819         local total_count=$(($begin + $count - 1))
5820         local symlink_count=10
5821         local uniq_count=10
5822
5823         if [ ! -f "$file1" ]; then
5824                 echo -n "creating initial file..."
5825                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5826                         error "cannot setstripe initial file"
5827                 echo "done"
5828
5829                 echo -n "creating symlinks..."
5830                 for s in $(seq 1 $symlink_count); do
5831                         ln -s "$file1" "$dir/slink$s" ||
5832                                 error "cannot create symlinks"
5833                 done
5834                 echo "done"
5835
5836                 echo -n "creating nonlinked files..."
5837                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5838                         error "cannot create nonlinked files"
5839                 echo "done"
5840         fi
5841
5842         # create hard links
5843         if [ ! -f "$dir/file$total_count" ]; then
5844                 echo -n "creating hard links $begin:$total_count..."
5845                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5846                         /dev/null || error "cannot create hard links"
5847                 echo "done"
5848         fi
5849
5850         echo -n "checking number of hard links listed in xattrs..."
5851         local fid=$($LFS getstripe -F "$file1")
5852         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5853
5854         echo "${#paths[*]}"
5855         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5856                         skip "hard link list has unexpected size, skipping test"
5857         fi
5858         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5859                         error "link names should exceed xattrs size"
5860         fi
5861
5862         echo -n "migrating files..."
5863         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5864         local rc=$?
5865         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5866         echo "done"
5867
5868         # make sure all links have been properly migrated
5869         echo -n "verifying files..."
5870         fid=$($LFS getstripe -F "$file1") ||
5871                 error "cannot get fid for file $file1"
5872         for i in $(seq 2 $total_count); do
5873                 local fid2=$($LFS getstripe -F $dir/file$i)
5874
5875                 [ "$fid2" == "$fid" ] ||
5876                         error "migrated hard link has mismatched FID"
5877         done
5878
5879         # make sure hard links were properly detected, and migration was
5880         # performed only once for the entire link set; nonlinked files should
5881         # also be migrated
5882         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5883         local expected=$(($uniq_count + 1))
5884
5885         [ "$actual" -eq  "$expected" ] ||
5886                 error "hard links individually migrated ($actual != $expected)"
5887
5888         # make sure the correct number of hard links are present
5889         local hardlinks=$(stat -c '%h' "$file1")
5890
5891         [ $hardlinks -eq $total_count ] ||
5892                 error "num hard links $hardlinks != $total_count"
5893         echo "done"
5894
5895         return 0
5896 }
5897
5898 test_56xb() {
5899         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5900                 skip "Need MDS version at least 2.10.55"
5901
5902         local dir="$DIR/$tdir"
5903
5904         test_mkdir "$dir" || error "cannot create dir $dir"
5905
5906         echo "testing lfs migrate mode when all links fit within xattrs"
5907         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5908
5909         echo "testing rsync mode when all links fit within xattrs"
5910         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5911
5912         echo "testing lfs migrate mode when all links do not fit within xattrs"
5913         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5914
5915         echo "testing rsync mode when all links do not fit within xattrs"
5916         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5917
5918
5919         # clean up
5920         rm -rf $dir
5921 }
5922 run_test 56xb "lfs migration hard link support"
5923
5924 test_56xc() {
5925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5926
5927         local dir="$DIR/$tdir"
5928
5929         test_mkdir "$dir" || error "cannot create dir $dir"
5930
5931         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5932         echo -n "Setting initial stripe for 20MB test file..."
5933         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5934         echo "done"
5935         echo -n "Sizing 20MB test file..."
5936         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5937         echo "done"
5938         echo -n "Verifying small file autostripe count is 1..."
5939         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5940                 error "cannot migrate 20MB file"
5941         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5942                 error "cannot get stripe for $dir/20mb"
5943         [ $stripe_count -eq 1 ] ||
5944                 error "unexpected stripe count $stripe_count for 20MB file"
5945         rm -f "$dir/20mb"
5946         echo "done"
5947
5948         # Test 2: File is small enough to fit within the available space on
5949         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5950         # have at least an additional 1KB for each desired stripe for test 3
5951         echo -n "Setting stripe for 1GB test file..."
5952         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5953         echo "done"
5954         echo -n "Sizing 1GB test file..."
5955         # File size is 1GB + 3KB
5956         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5957                 error "cannot create 1GB test file"
5958         echo "done"
5959         echo -n "Migrating 1GB file..."
5960         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5961                 error "cannot migrate file"
5962         echo "done"
5963         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5964         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5965                 error "cannot get stripe for $dir/1gb"
5966         [ $stripe_count -eq 2 ] ||
5967                 error "unexpected stripe count $stripe_count (expected 2)"
5968         echo "done"
5969
5970         # Test 3: File is too large to fit within the available space on
5971         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5972         if [ $OSTCOUNT -ge 3 ]; then
5973                 # The required available space is calculated as
5974                 # file size (1GB + 3KB) / OST count (3).
5975                 local kb_per_ost=349526
5976
5977                 echo -n "Migrating 1GB file..."
5978                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5979                         /dev/null || error "cannot migrate file"
5980                 echo "done"
5981
5982                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5983                 echo -n "Verifying autostripe count with limited space..."
5984                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5985                         error "unexpected stripe count $stripe_count (wanted 3)"
5986                 echo "done"
5987         fi
5988
5989         # clean up
5990         rm -rf $dir
5991 }
5992 run_test 56xc "lfs migration autostripe"
5993
5994 test_56y() {
5995         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5996                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5997
5998         local res=""
5999         local dir=$DIR/$tdir
6000         local f1=$dir/file1
6001         local f2=$dir/file2
6002
6003         test_mkdir -p $dir || error "creating dir $dir"
6004         touch $f1 || error "creating std file $f1"
6005         $MULTIOP $f2 H2c || error "creating released file $f2"
6006
6007         # a directory can be raid0, so ask only for files
6008         res=$($LFS find $dir -L raid0 -type f | wc -l)
6009         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6010
6011         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6012         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6013
6014         # only files can be released, so no need to force file search
6015         res=$($LFS find $dir -L released)
6016         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6017
6018         res=$($LFS find $dir -type f \! -L released)
6019         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6020 }
6021 run_test 56y "lfs find -L raid0|released"
6022
6023 test_56z() { # LU-4824
6024         # This checks to make sure 'lfs find' continues after errors
6025         # There are two classes of errors that should be caught:
6026         # - If multiple paths are provided, all should be searched even if one
6027         #   errors out
6028         # - If errors are encountered during the search, it should not terminate
6029         #   early
6030         local dir=$DIR/$tdir
6031         local i
6032
6033         test_mkdir $dir
6034         for i in d{0..9}; do
6035                 test_mkdir $dir/$i
6036         done
6037         touch $dir/d{0..9}/$tfile
6038         $LFS find $DIR/non_existent_dir $dir &&
6039                 error "$LFS find did not return an error"
6040         # Make a directory unsearchable. This should NOT be the last entry in
6041         # directory order.  Arbitrarily pick the 6th entry
6042         chmod 700 $($LFS find $dir -type d | sed '6!d')
6043
6044         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6045
6046         # The user should be able to see 10 directories and 9 files
6047         [ $count == 19 ] || error "$LFS find did not continue after error"
6048 }
6049 run_test 56z "lfs find should continue after an error"
6050
6051 test_56aa() { # LU-5937
6052         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6053
6054         local dir=$DIR/$tdir
6055
6056         mkdir $dir
6057         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6058
6059         createmany -o $dir/striped_dir/${tfile}- 1024
6060         local dirs=$($LFS find --size +8k $dir/)
6061
6062         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6063 }
6064 run_test 56aa "lfs find --size under striped dir"
6065
6066 test_56ab() { # LU-10705
6067         test_mkdir $DIR/$tdir
6068         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6069         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6070         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6071         # Flush writes to ensure valid blocks.  Need to be more thorough for
6072         # ZFS, since blocks are not allocated/returned to client immediately.
6073         sync_all_data
6074         wait_zfs_commit ost1 2
6075         cancel_lru_locks osc
6076         ls -ls $DIR/$tdir
6077
6078         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6079
6080         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6081
6082         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6083         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6084
6085         rm -f $DIR/$tdir/$tfile.[123]
6086 }
6087 run_test 56ab "lfs find --blocks"
6088
6089 test_56ba() {
6090         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6091                 skip "Need MDS version at least 2.10.50"
6092
6093         # Create composite files with one component
6094         local dir=$DIR/$tdir
6095
6096         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6097         # Create composite files with three components
6098         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6099         # Create non-composite files
6100         createmany -o $dir/${tfile}- 10
6101
6102         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6103
6104         [[ $nfiles == 10 ]] ||
6105                 error "lfs find -E 1M found $nfiles != 10 files"
6106
6107         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6108         [[ $nfiles == 25 ]] ||
6109                 error "lfs find ! -E 1M found $nfiles != 25 files"
6110
6111         # All files have a component that starts at 0
6112         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6113         [[ $nfiles == 35 ]] ||
6114                 error "lfs find --component-start 0 - $nfiles != 35 files"
6115
6116         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6117         [[ $nfiles == 15 ]] ||
6118                 error "lfs find --component-start 2M - $nfiles != 15 files"
6119
6120         # All files created here have a componenet that does not starts at 2M
6121         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6122         [[ $nfiles == 35 ]] ||
6123                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6124
6125         # Find files with a specified number of components
6126         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6127         [[ $nfiles == 15 ]] ||
6128                 error "lfs find --component-count 3 - $nfiles != 15 files"
6129
6130         # Remember non-composite files have a component count of zero
6131         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6132         [[ $nfiles == 10 ]] ||
6133                 error "lfs find --component-count 0 - $nfiles != 10 files"
6134
6135         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6136         [[ $nfiles == 20 ]] ||
6137                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6138
6139         # All files have a flag called "init"
6140         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6141         [[ $nfiles == 35 ]] ||
6142                 error "lfs find --component-flags init - $nfiles != 35 files"
6143
6144         # Multi-component files will have a component not initialized
6145         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6146         [[ $nfiles == 15 ]] ||
6147                 error "lfs find !--component-flags init - $nfiles != 15 files"
6148
6149         rm -rf $dir
6150
6151 }
6152 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6153
6154 test_56ca() {
6155         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6156                 skip "Need MDS version at least 2.10.57"
6157
6158         local td=$DIR/$tdir
6159         local tf=$td/$tfile
6160         local dir
6161         local nfiles
6162         local cmd
6163         local i
6164         local j
6165
6166         # create mirrored directories and mirrored files
6167         mkdir $td || error "mkdir $td failed"
6168         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6169         createmany -o $tf- 10 || error "create $tf- failed"
6170
6171         for i in $(seq 2); do
6172                 dir=$td/dir$i
6173                 mkdir $dir || error "mkdir $dir failed"
6174                 $LFS mirror create -N$((3 + i)) $dir ||
6175                         error "create mirrored dir $dir failed"
6176                 createmany -o $dir/$tfile- 10 ||
6177                         error "create $dir/$tfile- failed"
6178         done
6179
6180         # change the states of some mirrored files
6181         echo foo > $tf-6
6182         for i in $(seq 2); do
6183                 dir=$td/dir$i
6184                 for j in $(seq 4 9); do
6185                         echo foo > $dir/$tfile-$j
6186                 done
6187         done
6188
6189         # find mirrored files with specific mirror count
6190         cmd="$LFS find --mirror-count 3 --type f $td"
6191         nfiles=$($cmd | wc -l)
6192         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6193
6194         cmd="$LFS find ! --mirror-count 3 --type f $td"
6195         nfiles=$($cmd | wc -l)
6196         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6197
6198         cmd="$LFS find --mirror-count +2 --type f $td"
6199         nfiles=$($cmd | wc -l)
6200         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6201
6202         cmd="$LFS find --mirror-count -6 --type f $td"
6203         nfiles=$($cmd | wc -l)
6204         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6205
6206         # find mirrored files with specific file state
6207         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6208         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6209
6210         cmd="$LFS find --mirror-state=ro --type f $td"
6211         nfiles=$($cmd | wc -l)
6212         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6213
6214         cmd="$LFS find ! --mirror-state=ro --type f $td"
6215         nfiles=$($cmd | wc -l)
6216         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6217
6218         cmd="$LFS find --mirror-state=wp --type f $td"
6219         nfiles=$($cmd | wc -l)
6220         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6221
6222         cmd="$LFS find ! --mirror-state=sp --type f $td"
6223         nfiles=$($cmd | wc -l)
6224         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6225 }
6226 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6227
6228 test_57a() {
6229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6230         # note test will not do anything if MDS is not local
6231         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6232                 skip_env "ldiskfs only test"
6233         fi
6234         remote_mds_nodsh && skip "remote MDS with nodsh"
6235
6236         local MNTDEV="osd*.*MDT*.mntdev"
6237         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6238         [ -z "$DEV" ] && error "can't access $MNTDEV"
6239         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6240                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6241                         error "can't access $DEV"
6242                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6243                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6244                 rm $TMP/t57a.dump
6245         done
6246 }
6247 run_test 57a "verify MDS filesystem created with large inodes =="
6248
6249 test_57b() {
6250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6251         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6252                 skip_env "ldiskfs only test"
6253         fi
6254         remote_mds_nodsh && skip "remote MDS with nodsh"
6255
6256         local dir=$DIR/$tdir
6257         local filecount=100
6258         local file1=$dir/f1
6259         local fileN=$dir/f$filecount
6260
6261         rm -rf $dir || error "removing $dir"
6262         test_mkdir -c1 $dir
6263         local mdtidx=$($LFS getstripe -m $dir)
6264         local mdtname=MDT$(printf %04x $mdtidx)
6265         local facet=mds$((mdtidx + 1))
6266
6267         echo "mcreating $filecount files"
6268         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6269
6270         # verify that files do not have EAs yet
6271         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6272                 error "$file1 has an EA"
6273         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6274                 error "$fileN has an EA"
6275
6276         sync
6277         sleep 1
6278         df $dir  #make sure we get new statfs data
6279         local mdsfree=$(do_facet $facet \
6280                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6281         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6282         local file
6283
6284         echo "opening files to create objects/EAs"
6285         for file in $(seq -f $dir/f%g 1 $filecount); do
6286                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6287                         error "opening $file"
6288         done
6289
6290         # verify that files have EAs now
6291         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6292         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6293
6294         sleep 1  #make sure we get new statfs data
6295         df $dir
6296         local mdsfree2=$(do_facet $facet \
6297                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6298         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6299
6300         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6301                 if [ "$mdsfree" != "$mdsfree2" ]; then
6302                         error "MDC before $mdcfree != after $mdcfree2"
6303                 else
6304                         echo "MDC before $mdcfree != after $mdcfree2"
6305                         echo "unable to confirm if MDS has large inodes"
6306                 fi
6307         fi
6308         rm -rf $dir
6309 }
6310 run_test 57b "default LOV EAs are stored inside large inodes ==="
6311
6312 test_58() {
6313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6314         [ -z "$(which wiretest 2>/dev/null)" ] &&
6315                         skip_env "could not find wiretest"
6316
6317         wiretest
6318 }
6319 run_test 58 "verify cross-platform wire constants =============="
6320
6321 test_59() {
6322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6323
6324         echo "touch 130 files"
6325         createmany -o $DIR/f59- 130
6326         echo "rm 130 files"
6327         unlinkmany $DIR/f59- 130
6328         sync
6329         # wait for commitment of removal
6330         wait_delete_completed
6331 }
6332 run_test 59 "verify cancellation of llog records async ========="
6333
6334 TEST60_HEAD="test_60 run $RANDOM"
6335 test_60a() {
6336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6337         remote_mgs_nodsh && skip "remote MGS with nodsh"
6338         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6339                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6340                         skip_env "missing subtest run-llog.sh"
6341
6342         log "$TEST60_HEAD - from kernel mode"
6343         do_facet mgs "$LCTL dk > /dev/null"
6344         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6345         do_facet mgs $LCTL dk > $TMP/$tfile
6346
6347         # LU-6388: test llog_reader
6348         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6349         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6350         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6351                         skip_env "missing llog_reader"
6352         local fstype=$(facet_fstype mgs)
6353         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6354                 skip_env "Only for ldiskfs or zfs type mgs"
6355
6356         local mntpt=$(facet_mntpt mgs)
6357         local mgsdev=$(mgsdevname 1)
6358         local fid_list
6359         local fid
6360         local rec_list
6361         local rec
6362         local rec_type
6363         local obj_file
6364         local path
6365         local seq
6366         local oid
6367         local pass=true
6368
6369         #get fid and record list
6370         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6371                 tail -n 4))
6372         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6373                 tail -n 4))
6374         #remount mgs as ldiskfs or zfs type
6375         stop mgs || error "stop mgs failed"
6376         mount_fstype mgs || error "remount mgs failed"
6377         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6378                 fid=${fid_list[i]}
6379                 rec=${rec_list[i]}
6380                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6381                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6382                 oid=$((16#$oid))
6383
6384                 case $fstype in
6385                         ldiskfs )
6386                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6387                         zfs )
6388                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6389                 esac
6390                 echo "obj_file is $obj_file"
6391                 do_facet mgs $llog_reader $obj_file
6392
6393                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6394                         awk '{ print $3 }' | sed -e "s/^type=//g")
6395                 if [ $rec_type != $rec ]; then
6396                         echo "FAILED test_60a wrong record type $rec_type," \
6397                               "should be $rec"
6398                         pass=false
6399                         break
6400                 fi
6401
6402                 #check obj path if record type is LLOG_LOGID_MAGIC
6403                 if [ "$rec" == "1064553b" ]; then
6404                         path=$(do_facet mgs $llog_reader $obj_file |
6405                                 grep "path=" | awk '{ print $NF }' |
6406                                 sed -e "s/^path=//g")
6407                         if [ $obj_file != $mntpt/$path ]; then
6408                                 echo "FAILED test_60a wrong obj path" \
6409                                       "$montpt/$path, should be $obj_file"
6410                                 pass=false
6411                                 break
6412                         fi
6413                 fi
6414         done
6415         rm -f $TMP/$tfile
6416         #restart mgs before "error", otherwise it will block the next test
6417         stop mgs || error "stop mgs failed"
6418         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6419         $pass || error "test failed, see FAILED test_60a messages for specifics"
6420 }
6421 run_test 60a "llog_test run from kernel module and test llog_reader"
6422
6423 test_60b() { # bug 6411
6424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6425
6426         dmesg > $DIR/$tfile
6427         LLOG_COUNT=$(do_facet mgs dmesg |
6428                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6429                           /llog_[a-z]*.c:[0-9]/ {
6430                                 if (marker)
6431                                         from_marker++
6432                                 from_begin++
6433                           }
6434                           END {
6435                                 if (marker)
6436                                         print from_marker
6437                                 else
6438                                         print from_begin
6439                           }")
6440
6441         [[ $LLOG_COUNT -gt 120 ]] &&
6442                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6443 }
6444 run_test 60b "limit repeated messages from CERROR/CWARN"
6445
6446 test_60c() {
6447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6448
6449         echo "create 5000 files"
6450         createmany -o $DIR/f60c- 5000
6451 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6452         lctl set_param fail_loc=0x80000137
6453         unlinkmany $DIR/f60c- 5000
6454         lctl set_param fail_loc=0
6455 }
6456 run_test 60c "unlink file when mds full"
6457
6458 test_60d() {
6459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6460
6461         SAVEPRINTK=$(lctl get_param -n printk)
6462         # verify "lctl mark" is even working"
6463         MESSAGE="test message ID $RANDOM $$"
6464         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6465         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6466
6467         lctl set_param printk=0 || error "set lnet.printk failed"
6468         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6469         MESSAGE="new test message ID $RANDOM $$"
6470         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6471         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6472         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6473
6474         lctl set_param -n printk="$SAVEPRINTK"
6475 }
6476 run_test 60d "test printk console message masking"
6477
6478 test_60e() {
6479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6480         remote_mds_nodsh && skip "remote MDS with nodsh"
6481
6482         touch $DIR/$tfile
6483 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6484         do_facet mds1 lctl set_param fail_loc=0x15b
6485         rm $DIR/$tfile
6486 }
6487 run_test 60e "no space while new llog is being created"
6488
6489 test_60g() {
6490         local pid
6491
6492         test_mkdir -c $MDSCOUNT $DIR/$tdir
6493         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6494
6495         (
6496                 local index=0
6497                 while true; do
6498                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6499                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6500                         index=$((index + 1))
6501                 done
6502         ) &
6503
6504         pid=$!
6505
6506         for i in $(seq 100); do 
6507                 # define OBD_FAIL_OSD_TXN_START    0x19a
6508                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6509                 usleep 100
6510         done
6511
6512         kill -9 $pid
6513
6514         mkdir $DIR/$tdir/new || error "mkdir failed"
6515         rmdir $DIR/$tdir/new || error "rmdir failed"
6516 }
6517 run_test 60g "transaction abort won't cause MDT hung"
6518
6519 test_61a() {
6520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6521
6522         f="$DIR/f61"
6523         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6524         cancel_lru_locks osc
6525         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6526         sync
6527 }
6528 run_test 61a "mmap() writes don't make sync hang ================"
6529
6530 test_61b() {
6531         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6532 }
6533 run_test 61b "mmap() of unstriped file is successful"
6534
6535 # bug 2330 - insufficient obd_match error checking causes LBUG
6536 test_62() {
6537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6538
6539         f="$DIR/f62"
6540         echo foo > $f
6541         cancel_lru_locks osc
6542         lctl set_param fail_loc=0x405
6543         cat $f && error "cat succeeded, expect -EIO"
6544         lctl set_param fail_loc=0
6545 }
6546 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6547 # match every page all of the time.
6548 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6549
6550 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6551 # Though this test is irrelevant anymore, it helped to reveal some
6552 # other grant bugs (LU-4482), let's keep it.
6553 test_63a() {   # was test_63
6554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6555
6556         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6557
6558         for i in `seq 10` ; do
6559                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6560                 sleep 5
6561                 kill $!
6562                 sleep 1
6563         done
6564
6565         rm -f $DIR/f63 || true
6566 }
6567 run_test 63a "Verify oig_wait interruption does not crash ======="
6568
6569 # bug 2248 - async write errors didn't return to application on sync
6570 # bug 3677 - async write errors left page locked
6571 test_63b() {
6572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6573
6574         debugsave
6575         lctl set_param debug=-1
6576
6577         # ensure we have a grant to do async writes
6578         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6579         rm $DIR/$tfile
6580
6581         sync    # sync lest earlier test intercept the fail_loc
6582
6583         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6584         lctl set_param fail_loc=0x80000406
6585         $MULTIOP $DIR/$tfile Owy && \
6586                 error "sync didn't return ENOMEM"
6587         sync; sleep 2; sync     # do a real sync this time to flush page
6588         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6589                 error "locked page left in cache after async error" || true
6590         debugrestore
6591 }
6592 run_test 63b "async write errors should be returned to fsync ==="
6593
6594 test_64a () {
6595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6596
6597         df $DIR
6598         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6599 }
6600 run_test 64a "verify filter grant calculations (in kernel) ====="
6601
6602 test_64b () {
6603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6604
6605         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6606 }
6607 run_test 64b "check out-of-space detection on client"
6608
6609 test_64c() {
6610         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6611 }
6612 run_test 64c "verify grant shrink"
6613
6614 # this does exactly what osc_request.c:osc_announce_cached() does in
6615 # order to calculate max amount of grants to ask from server
6616 want_grant() {
6617         local tgt=$1
6618
6619         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6620         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6621
6622         ((rpc_in_flight ++));
6623         nrpages=$((nrpages * rpc_in_flight))
6624
6625         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6626
6627         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6628
6629         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6630         local undirty=$((nrpages * PAGE_SIZE))
6631
6632         local max_extent_pages
6633         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6634             grep grant_max_extent_size | awk '{print $2}')
6635         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6636         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6637         local grant_extent_tax
6638         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6639             grep grant_extent_tax | awk '{print $2}')
6640
6641         undirty=$((undirty + nrextents * grant_extent_tax))
6642
6643         echo $undirty
6644 }
6645
6646 # this is size of unit for grant allocation. It should be equal to
6647 # what tgt_grant.c:tgt_grant_chunk() calculates
6648 grant_chunk() {
6649         local tgt=$1
6650         local max_brw_size
6651         local grant_extent_tax
6652
6653         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6654             grep max_brw_size | awk '{print $2}')
6655
6656         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6657             grep grant_extent_tax | awk '{print $2}')
6658
6659         echo $(((max_brw_size + grant_extent_tax) * 2))
6660 }
6661
6662 test_64d() {
6663         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6664                 skip "OST < 2.10.55 doesn't limit grants enough"
6665
6666         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6667         local file=$DIR/$tfile
6668
6669         [[ $($LCTL get_param osc.${tgt}.import |
6670              grep "connect_flags:.*grant_param") ]] ||
6671                 skip "no grant_param connect flag"
6672
6673         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6674
6675         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6676
6677         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6678         stack_trap "rm -f $file" EXIT
6679
6680         $LFS setstripe $file -i 0 -c 1
6681         dd if=/dev/zero of=$file bs=1M count=1000 &
6682         ddpid=$!
6683
6684         while true
6685         do
6686                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6687                 if [[ $cur_grant -gt $max_cur_granted ]]
6688                 then
6689                         kill $ddpid
6690                         error "cur_grant $cur_grant > $max_cur_granted"
6691                 fi
6692                 kill -0 $ddpid
6693                 [[ $? -ne 0 ]] && break;
6694                 sleep 2
6695         done
6696
6697         rm -f $DIR/$tfile
6698         wait_delete_completed
6699         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6700 }
6701 run_test 64d "check grant limit exceed"
6702
6703 # bug 1414 - set/get directories' stripe info
6704 test_65a() {
6705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6706
6707         test_mkdir $DIR/$tdir
6708         touch $DIR/$tdir/f1
6709         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6710 }
6711 run_test 65a "directory with no stripe info"
6712
6713 test_65b() {
6714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6715
6716         test_mkdir $DIR/$tdir
6717         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6718
6719         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6720                                                 error "setstripe"
6721         touch $DIR/$tdir/f2
6722         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6723 }
6724 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6725
6726 test_65c() {
6727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6728         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6729
6730         test_mkdir $DIR/$tdir
6731         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6732
6733         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6734                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6735         touch $DIR/$tdir/f3
6736         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6737 }
6738 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6739
6740 test_65d() {
6741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6742
6743         test_mkdir $DIR/$tdir
6744         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6745         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6746
6747         if [[ $STRIPECOUNT -le 0 ]]; then
6748                 sc=1
6749         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6750 #LOV_MAX_STRIPE_COUNT is 2000
6751                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6752         else
6753                 sc=$(($STRIPECOUNT - 1))
6754         fi
6755         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6756         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6757         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6758                 error "lverify failed"
6759 }
6760 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6761
6762 test_65e() {
6763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6764
6765         test_mkdir $DIR/$tdir
6766
6767         $LFS setstripe $DIR/$tdir || error "setstripe"
6768         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6769                                         error "no stripe info failed"
6770         touch $DIR/$tdir/f6
6771         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6772 }
6773 run_test 65e "directory setstripe defaults"
6774
6775 test_65f() {
6776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6777
6778         test_mkdir $DIR/${tdir}f
6779         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6780                 error "setstripe succeeded" || true
6781 }
6782 run_test 65f "dir setstripe permission (should return error) ==="
6783
6784 test_65g() {
6785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6786
6787         test_mkdir $DIR/$tdir
6788         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6789
6790         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6791                 error "setstripe -S failed"
6792         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6793         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6794                 error "delete default stripe failed"
6795 }
6796 run_test 65g "directory setstripe -d"
6797
6798 test_65h() {
6799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6800
6801         test_mkdir $DIR/$tdir
6802         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6803
6804         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6805                 error "setstripe -S failed"
6806         test_mkdir $DIR/$tdir/dd1
6807         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6808                 error "stripe info inherit failed"
6809 }
6810 run_test 65h "directory stripe info inherit ===================="
6811
6812 test_65i() {
6813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6814
6815         save_layout_restore_at_exit $MOUNT
6816
6817         # bug6367: set non-default striping on root directory
6818         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6819
6820         # bug12836: getstripe on -1 default directory striping
6821         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6822
6823         # bug12836: getstripe -v on -1 default directory striping
6824         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6825
6826         # bug12836: new find on -1 default directory striping
6827         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6828 }
6829 run_test 65i "various tests to set root directory striping"
6830
6831 test_65j() { # bug6367
6832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6833
6834         sync; sleep 1
6835
6836         # if we aren't already remounting for each test, do so for this test
6837         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6838                 cleanup || error "failed to unmount"
6839                 setup
6840         fi
6841
6842         save_layout_restore_at_exit $MOUNT
6843
6844         $LFS setstripe -d $MOUNT || error "setstripe failed"
6845 }
6846 run_test 65j "set default striping on root directory (bug 6367)="
6847
6848 cleanup_65k() {
6849         rm -rf $DIR/$tdir
6850         wait_delete_completed
6851         do_facet $SINGLEMDS "lctl set_param -n \
6852                 osp.$ost*MDT0000.max_create_count=$max_count"
6853         do_facet $SINGLEMDS "lctl set_param -n \
6854                 osp.$ost*MDT0000.create_count=$count"
6855         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6856         echo $INACTIVE_OSC "is Activate"
6857
6858         wait_osc_import_state mds ost$ostnum FULL
6859 }
6860
6861 test_65k() { # bug11679
6862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6864         remote_mds_nodsh && skip "remote MDS with nodsh"
6865
6866         local disable_precreate=true
6867         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6868                 disable_precreate=false
6869
6870         echo "Check OST status: "
6871         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6872                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6873
6874         for OSC in $MDS_OSCS; do
6875                 echo $OSC "is active"
6876                 do_facet $SINGLEMDS lctl --device %$OSC activate
6877         done
6878
6879         for INACTIVE_OSC in $MDS_OSCS; do
6880                 local ost=$(osc_to_ost $INACTIVE_OSC)
6881                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6882                                lov.*md*.target_obd |
6883                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6884
6885                 mkdir -p $DIR/$tdir
6886                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6887                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6888
6889                 echo "Deactivate: " $INACTIVE_OSC
6890                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6891
6892                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6893                               osp.$ost*MDT0000.create_count")
6894                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6895                                   osp.$ost*MDT0000.max_create_count")
6896                 $disable_precreate &&
6897                         do_facet $SINGLEMDS "lctl set_param -n \
6898                                 osp.$ost*MDT0000.max_create_count=0"
6899
6900                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6901                         [ -f $DIR/$tdir/$idx ] && continue
6902                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6903                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6904                                 { cleanup_65k;
6905                                   error "setstripe $idx should succeed"; }
6906                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6907                 done
6908                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6909                 rmdir $DIR/$tdir
6910
6911                 do_facet $SINGLEMDS "lctl set_param -n \
6912                         osp.$ost*MDT0000.max_create_count=$max_count"
6913                 do_facet $SINGLEMDS "lctl set_param -n \
6914                         osp.$ost*MDT0000.create_count=$count"
6915                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6916                 echo $INACTIVE_OSC "is Activate"
6917
6918                 wait_osc_import_state mds ost$ostnum FULL
6919         done
6920 }
6921 run_test 65k "validate manual striping works properly with deactivated OSCs"
6922
6923 test_65l() { # bug 12836
6924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6925
6926         test_mkdir -p $DIR/$tdir/test_dir
6927         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6928         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6929 }
6930 run_test 65l "lfs find on -1 stripe dir ========================"
6931
6932 test_65m() {
6933         local layout=$(save_layout $MOUNT)
6934         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6935                 restore_layout $MOUNT $layout
6936                 error "setstripe should fail by non-root users"
6937         }
6938         true
6939 }
6940 run_test 65m "normal user can't set filesystem default stripe"
6941
6942 test_65n() {
6943         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6944         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6945                 skip "Need MDS version at least 2.12.50"
6946         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6947
6948         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6949         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6950         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6951
6952         local root_layout=$(save_layout $MOUNT)
6953         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6954
6955         # new subdirectory under root directory should not inherit
6956         # the default layout from root
6957         local dir1=$MOUNT/$tdir-1
6958         mkdir $dir1 || error "mkdir $dir1 failed"
6959         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6960                 error "$dir1 shouldn't have LOV EA"
6961
6962         # delete the default layout on root directory
6963         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6964
6965         local dir2=$MOUNT/$tdir-2
6966         mkdir $dir2 || error "mkdir $dir2 failed"
6967         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6968                 error "$dir2 shouldn't have LOV EA"
6969
6970         # set a new striping pattern on root directory
6971         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6972         local new_def_stripe_size=$((def_stripe_size * 2))
6973         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6974                 error "set stripe size on $MOUNT failed"
6975
6976         # new file created in $dir2 should inherit the new stripe size from
6977         # the filesystem default
6978         local file2=$dir2/$tfile-2
6979         touch $file2 || error "touch $file2 failed"
6980
6981         local file2_stripe_size=$($LFS getstripe -S $file2)
6982         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6983                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6984
6985         local dir3=$MOUNT/$tdir-3
6986         mkdir $dir3 || error "mkdir $dir3 failed"
6987         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6988                 error "$dir3 shouldn't have LOV EA"
6989
6990         # set OST pool on root directory
6991         local pool=$TESTNAME
6992         pool_add $pool || error "add $pool failed"
6993         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6994                 error "add targets to $pool failed"
6995
6996         $LFS setstripe -p $pool $MOUNT ||
6997                 error "set OST pool on $MOUNT failed"
6998
6999         # new file created in $dir3 should inherit the pool from
7000         # the filesystem default
7001         local file3=$dir3/$tfile-3
7002         touch $file3 || error "touch $file3 failed"
7003
7004         local file3_pool=$($LFS getstripe -p $file3)
7005         [[ "$file3_pool" = "$pool" ]] ||
7006                 error "$file3 didn't inherit OST pool $pool"
7007
7008         local dir4=$MOUNT/$tdir-4
7009         mkdir $dir4 || error "mkdir $dir4 failed"
7010         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7011                 error "$dir4 shouldn't have LOV EA"
7012
7013         # new file created in $dir4 should inherit the pool from
7014         # the filesystem default
7015         local file4=$dir4/$tfile-4
7016         touch $file4 || error "touch $file4 failed"
7017
7018         local file4_pool=$($LFS getstripe -p $file4)
7019         [[ "$file4_pool" = "$pool" ]] ||
7020                 error "$file4 didn't inherit OST pool $pool"
7021
7022         # new subdirectory under non-root directory should inherit
7023         # the default layout from its parent directory
7024         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7025                 error "set directory layout on $dir4 failed"
7026
7027         local dir5=$dir4/$tdir-5
7028         mkdir $dir5 || error "mkdir $dir5 failed"
7029
7030         local dir4_layout=$(get_layout_param $dir4)
7031         local dir5_layout=$(get_layout_param $dir5)
7032         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7033                 error "$dir5 should inherit the default layout from $dir4"
7034 }
7035 run_test 65n "don't inherit default layout from root for new subdirectories"
7036
7037 # bug 2543 - update blocks count on client
7038 test_66() {
7039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7040
7041         COUNT=${COUNT:-8}
7042         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7043         sync; sync_all_data; sync; sync_all_data
7044         cancel_lru_locks osc
7045         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7046         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7047 }
7048 run_test 66 "update inode blocks count on client ==============="
7049
7050 meminfo() {
7051         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7052 }
7053
7054 swap_used() {
7055         swapon -s | awk '($1 == "'$1'") { print $4 }'
7056 }
7057
7058 # bug5265, obdfilter oa2dentry return -ENOENT
7059 # #define OBD_FAIL_SRV_ENOENT 0x217
7060 test_69() {
7061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7062         remote_ost_nodsh && skip "remote OST with nodsh"
7063
7064         f="$DIR/$tfile"
7065         $LFS setstripe -c 1 -i 0 $f
7066
7067         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7068
7069         do_facet ost1 lctl set_param fail_loc=0x217
7070         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7071         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7072
7073         do_facet ost1 lctl set_param fail_loc=0
7074         $DIRECTIO write $f 0 2 || error "write error"
7075
7076         cancel_lru_locks osc
7077         $DIRECTIO read $f 0 1 || error "read error"
7078
7079         do_facet ost1 lctl set_param fail_loc=0x217
7080         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7081
7082         do_facet ost1 lctl set_param fail_loc=0
7083         rm -f $f
7084 }
7085 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7086
7087 test_71() {
7088         test_mkdir $DIR/$tdir
7089         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7090         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7091 }
7092 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7093
7094 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7096         [ "$RUNAS_ID" = "$UID" ] &&
7097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7098         # Check that testing environment is properly set up. Skip if not
7099         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7100                 skip_env "User $RUNAS_ID does not exist - skipping"
7101
7102         touch $DIR/$tfile
7103         chmod 777 $DIR/$tfile
7104         chmod ug+s $DIR/$tfile
7105         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7106                 error "$RUNAS dd $DIR/$tfile failed"
7107         # See if we are still setuid/sgid
7108         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7109                 error "S/gid is not dropped on write"
7110         # Now test that MDS is updated too
7111         cancel_lru_locks mdc
7112         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7113                 error "S/gid is not dropped on MDS"
7114         rm -f $DIR/$tfile
7115 }
7116 run_test 72a "Test that remove suid works properly (bug5695) ===="
7117
7118 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7119         local perm
7120
7121         [ "$RUNAS_ID" = "$UID" ] &&
7122                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7123         [ "$RUNAS_ID" -eq 0 ] &&
7124                 skip_env "RUNAS_ID = 0 -- skipping"
7125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7126         # Check that testing environment is properly set up. Skip if not
7127         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7128                 skip_env "User $RUNAS_ID does not exist - skipping"
7129
7130         touch $DIR/${tfile}-f{g,u}
7131         test_mkdir $DIR/${tfile}-dg
7132         test_mkdir $DIR/${tfile}-du
7133         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7134         chmod g+s $DIR/${tfile}-{f,d}g
7135         chmod u+s $DIR/${tfile}-{f,d}u
7136         for perm in 777 2777 4777; do
7137                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7138                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7139                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7140                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7141         done
7142         true
7143 }
7144 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7145
7146 # bug 3462 - multiple simultaneous MDC requests
7147 test_73() {
7148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7149
7150         test_mkdir $DIR/d73-1
7151         test_mkdir $DIR/d73-2
7152         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7153         pid1=$!
7154
7155         lctl set_param fail_loc=0x80000129
7156         $MULTIOP $DIR/d73-1/f73-2 Oc &
7157         sleep 1
7158         lctl set_param fail_loc=0
7159
7160         $MULTIOP $DIR/d73-2/f73-3 Oc &
7161         pid3=$!
7162
7163         kill -USR1 $pid1
7164         wait $pid1 || return 1
7165
7166         sleep 25
7167
7168         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7169         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7170         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7171
7172         rm -rf $DIR/d73-*
7173 }
7174 run_test 73 "multiple MDC requests (should not deadlock)"
7175
7176 test_74a() { # bug 6149, 6184
7177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7178
7179         touch $DIR/f74a
7180         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7181         #
7182         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7183         # will spin in a tight reconnection loop
7184         $LCTL set_param fail_loc=0x8000030e
7185         # get any lock that won't be difficult - lookup works.
7186         ls $DIR/f74a
7187         $LCTL set_param fail_loc=0
7188         rm -f $DIR/f74a
7189         true
7190 }
7191 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7192
7193 test_74b() { # bug 13310
7194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7195
7196         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7197         #
7198         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7199         # will spin in a tight reconnection loop
7200         $LCTL set_param fail_loc=0x8000030e
7201         # get a "difficult" lock
7202         touch $DIR/f74b
7203         $LCTL set_param fail_loc=0
7204         rm -f $DIR/f74b
7205         true
7206 }
7207 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7208
7209 test_74c() {
7210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7211
7212         #define OBD_FAIL_LDLM_NEW_LOCK
7213         $LCTL set_param fail_loc=0x319
7214         touch $DIR/$tfile && error "touch successful"
7215         $LCTL set_param fail_loc=0
7216         true
7217 }
7218 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7219
7220 num_inodes() {
7221         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7222 }
7223
7224 test_76() { # Now for bug 20433, added originally in bug 1443
7225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7226
7227         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7228
7229         cancel_lru_locks osc
7230         BEFORE_INODES=$(num_inodes)
7231         echo "before inodes: $BEFORE_INODES"
7232         local COUNT=1000
7233         [ "$SLOW" = "no" ] && COUNT=100
7234         for i in $(seq $COUNT); do
7235                 touch $DIR/$tfile
7236                 rm -f $DIR/$tfile
7237         done
7238         cancel_lru_locks osc
7239         AFTER_INODES=$(num_inodes)
7240         echo "after inodes: $AFTER_INODES"
7241         local wait=0
7242         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7243                 sleep 2
7244                 AFTER_INODES=$(num_inodes)
7245                 wait=$((wait+2))
7246                 echo "wait $wait seconds inodes: $AFTER_INODES"
7247                 if [ $wait -gt 30 ]; then
7248                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7249                 fi
7250         done
7251 }
7252 run_test 76 "confirm clients recycle inodes properly ===="
7253
7254
7255 export ORIG_CSUM=""
7256 set_checksums()
7257 {
7258         # Note: in sptlrpc modes which enable its own bulk checksum, the
7259         # original crc32_le bulk checksum will be automatically disabled,
7260         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7261         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7262         # In this case set_checksums() will not be no-op, because sptlrpc
7263         # bulk checksum will be enabled all through the test.
7264
7265         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7266         lctl set_param -n osc.*.checksums $1
7267         return 0
7268 }
7269
7270 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7271                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7272 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7273                              tr -d [] | head -n1)}
7274 set_checksum_type()
7275 {
7276         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7277         log "set checksum type to $1"
7278         return 0
7279 }
7280 F77_TMP=$TMP/f77-temp
7281 F77SZ=8
7282 setup_f77() {
7283         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7284                 error "error writing to $F77_TMP"
7285 }
7286
7287 test_77a() { # bug 10889
7288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7289         $GSS && skip_env "could not run with gss"
7290
7291         [ ! -f $F77_TMP ] && setup_f77
7292         set_checksums 1
7293         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7294         set_checksums 0
7295         rm -f $DIR/$tfile
7296 }
7297 run_test 77a "normal checksum read/write operation"
7298
7299 test_77b() { # bug 10889
7300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7301         $GSS && skip_env "could not run with gss"
7302
7303         [ ! -f $F77_TMP ] && setup_f77
7304         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7305         $LCTL set_param fail_loc=0x80000409
7306         set_checksums 1
7307
7308         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7309                 error "dd error: $?"
7310         $LCTL set_param fail_loc=0
7311
7312         for algo in $CKSUM_TYPES; do
7313                 cancel_lru_locks osc
7314                 set_checksum_type $algo
7315                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7316                 $LCTL set_param fail_loc=0x80000408
7317                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7318                 $LCTL set_param fail_loc=0
7319         done
7320         set_checksums 0
7321         set_checksum_type $ORIG_CSUM_TYPE
7322         rm -f $DIR/$tfile
7323 }
7324 run_test 77b "checksum error on client write, read"
7325
7326 cleanup_77c() {
7327         trap 0
7328         set_checksums 0
7329         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7330         $check_ost &&
7331                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7332         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7333         $check_ost && [ -n "$ost_file_prefix" ] &&
7334                 do_facet ost1 rm -f ${ost_file_prefix}\*
7335 }
7336
7337 test_77c() {
7338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7339         $GSS && skip_env "could not run with gss"
7340         remote_ost_nodsh && skip "remote OST with nodsh"
7341
7342         local bad1
7343         local osc_file_prefix
7344         local osc_file
7345         local check_ost=false
7346         local ost_file_prefix
7347         local ost_file
7348         local orig_cksum
7349         local dump_cksum
7350         local fid
7351
7352         # ensure corruption will occur on first OSS/OST
7353         $LFS setstripe -i 0 $DIR/$tfile
7354
7355         [ ! -f $F77_TMP ] && setup_f77
7356         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7357                 error "dd write error: $?"
7358         fid=$($LFS path2fid $DIR/$tfile)
7359
7360         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7361         then
7362                 check_ost=true
7363                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7364                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7365         else
7366                 echo "OSS do not support bulk pages dump upon error"
7367         fi
7368
7369         osc_file_prefix=$($LCTL get_param -n debug_path)
7370         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7371
7372         trap cleanup_77c EXIT
7373
7374         set_checksums 1
7375         # enable bulk pages dump upon error on Client
7376         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7377         # enable bulk pages dump upon error on OSS
7378         $check_ost &&
7379                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7380
7381         # flush Client cache to allow next read to reach OSS
7382         cancel_lru_locks osc
7383
7384         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7385         $LCTL set_param fail_loc=0x80000408
7386         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7387         $LCTL set_param fail_loc=0
7388
7389         rm -f $DIR/$tfile
7390
7391         # check cksum dump on Client
7392         osc_file=$(ls ${osc_file_prefix}*)
7393         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7394         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7395         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7396         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7397         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7398                      cksum)
7399         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7400         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7401                 error "dump content does not match on Client"
7402
7403         $check_ost || skip "No need to check cksum dump on OSS"
7404
7405         # check cksum dump on OSS
7406         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7407         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7408         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7409         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7410         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7411                 error "dump content does not match on OSS"
7412
7413         cleanup_77c
7414 }
7415 run_test 77c "checksum error on client read with debug"
7416
7417 test_77d() { # bug 10889
7418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7419         $GSS && skip_env "could not run with gss"
7420
7421         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7422         $LCTL set_param fail_loc=0x80000409
7423         set_checksums 1
7424         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7425                 error "direct write: rc=$?"
7426         $LCTL set_param fail_loc=0
7427         set_checksums 0
7428
7429         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7430         $LCTL set_param fail_loc=0x80000408
7431         set_checksums 1
7432         cancel_lru_locks osc
7433         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7434                 error "direct read: rc=$?"
7435         $LCTL set_param fail_loc=0
7436         set_checksums 0
7437 }
7438 run_test 77d "checksum error on OST direct write, read"
7439
7440 test_77f() { # bug 10889
7441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7442         $GSS && skip_env "could not run with gss"
7443
7444         set_checksums 1
7445         for algo in $CKSUM_TYPES; do
7446                 cancel_lru_locks osc
7447                 set_checksum_type $algo
7448                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7449                 $LCTL set_param fail_loc=0x409
7450                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7451                         error "direct write succeeded"
7452                 $LCTL set_param fail_loc=0
7453         done
7454         set_checksum_type $ORIG_CSUM_TYPE
7455         set_checksums 0
7456 }
7457 run_test 77f "repeat checksum error on write (expect error)"
7458
7459 test_77g() { # bug 10889
7460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7461         $GSS && skip_env "could not run with gss"
7462         remote_ost_nodsh && skip "remote OST with nodsh"
7463
7464         [ ! -f $F77_TMP ] && setup_f77
7465
7466         local file=$DIR/$tfile
7467         stack_trap "rm -f $file" EXIT
7468
7469         $LFS setstripe -c 1 -i 0 $file
7470         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7471         do_facet ost1 lctl set_param fail_loc=0x8000021a
7472         set_checksums 1
7473         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7474                 error "write error: rc=$?"
7475         do_facet ost1 lctl set_param fail_loc=0
7476         set_checksums 0
7477
7478         cancel_lru_locks osc
7479         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7480         do_facet ost1 lctl set_param fail_loc=0x8000021b
7481         set_checksums 1
7482         cmp $F77_TMP $file || error "file compare failed"
7483         do_facet ost1 lctl set_param fail_loc=0
7484         set_checksums 0
7485 }
7486 run_test 77g "checksum error on OST write, read"
7487
7488 test_77k() { # LU-10906
7489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7490         $GSS && skip_env "could not run with gss"
7491
7492         local cksum_param="osc.$FSNAME*.checksums"
7493         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7494         local checksum
7495         local i
7496
7497         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7498         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7499         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7500                 EXIT
7501
7502         for i in 0 1; do
7503                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7504                         error "failed to set checksum=$i on MGS"
7505                 wait_update $HOSTNAME "$get_checksum" $i
7506                 #remount
7507                 echo "remount client, checksum should be $i"
7508                 remount_client $MOUNT || "failed to remount client"
7509                 checksum=$(eval $get_checksum)
7510                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7511         done
7512         # remove persistent param to avoid races with checksum mountopt below
7513         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7514                 error "failed to delete checksum on MGS"
7515
7516         for opt in "checksum" "nochecksum"; do
7517                 #remount with mount option
7518                 echo "remount client with option $opt, checksum should be $i"
7519                 umount_client $MOUNT || "failed to umount client"
7520                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7521                         "failed to mount client with option '$opt'"
7522                 checksum=$(eval $get_checksum)
7523                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7524                 i=$((i - 1))
7525         done
7526
7527         remount_client $MOUNT || "failed to remount client"
7528 }
7529 run_test 77k "enable/disable checksum correctly"
7530
7531 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7532 rm -f $F77_TMP
7533 unset F77_TMP
7534
7535 cleanup_test_78() {
7536         trap 0
7537         rm -f $DIR/$tfile
7538 }
7539
7540 test_78() { # bug 10901
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542         remote_ost || skip_env "local OST"
7543
7544         NSEQ=5
7545         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7546         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7547         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7548         echo "MemTotal: $MEMTOTAL"
7549
7550         # reserve 256MB of memory for the kernel and other running processes,
7551         # and then take 1/2 of the remaining memory for the read/write buffers.
7552         if [ $MEMTOTAL -gt 512 ] ;then
7553                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7554         else
7555                 # for those poor memory-starved high-end clusters...
7556                 MEMTOTAL=$((MEMTOTAL / 2))
7557         fi
7558         echo "Mem to use for directio: $MEMTOTAL"
7559
7560         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7561         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7562         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7563         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7564                 head -n1)
7565         echo "Smallest OST: $SMALLESTOST"
7566         [[ $SMALLESTOST -lt 10240 ]] &&
7567                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7568
7569         trap cleanup_test_78 EXIT
7570
7571         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7572                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7573
7574         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7575         echo "File size: $F78SIZE"
7576         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7577         for i in $(seq 1 $NSEQ); do
7578                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7579                 echo directIO rdwr round $i of $NSEQ
7580                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7581         done
7582
7583         cleanup_test_78
7584 }
7585 run_test 78 "handle large O_DIRECT writes correctly ============"
7586
7587 test_79() { # bug 12743
7588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7589
7590         wait_delete_completed
7591
7592         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7593         BKFREE=$(calc_osc_kbytes kbytesfree)
7594         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7595
7596         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7597         DFTOTAL=`echo $STRING | cut -d, -f1`
7598         DFUSED=`echo $STRING  | cut -d, -f2`
7599         DFAVAIL=`echo $STRING | cut -d, -f3`
7600         DFFREE=$(($DFTOTAL - $DFUSED))
7601
7602         ALLOWANCE=$((64 * $OSTCOUNT))
7603
7604         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7605            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7606                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7607         fi
7608         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7609            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7610                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7611         fi
7612         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7613            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7614                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7615         fi
7616 }
7617 run_test 79 "df report consistency check ======================="
7618
7619 test_80() { # bug 10718
7620         remote_ost_nodsh && skip "remote OST with nodsh"
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7622
7623         # relax strong synchronous semantics for slow backends like ZFS
7624         local soc="obdfilter.*.sync_on_lock_cancel"
7625         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7626         local hosts=
7627         if [ "$soc_old" != "never" ] &&
7628                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7629                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7630                                 facet_active_host $host; done | sort -u)
7631                         do_nodes $hosts lctl set_param $soc=never
7632         fi
7633
7634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7635         sync; sleep 1; sync
7636         local BEFORE=`date +%s`
7637         cancel_lru_locks osc
7638         local AFTER=`date +%s`
7639         local DIFF=$((AFTER-BEFORE))
7640         if [ $DIFF -gt 1 ] ; then
7641                 error "elapsed for 1M@1T = $DIFF"
7642         fi
7643
7644         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7645
7646         rm -f $DIR/$tfile
7647 }
7648 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7649
7650 test_81a() { # LU-456
7651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7652         remote_ost_nodsh && skip "remote OST with nodsh"
7653
7654         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7655         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7656         do_facet ost1 lctl set_param fail_loc=0x80000228
7657
7658         # write should trigger a retry and success
7659         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7660         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7661         RC=$?
7662         if [ $RC -ne 0 ] ; then
7663                 error "write should success, but failed for $RC"
7664         fi
7665 }
7666 run_test 81a "OST should retry write when get -ENOSPC ==============="
7667
7668 test_81b() { # LU-456
7669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7670         remote_ost_nodsh && skip "remote OST with nodsh"
7671
7672         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7673         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7674         do_facet ost1 lctl set_param fail_loc=0x228
7675
7676         # write should retry several times and return -ENOSPC finally
7677         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7678         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7679         RC=$?
7680         ENOSPC=28
7681         if [ $RC -ne $ENOSPC ] ; then
7682                 error "dd should fail for -ENOSPC, but succeed."
7683         fi
7684 }
7685 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7686
7687 test_82() { # LU-1031
7688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7689         local gid1=14091995
7690         local gid2=16022000
7691
7692         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7693         local MULTIPID1=$!
7694         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7695         local MULTIPID2=$!
7696         kill -USR1 $MULTIPID2
7697         sleep 2
7698         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7699                 error "First grouplock does not block second one"
7700         else
7701                 echo "Second grouplock blocks first one"
7702         fi
7703         kill -USR1 $MULTIPID1
7704         wait $MULTIPID1
7705         wait $MULTIPID2
7706 }
7707 run_test 82 "Basic grouplock test"
7708
7709 test_99() {
7710         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7711
7712         test_mkdir $DIR/$tdir.cvsroot
7713         chown $RUNAS_ID $DIR/$tdir.cvsroot
7714
7715         cd $TMP
7716         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7717
7718         cd /etc/init.d
7719         # some versions of cvs import exit(1) when asked to import links or
7720         # files they can't read.  ignore those files.
7721         local toignore=$(find . -type l -printf '-I %f\n' -o \
7722                          ! -perm /4 -printf '-I %f\n')
7723         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7724                 $tdir.reposname vtag rtag
7725
7726         cd $DIR
7727         test_mkdir $DIR/$tdir.reposname
7728         chown $RUNAS_ID $DIR/$tdir.reposname
7729         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7730
7731         cd $DIR/$tdir.reposname
7732         $RUNAS touch foo99
7733         $RUNAS cvs add -m 'addmsg' foo99
7734         $RUNAS cvs update
7735         $RUNAS cvs commit -m 'nomsg' foo99
7736         rm -fr $DIR/$tdir.cvsroot
7737 }
7738 run_test 99 "cvs strange file/directory operations"
7739
7740 test_100() {
7741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7742         [[ "$NETTYPE" =~ tcp ]] ||
7743                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7744         remote_ost_nodsh && skip "remote OST with nodsh"
7745         remote_mds_nodsh && skip "remote MDS with nodsh"
7746         remote_servers ||
7747                 skip "useless for local single node setup"
7748
7749         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7750                 [ "$PROT" != "tcp" ] && continue
7751                 RPORT=$(echo $REMOTE | cut -d: -f2)
7752                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7753
7754                 rc=0
7755                 LPORT=`echo $LOCAL | cut -d: -f2`
7756                 if [ $LPORT -ge 1024 ]; then
7757                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7758                         netstat -tna
7759                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7760                 fi
7761         done
7762         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7763 }
7764 run_test 100 "check local port using privileged port ==========="
7765
7766 function get_named_value()
7767 {
7768     local tag
7769
7770     tag=$1
7771     while read ;do
7772         line=$REPLY
7773         case $line in
7774         $tag*)
7775             echo $line | sed "s/^$tag[ ]*//"
7776             break
7777             ;;
7778         esac
7779     done
7780 }
7781
7782 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7783                    awk '/^max_cached_mb/ { print $2 }')
7784
7785 cleanup_101a() {
7786         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7787         trap 0
7788 }
7789
7790 test_101a() {
7791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7792         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7793
7794         local s
7795         local discard
7796         local nreads=10000
7797         local cache_limit=32
7798
7799         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7800         trap cleanup_101a EXIT
7801         $LCTL set_param -n llite.*.read_ahead_stats 0
7802         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7803
7804         #
7805         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7806         #
7807         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7808         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7809
7810         discard=0
7811         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7812                 get_named_value 'read but discarded' | cut -d" " -f1); do
7813                         discard=$(($discard + $s))
7814         done
7815         cleanup_101a
7816
7817         if [[ $(($discard * 10)) -gt $nreads ]]; then
7818                 $LCTL get_param osc.*-osc*.rpc_stats
7819                 $LCTL get_param llite.*.read_ahead_stats
7820                 error "too many ($discard) discarded pages"
7821         fi
7822         rm -f $DIR/$tfile || true
7823 }
7824 run_test 101a "check read-ahead for random reads"
7825
7826 setup_test101bc() {
7827         test_mkdir $DIR/$tdir
7828         local ssize=$1
7829         local FILE_LENGTH=$2
7830         STRIPE_OFFSET=0
7831
7832         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7833
7834         local list=$(comma_list $(osts_nodes))
7835         set_osd_param $list '' read_cache_enable 0
7836         set_osd_param $list '' writethrough_cache_enable 0
7837
7838         trap cleanup_test101bc EXIT
7839         # prepare the read-ahead file
7840         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7841
7842         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7843                                 count=$FILE_SIZE_MB 2> /dev/null
7844
7845 }
7846
7847 cleanup_test101bc() {
7848         trap 0
7849         rm -rf $DIR/$tdir
7850         rm -f $DIR/$tfile
7851
7852         local list=$(comma_list $(osts_nodes))
7853         set_osd_param $list '' read_cache_enable 1
7854         set_osd_param $list '' writethrough_cache_enable 1
7855 }
7856
7857 calc_total() {
7858         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7859 }
7860
7861 ra_check_101() {
7862         local READ_SIZE=$1
7863         local STRIPE_SIZE=$2
7864         local FILE_LENGTH=$3
7865         local RA_INC=1048576
7866         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7867         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7868                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7869         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7870                         get_named_value 'read but discarded' |
7871                         cut -d" " -f1 | calc_total)
7872         if [[ $DISCARD -gt $discard_limit ]]; then
7873                 $LCTL get_param llite.*.read_ahead_stats
7874                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7875         else
7876                 echo "Read-ahead success for size ${READ_SIZE}"
7877         fi
7878 }
7879
7880 test_101b() {
7881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7882         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7883
7884         local STRIPE_SIZE=1048576
7885         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7886
7887         if [ $SLOW == "yes" ]; then
7888                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7889         else
7890                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7891         fi
7892
7893         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7894
7895         # prepare the read-ahead file
7896         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7897         cancel_lru_locks osc
7898         for BIDX in 2 4 8 16 32 64 128 256
7899         do
7900                 local BSIZE=$((BIDX*4096))
7901                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7902                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7903                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7904                 $LCTL set_param -n llite.*.read_ahead_stats 0
7905                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7906                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7907                 cancel_lru_locks osc
7908                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7909         done
7910         cleanup_test101bc
7911         true
7912 }
7913 run_test 101b "check stride-io mode read-ahead ================="
7914
7915 test_101c() {
7916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7917
7918         local STRIPE_SIZE=1048576
7919         local FILE_LENGTH=$((STRIPE_SIZE*100))
7920         local nreads=10000
7921         local rsize=65536
7922         local osc_rpc_stats
7923
7924         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7925
7926         cancel_lru_locks osc
7927         $LCTL set_param osc.*.rpc_stats 0
7928         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7929         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7930                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7931                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7932                 local size
7933
7934                 if [ $lines -le 20 ]; then
7935                         continue
7936                 fi
7937                 for size in 1 2 4 8; do
7938                         local rpc=$(echo "$stats" |
7939                                     awk '($1 == "'$size':") {print $2; exit; }')
7940                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7941                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7942                 done
7943                 echo "$osc_rpc_stats check passed!"
7944         done
7945         cleanup_test101bc
7946         true
7947 }
7948 run_test 101c "check stripe_size aligned read-ahead ================="
7949
7950 set_read_ahead() {
7951         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7952         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7953 }
7954
7955 test_101d() {
7956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7957
7958         local file=$DIR/$tfile
7959         local sz_MB=${FILESIZE_101d:-500}
7960         local ra_MB=${READAHEAD_MB:-40}
7961
7962         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7963         [ $free_MB -lt $sz_MB ] &&
7964                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7965
7966         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7967         $LFS setstripe -c -1 $file || error "setstripe failed"
7968
7969         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7970         echo Cancel LRU locks on lustre client to flush the client cache
7971         cancel_lru_locks osc
7972
7973         echo Disable read-ahead
7974         local old_READAHEAD=$(set_read_ahead 0)
7975
7976         echo Reading the test file $file with read-ahead disabled
7977         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7978
7979         echo Cancel LRU locks on lustre client to flush the client cache
7980         cancel_lru_locks osc
7981         echo Enable read-ahead with ${ra_MB}MB
7982         set_read_ahead $ra_MB
7983
7984         echo Reading the test file $file with read-ahead enabled
7985         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7986
7987         echo "read-ahead disabled time read $raOFF"
7988         echo "read-ahead enabled  time read $raON"
7989
7990         set_read_ahead $old_READAHEAD
7991         rm -f $file
7992         wait_delete_completed
7993
7994         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
7995                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7996 }
7997 run_test 101d "file read with and without read-ahead enabled"
7998
7999 test_101e() {
8000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8001
8002         local file=$DIR/$tfile
8003         local size_KB=500  #KB
8004         local count=100
8005         local bsize=1024
8006
8007         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8008         local need_KB=$((count * size_KB))
8009         [[ $free_KB -le $need_KB ]] &&
8010                 skip_env "Need free space $need_KB, have $free_KB"
8011
8012         echo "Creating $count ${size_KB}K test files"
8013         for ((i = 0; i < $count; i++)); do
8014                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8015         done
8016
8017         echo "Cancel LRU locks on lustre client to flush the client cache"
8018         cancel_lru_locks $OSC
8019
8020         echo "Reset readahead stats"
8021         $LCTL set_param -n llite.*.read_ahead_stats 0
8022
8023         for ((i = 0; i < $count; i++)); do
8024                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8025         done
8026
8027         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8028                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8029
8030         for ((i = 0; i < $count; i++)); do
8031                 rm -rf $file.$i 2>/dev/null
8032         done
8033
8034         #10000 means 20% reads are missing in readahead
8035         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8036 }
8037 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8038
8039 test_101f() {
8040         which iozone || skip_env "no iozone installed"
8041
8042         local old_debug=$($LCTL get_param debug)
8043         old_debug=${old_debug#*=}
8044         $LCTL set_param debug="reada mmap"
8045
8046         # create a test file
8047         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8048
8049         echo Cancel LRU locks on lustre client to flush the client cache
8050         cancel_lru_locks osc
8051
8052         echo Reset readahead stats
8053         $LCTL set_param -n llite.*.read_ahead_stats 0
8054
8055         echo mmap read the file with small block size
8056         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8057                 > /dev/null 2>&1
8058
8059         echo checking missing pages
8060         $LCTL get_param llite.*.read_ahead_stats
8061         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8062                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8063
8064         $LCTL set_param debug="$old_debug"
8065         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8066         rm -f $DIR/$tfile
8067 }
8068 run_test 101f "check mmap read performance"
8069
8070 test_101g_brw_size_test() {
8071         local mb=$1
8072         local pages=$((mb * 1048576 / PAGE_SIZE))
8073         local file=$DIR/$tfile
8074
8075         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8076                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8077         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8078                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8079                         return 2
8080         done
8081
8082         stack_trap "rm -f $file" EXIT
8083         $LCTL set_param -n osc.*.rpc_stats=0
8084
8085         # 10 RPCs should be enough for the test
8086         local count=10
8087         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8088                 { error "dd write ${mb} MB blocks failed"; return 3; }
8089         cancel_lru_locks osc
8090         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8091                 { error "dd write ${mb} MB blocks failed"; return 4; }
8092
8093         # calculate number of full-sized read and write RPCs
8094         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8095                 sed -n '/pages per rpc/,/^$/p' |
8096                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8097                 END { print reads,writes }'))
8098         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8099                 return 5
8100         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8101                 return 6
8102
8103         return 0
8104 }
8105
8106 test_101g() {
8107         remote_ost_nodsh && skip "remote OST with nodsh"
8108
8109         local rpcs
8110         local osts=$(get_facets OST)
8111         local list=$(comma_list $(osts_nodes))
8112         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8113         local brw_size="obdfilter.*.brw_size"
8114
8115         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8116
8117         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8118
8119         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8120                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8121                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8122            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8123                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8124                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8125
8126                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8127                         suffix="M"
8128
8129                 if [[ $orig_mb -lt 16 ]]; then
8130                         save_lustre_params $osts "$brw_size" > $p
8131                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8132                                 error "set 16MB RPC size failed"
8133
8134                         echo "remount client to enable new RPC size"
8135                         remount_client $MOUNT || error "remount_client failed"
8136                 fi
8137
8138                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8139                 # should be able to set brw_size=12, but no rpc_stats for that
8140                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8141         fi
8142
8143         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8144
8145         if [[ $orig_mb -lt 16 ]]; then
8146                 restore_lustre_params < $p
8147                 remount_client $MOUNT || error "remount_client restore failed"
8148         fi
8149
8150         rm -f $p $DIR/$tfile
8151 }
8152 run_test 101g "Big bulk(4/16 MiB) readahead"
8153
8154 setup_test102() {
8155         test_mkdir $DIR/$tdir
8156         chown $RUNAS_ID $DIR/$tdir
8157         STRIPE_SIZE=65536
8158         STRIPE_OFFSET=1
8159         STRIPE_COUNT=$OSTCOUNT
8160         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8161
8162         trap cleanup_test102 EXIT
8163         cd $DIR
8164         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8165         cd $DIR/$tdir
8166         for num in 1 2 3 4; do
8167                 for count in $(seq 1 $STRIPE_COUNT); do
8168                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8169                                 local size=`expr $STRIPE_SIZE \* $num`
8170                                 local file=file"$num-$idx-$count"
8171                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8172                         done
8173                 done
8174         done
8175
8176         cd $DIR
8177         $1 tar cf $TMP/f102.tar $tdir --xattrs
8178 }
8179
8180 cleanup_test102() {
8181         trap 0
8182         rm -f $TMP/f102.tar
8183         rm -rf $DIR/d0.sanity/d102
8184 }
8185
8186 test_102a() {
8187         [ "$UID" != 0 ] && skip "must run as root"
8188         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8189                 skip_env "must have user_xattr"
8190
8191         [ -z "$(which setfattr 2>/dev/null)" ] &&
8192                 skip_env "could not find setfattr"
8193
8194         local testfile=$DIR/$tfile
8195
8196         touch $testfile
8197         echo "set/get xattr..."
8198         setfattr -n trusted.name1 -v value1 $testfile ||
8199                 error "setfattr -n trusted.name1=value1 $testfile failed"
8200         getfattr -n trusted.name1 $testfile 2> /dev/null |
8201           grep "trusted.name1=.value1" ||
8202                 error "$testfile missing trusted.name1=value1"
8203
8204         setfattr -n user.author1 -v author1 $testfile ||
8205                 error "setfattr -n user.author1=author1 $testfile failed"
8206         getfattr -n user.author1 $testfile 2> /dev/null |
8207           grep "user.author1=.author1" ||
8208                 error "$testfile missing trusted.author1=author1"
8209
8210         echo "listxattr..."
8211         setfattr -n trusted.name2 -v value2 $testfile ||
8212                 error "$testfile unable to set trusted.name2"
8213         setfattr -n trusted.name3 -v value3 $testfile ||
8214                 error "$testfile unable to set trusted.name3"
8215         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8216             grep "trusted.name" | wc -l) -eq 3 ] ||
8217                 error "$testfile missing 3 trusted.name xattrs"
8218
8219         setfattr -n user.author2 -v author2 $testfile ||
8220                 error "$testfile unable to set user.author2"
8221         setfattr -n user.author3 -v author3 $testfile ||
8222                 error "$testfile unable to set user.author3"
8223         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8224             grep "user.author" | wc -l) -eq 3 ] ||
8225                 error "$testfile missing 3 user.author xattrs"
8226
8227         echo "remove xattr..."
8228         setfattr -x trusted.name1 $testfile ||
8229                 error "$testfile error deleting trusted.name1"
8230         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8231                 error "$testfile did not delete trusted.name1 xattr"
8232
8233         setfattr -x user.author1 $testfile ||
8234                 error "$testfile error deleting user.author1"
8235         echo "set lustre special xattr ..."
8236         $LFS setstripe -c1 $testfile
8237         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8238                 awk -F "=" '/trusted.lov/ { print $2 }' )
8239         setfattr -n "trusted.lov" -v $lovea $testfile ||
8240                 error "$testfile doesn't ignore setting trusted.lov again"
8241         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8242                 error "$testfile allow setting invalid trusted.lov"
8243         rm -f $testfile
8244 }
8245 run_test 102a "user xattr test =================================="
8246
8247 test_102b() {
8248         [ -z "$(which setfattr 2>/dev/null)" ] &&
8249                 skip_env "could not find setfattr"
8250         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8251
8252         # b10930: get/set/list trusted.lov xattr
8253         echo "get/set/list trusted.lov xattr ..."
8254         local testfile=$DIR/$tfile
8255         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8256                 error "setstripe failed"
8257         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8258                 error "getstripe failed"
8259         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8260                 error "can't get trusted.lov from $testfile"
8261
8262         local testfile2=${testfile}2
8263         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8264                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8265
8266         $MCREATE $testfile2
8267         setfattr -n trusted.lov -v $value $testfile2
8268         local stripe_size=$($LFS getstripe -S $testfile2)
8269         local stripe_count=$($LFS getstripe -c $testfile2)
8270         [[ $stripe_size -eq 65536 ]] ||
8271                 error "stripe size $stripe_size != 65536"
8272         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8273                 error "stripe count $stripe_count != $STRIPECOUNT"
8274         rm -f $DIR/$tfile
8275 }
8276 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8277
8278 test_102c() {
8279         [ -z "$(which setfattr 2>/dev/null)" ] &&
8280                 skip_env "could not find setfattr"
8281         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8282
8283         # b10930: get/set/list lustre.lov xattr
8284         echo "get/set/list lustre.lov xattr ..."
8285         test_mkdir $DIR/$tdir
8286         chown $RUNAS_ID $DIR/$tdir
8287         local testfile=$DIR/$tdir/$tfile
8288         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8289                 error "setstripe failed"
8290         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8291                 error "getstripe failed"
8292         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8293         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8294
8295         local testfile2=${testfile}2
8296         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8297                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8298
8299         $RUNAS $MCREATE $testfile2
8300         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8301         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8302         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8303         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8304         [ $stripe_count -eq $STRIPECOUNT ] ||
8305                 error "stripe count $stripe_count != $STRIPECOUNT"
8306 }
8307 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8308
8309 compare_stripe_info1() {
8310         local stripe_index_all_zero=true
8311
8312         for num in 1 2 3 4; do
8313                 for count in $(seq 1 $STRIPE_COUNT); do
8314                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8315                                 local size=$((STRIPE_SIZE * num))
8316                                 local file=file"$num-$offset-$count"
8317                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8318                                 [[ $stripe_size -ne $size ]] &&
8319                                     error "$file: size $stripe_size != $size"
8320                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8321                                 # allow fewer stripes to be created, ORI-601
8322                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8323                                     error "$file: count $stripe_count != $count"
8324                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8325                                 [[ $stripe_index -ne 0 ]] &&
8326                                         stripe_index_all_zero=false
8327                         done
8328                 done
8329         done
8330         $stripe_index_all_zero &&
8331                 error "all files are being extracted starting from OST index 0"
8332         return 0
8333 }
8334
8335 have_xattrs_include() {
8336         tar --help | grep -q xattrs-include &&
8337                 echo --xattrs-include="lustre.*"
8338 }
8339
8340 test_102d() {
8341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8342         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8343
8344         XINC=$(have_xattrs_include)
8345         setup_test102
8346         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8347         cd $DIR/$tdir/$tdir
8348         compare_stripe_info1
8349 }
8350 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8351
8352 test_102f() {
8353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8354         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8355
8356         XINC=$(have_xattrs_include)
8357         setup_test102
8358         test_mkdir $DIR/$tdir.restore
8359         cd $DIR
8360         tar cf - --xattrs $tdir | tar xf - \
8361                 -C $DIR/$tdir.restore --xattrs $XINC
8362         cd $DIR/$tdir.restore/$tdir
8363         compare_stripe_info1
8364 }
8365 run_test 102f "tar copy files, not keep osts"
8366
8367 grow_xattr() {
8368         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8369                 skip "must have user_xattr"
8370         [ -z "$(which setfattr 2>/dev/null)" ] &&
8371                 skip_env "could not find setfattr"
8372         [ -z "$(which getfattr 2>/dev/null)" ] &&
8373                 skip_env "could not find getfattr"
8374
8375         local xsize=${1:-1024}  # in bytes
8376         local file=$DIR/$tfile
8377         local value="$(generate_string $xsize)"
8378         local xbig=trusted.big
8379         local toobig=$2
8380
8381         touch $file
8382         log "save $xbig on $file"
8383         if [ -z "$toobig" ]
8384         then
8385                 setfattr -n $xbig -v $value $file ||
8386                         error "saving $xbig on $file failed"
8387         else
8388                 setfattr -n $xbig -v $value $file &&
8389                         error "saving $xbig on $file succeeded"
8390                 return 0
8391         fi
8392
8393         local orig=$(get_xattr_value $xbig $file)
8394         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8395
8396         local xsml=trusted.sml
8397         log "save $xsml on $file"
8398         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8399
8400         local new=$(get_xattr_value $xbig $file)
8401         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8402
8403         log "grow $xsml on $file"
8404         setfattr -n $xsml -v "$value" $file ||
8405                 error "growing $xsml on $file failed"
8406
8407         new=$(get_xattr_value $xbig $file)
8408         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8409         log "$xbig still valid after growing $xsml"
8410
8411         rm -f $file
8412 }
8413
8414 test_102h() { # bug 15777
8415         grow_xattr 1024
8416 }
8417 run_test 102h "grow xattr from inside inode to external block"
8418
8419 test_102ha() {
8420         large_xattr_enabled || skip_env "ea_inode feature disabled"
8421
8422         echo "setting xattr of max xattr size: $(max_xattr_size)"
8423         grow_xattr $(max_xattr_size)
8424
8425         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8426         echo "This should fail:"
8427         grow_xattr $(($(max_xattr_size) + 10)) 1
8428 }
8429 run_test 102ha "grow xattr from inside inode to external inode"
8430
8431 test_102i() { # bug 17038
8432         [ -z "$(which getfattr 2>/dev/null)" ] &&
8433                 skip "could not find getfattr"
8434
8435         touch $DIR/$tfile
8436         ln -s $DIR/$tfile $DIR/${tfile}link
8437         getfattr -n trusted.lov $DIR/$tfile ||
8438                 error "lgetxattr on $DIR/$tfile failed"
8439         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8440                 grep -i "no such attr" ||
8441                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8442         rm -f $DIR/$tfile $DIR/${tfile}link
8443 }
8444 run_test 102i "lgetxattr test on symbolic link ============"
8445
8446 test_102j() {
8447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8448         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8449
8450         XINC=$(have_xattrs_include)
8451         setup_test102 "$RUNAS"
8452         chown $RUNAS_ID $DIR/$tdir
8453         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8454         cd $DIR/$tdir/$tdir
8455         compare_stripe_info1 "$RUNAS"
8456 }
8457 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8458
8459 test_102k() {
8460         [ -z "$(which setfattr 2>/dev/null)" ] &&
8461                 skip "could not find setfattr"
8462
8463         touch $DIR/$tfile
8464         # b22187 just check that does not crash for regular file.
8465         setfattr -n trusted.lov $DIR/$tfile
8466         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8467         local test_kdir=$DIR/$tdir
8468         test_mkdir $test_kdir
8469         local default_size=$($LFS getstripe -S $test_kdir)
8470         local default_count=$($LFS getstripe -c $test_kdir)
8471         local default_offset=$($LFS getstripe -i $test_kdir)
8472         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8473                 error 'dir setstripe failed'
8474         setfattr -n trusted.lov $test_kdir
8475         local stripe_size=$($LFS getstripe -S $test_kdir)
8476         local stripe_count=$($LFS getstripe -c $test_kdir)
8477         local stripe_offset=$($LFS getstripe -i $test_kdir)
8478         [ $stripe_size -eq $default_size ] ||
8479                 error "stripe size $stripe_size != $default_size"
8480         [ $stripe_count -eq $default_count ] ||
8481                 error "stripe count $stripe_count != $default_count"
8482         [ $stripe_offset -eq $default_offset ] ||
8483                 error "stripe offset $stripe_offset != $default_offset"
8484         rm -rf $DIR/$tfile $test_kdir
8485 }
8486 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8487
8488 test_102l() {
8489         [ -z "$(which getfattr 2>/dev/null)" ] &&
8490                 skip "could not find getfattr"
8491
8492         # LU-532 trusted. xattr is invisible to non-root
8493         local testfile=$DIR/$tfile
8494
8495         touch $testfile
8496
8497         echo "listxattr as user..."
8498         chown $RUNAS_ID $testfile
8499         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8500             grep -q "trusted" &&
8501                 error "$testfile trusted xattrs are user visible"
8502
8503         return 0;
8504 }
8505 run_test 102l "listxattr size test =================================="
8506
8507 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8508         local path=$DIR/$tfile
8509         touch $path
8510
8511         listxattr_size_check $path || error "listattr_size_check $path failed"
8512 }
8513 run_test 102m "Ensure listxattr fails on small bufffer ========"
8514
8515 cleanup_test102
8516
8517 getxattr() { # getxattr path name
8518         # Return the base64 encoding of the value of xattr name on path.
8519         local path=$1
8520         local name=$2
8521
8522         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8523         # file: $path
8524         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8525         #
8526         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8527
8528         getfattr --absolute-names --encoding=base64 --name=$name $path |
8529                 awk -F= -v name=$name '$1 == name {
8530                         print substr($0, index($0, "=") + 1);
8531         }'
8532 }
8533
8534 test_102n() { # LU-4101 mdt: protect internal xattrs
8535         [ -z "$(which setfattr 2>/dev/null)" ] &&
8536                 skip "could not find setfattr"
8537         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8538         then
8539                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8540         fi
8541
8542         local file0=$DIR/$tfile.0
8543         local file1=$DIR/$tfile.1
8544         local xattr0=$TMP/$tfile.0
8545         local xattr1=$TMP/$tfile.1
8546         local namelist="lov lma lmv link fid version som hsm"
8547         local name
8548         local value
8549
8550         rm -rf $file0 $file1 $xattr0 $xattr1
8551         touch $file0 $file1
8552
8553         # Get 'before' xattrs of $file1.
8554         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8555
8556         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8557                 namelist+=" lfsck_namespace"
8558         for name in $namelist; do
8559                 # Try to copy xattr from $file0 to $file1.
8560                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8561
8562                 setfattr --name=trusted.$name --value="$value" $file1 ||
8563                         error "setxattr 'trusted.$name' failed"
8564
8565                 # Try to set a garbage xattr.
8566                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8567
8568                 if [[ x$name == "xlov" ]]; then
8569                         setfattr --name=trusted.lov --value="$value" $file1 &&
8570                         error "setxattr invalid 'trusted.lov' success"
8571                 else
8572                         setfattr --name=trusted.$name --value="$value" $file1 ||
8573                                 error "setxattr invalid 'trusted.$name' failed"
8574                 fi
8575
8576                 # Try to remove the xattr from $file1. We don't care if this
8577                 # appears to succeed or fail, we just don't want there to be
8578                 # any changes or crashes.
8579                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8580         done
8581
8582         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8583         then
8584                 name="lfsck_ns"
8585                 # Try to copy xattr from $file0 to $file1.
8586                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8587
8588                 setfattr --name=trusted.$name --value="$value" $file1 ||
8589                         error "setxattr 'trusted.$name' failed"
8590
8591                 # Try to set a garbage xattr.
8592                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8593
8594                 setfattr --name=trusted.$name --value="$value" $file1 ||
8595                         error "setxattr 'trusted.$name' failed"
8596
8597                 # Try to remove the xattr from $file1. We don't care if this
8598                 # appears to succeed or fail, we just don't want there to be
8599                 # any changes or crashes.
8600                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8601         fi
8602
8603         # Get 'after' xattrs of file1.
8604         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8605
8606         if ! diff $xattr0 $xattr1; then
8607                 error "before and after xattrs of '$file1' differ"
8608         fi
8609
8610         rm -rf $file0 $file1 $xattr0 $xattr1
8611
8612         return 0
8613 }
8614 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8615
8616 test_102p() { # LU-4703 setxattr did not check ownership
8617         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8618                 skip "MDS needs to be at least 2.5.56"
8619
8620         local testfile=$DIR/$tfile
8621
8622         touch $testfile
8623
8624         echo "setfacl as user..."
8625         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8626         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8627
8628         echo "setfattr as user..."
8629         setfacl -m "u:$RUNAS_ID:---" $testfile
8630         $RUNAS setfattr -x system.posix_acl_access $testfile
8631         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8632 }
8633 run_test 102p "check setxattr(2) correctly fails without permission"
8634
8635 test_102q() {
8636         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8637                 skip "MDS needs to be at least 2.6.92"
8638
8639         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8640 }
8641 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8642
8643 test_102r() {
8644         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8645                 skip "MDS needs to be at least 2.6.93"
8646
8647         touch $DIR/$tfile || error "touch"
8648         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8649         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8650         rm $DIR/$tfile || error "rm"
8651
8652         #normal directory
8653         mkdir -p $DIR/$tdir || error "mkdir"
8654         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8655         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8656         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8657                 error "$testfile error deleting user.author1"
8658         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8659                 grep "user.$(basename $tdir)" &&
8660                 error "$tdir did not delete user.$(basename $tdir)"
8661         rmdir $DIR/$tdir || error "rmdir"
8662
8663         #striped directory
8664         test_mkdir $DIR/$tdir
8665         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8666         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8667         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8668                 error "$testfile error deleting user.author1"
8669         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8670                 grep "user.$(basename $tdir)" &&
8671                 error "$tdir did not delete user.$(basename $tdir)"
8672         rmdir $DIR/$tdir || error "rm striped dir"
8673 }
8674 run_test 102r "set EAs with empty values"
8675
8676 test_102s() {
8677         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8678                 skip "MDS needs to be at least 2.11.52"
8679
8680         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8681
8682         save_lustre_params client "llite.*.xattr_cache" > $save
8683
8684         for cache in 0 1; do
8685                 lctl set_param llite.*.xattr_cache=$cache
8686
8687                 rm -f $DIR/$tfile
8688                 touch $DIR/$tfile || error "touch"
8689                 for prefix in lustre security system trusted user; do
8690                         # Note getxattr() may fail with 'Operation not
8691                         # supported' or 'No such attribute' depending
8692                         # on prefix and cache.
8693                         getfattr -n $prefix.n102s $DIR/$tfile &&
8694                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8695                 done
8696         done
8697
8698         restore_lustre_params < $save
8699 }
8700 run_test 102s "getting nonexistent xattrs should fail"
8701
8702 test_102t() {
8703         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8704                 skip "MDS needs to be at least 2.11.52"
8705
8706         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8707
8708         save_lustre_params client "llite.*.xattr_cache" > $save
8709
8710         for cache in 0 1; do
8711                 lctl set_param llite.*.xattr_cache=$cache
8712
8713                 for buf_size in 0 256; do
8714                         rm -f $DIR/$tfile
8715                         touch $DIR/$tfile || error "touch"
8716                         setfattr -n user.multiop $DIR/$tfile
8717                         $MULTIOP $DIR/$tfile oa$buf_size ||
8718                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8719                 done
8720         done
8721
8722         restore_lustre_params < $save
8723 }
8724 run_test 102t "zero length xattr values handled correctly"
8725
8726 run_acl_subtest()
8727 {
8728     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8729     return $?
8730 }
8731
8732 test_103a() {
8733         [ "$UID" != 0 ] && skip "must run as root"
8734         $GSS && skip_env "could not run under gss"
8735         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8736                 skip_env "must have acl enabled"
8737         [ -z "$(which setfacl 2>/dev/null)" ] &&
8738                 skip_env "could not find setfacl"
8739         remote_mds_nodsh && skip "remote MDS with nodsh"
8740
8741         gpasswd -a daemon bin                           # LU-5641
8742         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8743
8744         declare -a identity_old
8745
8746         for num in $(seq $MDSCOUNT); do
8747                 switch_identity $num true || identity_old[$num]=$?
8748         done
8749
8750         SAVE_UMASK=$(umask)
8751         umask 0022
8752         mkdir -p $DIR/$tdir
8753         cd $DIR/$tdir
8754
8755         echo "performing cp ..."
8756         run_acl_subtest cp || error "run_acl_subtest cp failed"
8757         echo "performing getfacl-noacl..."
8758         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8759         echo "performing misc..."
8760         run_acl_subtest misc || error  "misc test failed"
8761         echo "performing permissions..."
8762         run_acl_subtest permissions || error "permissions failed"
8763         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8764         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8765                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8766                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8767         then
8768                 echo "performing permissions xattr..."
8769                 run_acl_subtest permissions_xattr ||
8770                         error "permissions_xattr failed"
8771         fi
8772         echo "performing setfacl..."
8773         run_acl_subtest setfacl || error  "setfacl test failed"
8774
8775         # inheritance test got from HP
8776         echo "performing inheritance..."
8777         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8778         chmod +x make-tree || error "chmod +x failed"
8779         run_acl_subtest inheritance || error "inheritance test failed"
8780         rm -f make-tree
8781
8782         echo "LU-974 ignore umask when acl is enabled..."
8783         run_acl_subtest 974 || error "LU-974 umask test failed"
8784         if [ $MDSCOUNT -ge 2 ]; then
8785                 run_acl_subtest 974_remote ||
8786                         error "LU-974 umask test failed under remote dir"
8787         fi
8788
8789         echo "LU-2561 newly created file is same size as directory..."
8790         if [ "$mds1_FSTYPE" != "zfs" ]; then
8791                 run_acl_subtest 2561 || error "LU-2561 test failed"
8792         else
8793                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8794         fi
8795
8796         run_acl_subtest 4924 || error "LU-4924 test failed"
8797
8798         cd $SAVE_PWD
8799         umask $SAVE_UMASK
8800
8801         for num in $(seq $MDSCOUNT); do
8802                 if [ "${identity_old[$num]}" = 1 ]; then
8803                         switch_identity $num false || identity_old[$num]=$?
8804                 fi
8805         done
8806 }
8807 run_test 103a "acl test"
8808
8809 test_103b() {
8810         declare -a pids
8811         local U
8812
8813         for U in {0..511}; do
8814                 {
8815                 local O=$(printf "%04o" $U)
8816
8817                 umask $(printf "%04o" $((511 ^ $O)))
8818                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8819                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8820
8821                 (( $S == ($O & 0666) )) ||
8822                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8823
8824                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8825                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8826                 (( $S == ($O & 0666) )) ||
8827                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8828
8829                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8830                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8831                 (( $S == ($O & 0666) )) ||
8832                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8833                 rm -f $DIR/$tfile.[smp]$0
8834                 } &
8835                 local pid=$!
8836
8837                 # limit the concurrently running threads to 64. LU-11878
8838                 local idx=$((U % 64))
8839                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8840                 pids[idx]=$pid
8841         done
8842         wait
8843 }
8844 run_test 103b "umask lfs setstripe"
8845
8846 test_103c() {
8847         mkdir -p $DIR/$tdir
8848         cp -rp $DIR/$tdir $DIR/$tdir.bak
8849
8850         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8851                 error "$DIR/$tdir shouldn't contain default ACL"
8852         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8853                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8854         true
8855 }
8856 run_test 103c "'cp -rp' won't set empty acl"
8857
8858 test_104a() {
8859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8860
8861         touch $DIR/$tfile
8862         lfs df || error "lfs df failed"
8863         lfs df -ih || error "lfs df -ih failed"
8864         lfs df -h $DIR || error "lfs df -h $DIR failed"
8865         lfs df -i $DIR || error "lfs df -i $DIR failed"
8866         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8867         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8868
8869         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8870         lctl --device %$OSC deactivate
8871         lfs df || error "lfs df with deactivated OSC failed"
8872         lctl --device %$OSC activate
8873         # wait the osc back to normal
8874         wait_osc_import_ready client ost
8875
8876         lfs df || error "lfs df with reactivated OSC failed"
8877         rm -f $DIR/$tfile
8878 }
8879 run_test 104a "lfs df [-ih] [path] test ========================="
8880
8881 test_104b() {
8882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8883         [ $RUNAS_ID -eq $UID ] &&
8884                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8885
8886         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8887                         grep "Permission denied" | wc -l)))
8888         if [ $denied_cnt -ne 0 ]; then
8889                 error "lfs check servers test failed"
8890         fi
8891 }
8892 run_test 104b "$RUNAS lfs check servers test ===================="
8893
8894 test_105a() {
8895         # doesn't work on 2.4 kernels
8896         touch $DIR/$tfile
8897         if $(flock_is_enabled); then
8898                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8899         else
8900                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8901         fi
8902         rm -f $DIR/$tfile
8903 }
8904 run_test 105a "flock when mounted without -o flock test ========"
8905
8906 test_105b() {
8907         touch $DIR/$tfile
8908         if $(flock_is_enabled); then
8909                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8910         else
8911                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8912         fi
8913         rm -f $DIR/$tfile
8914 }
8915 run_test 105b "fcntl when mounted without -o flock test ========"
8916
8917 test_105c() {
8918         touch $DIR/$tfile
8919         if $(flock_is_enabled); then
8920                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8921         else
8922                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8923         fi
8924         rm -f $DIR/$tfile
8925 }
8926 run_test 105c "lockf when mounted without -o flock test"
8927
8928 test_105d() { # bug 15924
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930
8931         test_mkdir $DIR/$tdir
8932         flock_is_enabled || skip_env "mount w/o flock enabled"
8933         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8934         $LCTL set_param fail_loc=0x80000315
8935         flocks_test 2 $DIR/$tdir
8936 }
8937 run_test 105d "flock race (should not freeze) ========"
8938
8939 test_105e() { # bug 22660 && 22040
8940         flock_is_enabled || skip_env "mount w/o flock enabled"
8941
8942         touch $DIR/$tfile
8943         flocks_test 3 $DIR/$tfile
8944 }
8945 run_test 105e "Two conflicting flocks from same process"
8946
8947 test_106() { #bug 10921
8948         test_mkdir $DIR/$tdir
8949         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8950         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8951 }
8952 run_test 106 "attempt exec of dir followed by chown of that dir"
8953
8954 test_107() {
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956
8957         CDIR=`pwd`
8958         local file=core
8959
8960         cd $DIR
8961         rm -f $file
8962
8963         local save_pattern=$(sysctl -n kernel.core_pattern)
8964         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8965         sysctl -w kernel.core_pattern=$file
8966         sysctl -w kernel.core_uses_pid=0
8967
8968         ulimit -c unlimited
8969         sleep 60 &
8970         SLEEPPID=$!
8971
8972         sleep 1
8973
8974         kill -s 11 $SLEEPPID
8975         wait $SLEEPPID
8976         if [ -e $file ]; then
8977                 size=`stat -c%s $file`
8978                 [ $size -eq 0 ] && error "Fail to create core file $file"
8979         else
8980                 error "Fail to create core file $file"
8981         fi
8982         rm -f $file
8983         sysctl -w kernel.core_pattern=$save_pattern
8984         sysctl -w kernel.core_uses_pid=$save_uses_pid
8985         cd $CDIR
8986 }
8987 run_test 107 "Coredump on SIG"
8988
8989 test_110() {
8990         test_mkdir $DIR/$tdir
8991         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8992         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8993                 error "mkdir with 256 char should fail, but did not"
8994         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8995                 error "create with 255 char failed"
8996         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8997                 error "create with 256 char should fail, but did not"
8998
8999         ls -l $DIR/$tdir
9000         rm -rf $DIR/$tdir
9001 }
9002 run_test 110 "filename length checking"
9003
9004 #
9005 # Purpose: To verify dynamic thread (OSS) creation.
9006 #
9007 test_115() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009         remote_ost_nodsh && skip "remote OST with nodsh"
9010
9011         # Lustre does not stop service threads once they are started.
9012         # Reset number of running threads to default.
9013         stopall
9014         setupall
9015
9016         local OSTIO_pre
9017         local save_params="$TMP/sanity-$TESTNAME.parameters"
9018
9019         # Get ll_ost_io count before I/O
9020         OSTIO_pre=$(do_facet ost1 \
9021                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9022         # Exit if lustre is not running (ll_ost_io not running).
9023         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9024
9025         echo "Starting with $OSTIO_pre threads"
9026         local thread_max=$((OSTIO_pre * 2))
9027         local rpc_in_flight=$((thread_max * 2))
9028         # Number of I/O Process proposed to be started.
9029         local nfiles
9030         local facets=$(get_facets OST)
9031
9032         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9033         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9034
9035         # Set in_flight to $rpc_in_flight
9036         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9037                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9038         nfiles=${rpc_in_flight}
9039         # Set ost thread_max to $thread_max
9040         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9041
9042         # 5 Minutes should be sufficient for max number of OSS
9043         # threads(thread_max) to be created.
9044         local timeout=300
9045
9046         # Start I/O.
9047         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9048         test_mkdir $DIR/$tdir
9049         for i in $(seq $nfiles); do
9050                 local file=$DIR/$tdir/${tfile}-$i
9051                 $LFS setstripe -c -1 -i 0 $file
9052                 ($WTL $file $timeout)&
9053         done
9054
9055         # I/O Started - Wait for thread_started to reach thread_max or report
9056         # error if thread_started is more than thread_max.
9057         echo "Waiting for thread_started to reach thread_max"
9058         local thread_started=0
9059         local end_time=$((SECONDS + timeout))
9060
9061         while [ $SECONDS -le $end_time ] ; do
9062                 echo -n "."
9063                 # Get ost i/o thread_started count.
9064                 thread_started=$(do_facet ost1 \
9065                         "$LCTL get_param \
9066                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9067                 # Break out if thread_started is equal/greater than thread_max
9068                 if [[ $thread_started -ge $thread_max ]]; then
9069                         echo ll_ost_io thread_started $thread_started, \
9070                                 equal/greater than thread_max $thread_max
9071                         break
9072                 fi
9073                 sleep 1
9074         done
9075
9076         # Cleanup - We have the numbers, Kill i/o jobs if running.
9077         jobcount=($(jobs -p))
9078         for i in $(seq 0 $((${#jobcount[@]}-1)))
9079         do
9080                 kill -9 ${jobcount[$i]}
9081                 if [ $? -ne 0 ] ; then
9082                         echo Warning: \
9083                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9084                 fi
9085         done
9086
9087         # Cleanup files left by WTL binary.
9088         for i in $(seq $nfiles); do
9089                 local file=$DIR/$tdir/${tfile}-$i
9090                 rm -rf $file
9091                 if [ $? -ne 0 ] ; then
9092                         echo "Warning: Failed to delete file $file"
9093                 fi
9094         done
9095
9096         restore_lustre_params <$save_params
9097         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9098
9099         # Error out if no new thread has started or Thread started is greater
9100         # than thread max.
9101         if [[ $thread_started -le $OSTIO_pre ||
9102                         $thread_started -gt $thread_max ]]; then
9103                 error "ll_ost_io: thread_started $thread_started" \
9104                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9105                       "No new thread started or thread started greater " \
9106                       "than thread_max."
9107         fi
9108 }
9109 run_test 115 "verify dynamic thread creation===================="
9110
9111 free_min_max () {
9112         wait_delete_completed
9113         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9114         echo "OST kbytes available: ${AVAIL[@]}"
9115         MAXV=${AVAIL[0]}
9116         MAXI=0
9117         MINV=${AVAIL[0]}
9118         MINI=0
9119         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9120                 #echo OST $i: ${AVAIL[i]}kb
9121                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9122                         MAXV=${AVAIL[i]}
9123                         MAXI=$i
9124                 fi
9125                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9126                         MINV=${AVAIL[i]}
9127                         MINI=$i
9128                 fi
9129         done
9130         echo "Min free space: OST $MINI: $MINV"
9131         echo "Max free space: OST $MAXI: $MAXV"
9132 }
9133
9134 test_116a() { # was previously test_116()
9135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9136         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9137         remote_mds_nodsh && skip "remote MDS with nodsh"
9138
9139         echo -n "Free space priority "
9140         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9141                 head -n1
9142         declare -a AVAIL
9143         free_min_max
9144
9145         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9146         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9147         trap simple_cleanup_common EXIT
9148
9149         # Check if we need to generate uneven OSTs
9150         test_mkdir -p $DIR/$tdir/OST${MINI}
9151         local FILL=$((MINV / 4))
9152         local DIFF=$((MAXV - MINV))
9153         local DIFF2=$((DIFF * 100 / MINV))
9154
9155         local threshold=$(do_facet $SINGLEMDS \
9156                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9157         threshold=${threshold%%%}
9158         echo -n "Check for uneven OSTs: "
9159         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9160
9161         if [[ $DIFF2 -gt $threshold ]]; then
9162                 echo "ok"
9163                 echo "Don't need to fill OST$MINI"
9164         else
9165                 # generate uneven OSTs. Write 2% over the QOS threshold value
9166                 echo "no"
9167                 DIFF=$((threshold - DIFF2 + 2))
9168                 DIFF2=$((MINV * DIFF / 100))
9169                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9170                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9171                         error "setstripe failed"
9172                 DIFF=$((DIFF2 / 2048))
9173                 i=0
9174                 while [ $i -lt $DIFF ]; do
9175                         i=$((i + 1))
9176                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9177                                 bs=2M count=1 2>/dev/null
9178                         echo -n .
9179                 done
9180                 echo .
9181                 sync
9182                 sleep_maxage
9183                 free_min_max
9184         fi
9185
9186         DIFF=$((MAXV - MINV))
9187         DIFF2=$((DIFF * 100 / MINV))
9188         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9189         if [ $DIFF2 -gt $threshold ]; then
9190                 echo "ok"
9191         else
9192                 echo "failed - QOS mode won't be used"
9193                 simple_cleanup_common
9194                 skip "QOS imbalance criteria not met"
9195         fi
9196
9197         MINI1=$MINI
9198         MINV1=$MINV
9199         MAXI1=$MAXI
9200         MAXV1=$MAXV
9201
9202         # now fill using QOS
9203         $LFS setstripe -c 1 $DIR/$tdir
9204         FILL=$((FILL / 200))
9205         if [ $FILL -gt 600 ]; then
9206                 FILL=600
9207         fi
9208         echo "writing $FILL files to QOS-assigned OSTs"
9209         i=0
9210         while [ $i -lt $FILL ]; do
9211                 i=$((i + 1))
9212                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9213                         count=1 2>/dev/null
9214                 echo -n .
9215         done
9216         echo "wrote $i 200k files"
9217         sync
9218         sleep_maxage
9219
9220         echo "Note: free space may not be updated, so measurements might be off"
9221         free_min_max
9222         DIFF2=$((MAXV - MINV))
9223         echo "free space delta: orig $DIFF final $DIFF2"
9224         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9225         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9226         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9227         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9228         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9229         if [[ $DIFF -gt 0 ]]; then
9230                 FILL=$((DIFF2 * 100 / DIFF - 100))
9231                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9232         fi
9233
9234         # Figure out which files were written where
9235         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9236                awk '/'$MINI1': / {print $2; exit}')
9237         echo $UUID
9238         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9239         echo "$MINC files created on smaller OST $MINI1"
9240         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9241                awk '/'$MAXI1': / {print $2; exit}')
9242         echo $UUID
9243         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9244         echo "$MAXC files created on larger OST $MAXI1"
9245         if [[ $MINC -gt 0 ]]; then
9246                 FILL=$((MAXC * 100 / MINC - 100))
9247                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9248         fi
9249         [[ $MAXC -gt $MINC ]] ||
9250                 error_ignore LU-9 "stripe QOS didn't balance free space"
9251         simple_cleanup_common
9252 }
9253 run_test 116a "stripe QOS: free space balance ==================="
9254
9255 test_116b() { # LU-2093
9256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9257         remote_mds_nodsh && skip "remote MDS with nodsh"
9258
9259 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9260         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9261                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9262         [ -z "$old_rr" ] && skip "no QOS"
9263         do_facet $SINGLEMDS lctl set_param \
9264                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9265         mkdir -p $DIR/$tdir
9266         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9267         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9268         do_facet $SINGLEMDS lctl set_param fail_loc=0
9269         rm -rf $DIR/$tdir
9270         do_facet $SINGLEMDS lctl set_param \
9271                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9272 }
9273 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9274
9275 test_117() # bug 10891
9276 {
9277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9278
9279         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9280         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9281         lctl set_param fail_loc=0x21e
9282         > $DIR/$tfile || error "truncate failed"
9283         lctl set_param fail_loc=0
9284         echo "Truncate succeeded."
9285         rm -f $DIR/$tfile
9286 }
9287 run_test 117 "verify osd extend =========="
9288
9289 NO_SLOW_RESENDCOUNT=4
9290 export OLD_RESENDCOUNT=""
9291 set_resend_count () {
9292         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9293         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9294         lctl set_param -n $PROC_RESENDCOUNT $1
9295         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9296 }
9297
9298 # for reduce test_118* time (b=14842)
9299 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9300
9301 # Reset async IO behavior after error case
9302 reset_async() {
9303         FILE=$DIR/reset_async
9304
9305         # Ensure all OSCs are cleared
9306         $LFS setstripe -c -1 $FILE
9307         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9308         sync
9309         rm $FILE
9310 }
9311
9312 test_118a() #bug 11710
9313 {
9314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9315
9316         reset_async
9317
9318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9319         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9320         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9321
9322         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9323                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9324                 return 1;
9325         fi
9326         rm -f $DIR/$tfile
9327 }
9328 run_test 118a "verify O_SYNC works =========="
9329
9330 test_118b()
9331 {
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333         remote_ost_nodsh && skip "remote OST with nodsh"
9334
9335         reset_async
9336
9337         #define OBD_FAIL_SRV_ENOENT 0x217
9338         set_nodes_failloc "$(osts_nodes)" 0x217
9339         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9340         RC=$?
9341         set_nodes_failloc "$(osts_nodes)" 0
9342         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9343         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9344                     grep -c writeback)
9345
9346         if [[ $RC -eq 0 ]]; then
9347                 error "Must return error due to dropped pages, rc=$RC"
9348                 return 1;
9349         fi
9350
9351         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9352                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9353                 return 1;
9354         fi
9355
9356         echo "Dirty pages not leaked on ENOENT"
9357
9358         # Due to the above error the OSC will issue all RPCs syncronously
9359         # until a subsequent RPC completes successfully without error.
9360         $MULTIOP $DIR/$tfile Ow4096yc
9361         rm -f $DIR/$tfile
9362
9363         return 0
9364 }
9365 run_test 118b "Reclaim dirty pages on fatal error =========="
9366
9367 test_118c()
9368 {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370
9371         # for 118c, restore the original resend count, LU-1940
9372         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9373                                 set_resend_count $OLD_RESENDCOUNT
9374         remote_ost_nodsh && skip "remote OST with nodsh"
9375
9376         reset_async
9377
9378         #define OBD_FAIL_OST_EROFS               0x216
9379         set_nodes_failloc "$(osts_nodes)" 0x216
9380
9381         # multiop should block due to fsync until pages are written
9382         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9383         MULTIPID=$!
9384         sleep 1
9385
9386         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9387                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9388         fi
9389
9390         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9391                     grep -c writeback)
9392         if [[ $WRITEBACK -eq 0 ]]; then
9393                 error "No page in writeback, writeback=$WRITEBACK"
9394         fi
9395
9396         set_nodes_failloc "$(osts_nodes)" 0
9397         wait $MULTIPID
9398         RC=$?
9399         if [[ $RC -ne 0 ]]; then
9400                 error "Multiop fsync failed, rc=$RC"
9401         fi
9402
9403         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9404         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9405                     grep -c writeback)
9406         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9407                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9408         fi
9409
9410         rm -f $DIR/$tfile
9411         echo "Dirty pages flushed via fsync on EROFS"
9412         return 0
9413 }
9414 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9415
9416 # continue to use small resend count to reduce test_118* time (b=14842)
9417 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9418
9419 test_118d()
9420 {
9421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9422         remote_ost_nodsh && skip "remote OST with nodsh"
9423
9424         reset_async
9425
9426         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9427         set_nodes_failloc "$(osts_nodes)" 0x214
9428         # multiop should block due to fsync until pages are written
9429         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9430         MULTIPID=$!
9431         sleep 1
9432
9433         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9434                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9435         fi
9436
9437         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9438                     grep -c writeback)
9439         if [[ $WRITEBACK -eq 0 ]]; then
9440                 error "No page in writeback, writeback=$WRITEBACK"
9441         fi
9442
9443         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9444         set_nodes_failloc "$(osts_nodes)" 0
9445
9446         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9447         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9448                     grep -c writeback)
9449         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9450                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9451         fi
9452
9453         rm -f $DIR/$tfile
9454         echo "Dirty pages gaurenteed flushed via fsync"
9455         return 0
9456 }
9457 run_test 118d "Fsync validation inject a delay of the bulk =========="
9458
9459 test_118f() {
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461
9462         reset_async
9463
9464         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9465         lctl set_param fail_loc=0x8000040a
9466
9467         # Should simulate EINVAL error which is fatal
9468         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9469         RC=$?
9470         if [[ $RC -eq 0 ]]; then
9471                 error "Must return error due to dropped pages, rc=$RC"
9472         fi
9473
9474         lctl set_param fail_loc=0x0
9475
9476         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9477         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9478         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9479                     grep -c writeback)
9480         if [[ $LOCKED -ne 0 ]]; then
9481                 error "Locked pages remain in cache, locked=$LOCKED"
9482         fi
9483
9484         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9485                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9486         fi
9487
9488         rm -f $DIR/$tfile
9489         echo "No pages locked after fsync"
9490
9491         reset_async
9492         return 0
9493 }
9494 run_test 118f "Simulate unrecoverable OSC side error =========="
9495
9496 test_118g() {
9497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9498
9499         reset_async
9500
9501         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9502         lctl set_param fail_loc=0x406
9503
9504         # simulate local -ENOMEM
9505         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9506         RC=$?
9507
9508         lctl set_param fail_loc=0
9509         if [[ $RC -eq 0 ]]; then
9510                 error "Must return error due to dropped pages, rc=$RC"
9511         fi
9512
9513         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9514         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9515         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9516                         grep -c writeback)
9517         if [[ $LOCKED -ne 0 ]]; then
9518                 error "Locked pages remain in cache, locked=$LOCKED"
9519         fi
9520
9521         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9522                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9523         fi
9524
9525         rm -f $DIR/$tfile
9526         echo "No pages locked after fsync"
9527
9528         reset_async
9529         return 0
9530 }
9531 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9532
9533 test_118h() {
9534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9535         remote_ost_nodsh && skip "remote OST with nodsh"
9536
9537         reset_async
9538
9539         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9540         set_nodes_failloc "$(osts_nodes)" 0x20e
9541         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9542         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9543         RC=$?
9544
9545         set_nodes_failloc "$(osts_nodes)" 0
9546         if [[ $RC -eq 0 ]]; then
9547                 error "Must return error due to dropped pages, rc=$RC"
9548         fi
9549
9550         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9551         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9552         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9553                     grep -c writeback)
9554         if [[ $LOCKED -ne 0 ]]; then
9555                 error "Locked pages remain in cache, locked=$LOCKED"
9556         fi
9557
9558         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9559                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9560         fi
9561
9562         rm -f $DIR/$tfile
9563         echo "No pages locked after fsync"
9564
9565         return 0
9566 }
9567 run_test 118h "Verify timeout in handling recoverables errors  =========="
9568
9569 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9570
9571 test_118i() {
9572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9573         remote_ost_nodsh && skip "remote OST with nodsh"
9574
9575         reset_async
9576
9577         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9578         set_nodes_failloc "$(osts_nodes)" 0x20e
9579
9580         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9581         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9582         PID=$!
9583         sleep 5
9584         set_nodes_failloc "$(osts_nodes)" 0
9585
9586         wait $PID
9587         RC=$?
9588         if [[ $RC -ne 0 ]]; then
9589                 error "got error, but should be not, rc=$RC"
9590         fi
9591
9592         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9593         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9594         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9595         if [[ $LOCKED -ne 0 ]]; then
9596                 error "Locked pages remain in cache, locked=$LOCKED"
9597         fi
9598
9599         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9600                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9601         fi
9602
9603         rm -f $DIR/$tfile
9604         echo "No pages locked after fsync"
9605
9606         return 0
9607 }
9608 run_test 118i "Fix error before timeout in recoverable error  =========="
9609
9610 [ "$SLOW" = "no" ] && set_resend_count 4
9611
9612 test_118j() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614         remote_ost_nodsh && skip "remote OST with nodsh"
9615
9616         reset_async
9617
9618         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9619         set_nodes_failloc "$(osts_nodes)" 0x220
9620
9621         # return -EIO from OST
9622         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9623         RC=$?
9624         set_nodes_failloc "$(osts_nodes)" 0x0
9625         if [[ $RC -eq 0 ]]; then
9626                 error "Must return error due to dropped pages, rc=$RC"
9627         fi
9628
9629         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9630         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9631         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9632         if [[ $LOCKED -ne 0 ]]; then
9633                 error "Locked pages remain in cache, locked=$LOCKED"
9634         fi
9635
9636         # in recoverable error on OST we want resend and stay until it finished
9637         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9638                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9639         fi
9640
9641         rm -f $DIR/$tfile
9642         echo "No pages locked after fsync"
9643
9644         return 0
9645 }
9646 run_test 118j "Simulate unrecoverable OST side error =========="
9647
9648 test_118k()
9649 {
9650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9651         remote_ost_nodsh && skip "remote OSTs with nodsh"
9652
9653         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9654         set_nodes_failloc "$(osts_nodes)" 0x20e
9655         test_mkdir $DIR/$tdir
9656
9657         for ((i=0;i<10;i++)); do
9658                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9659                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9660                 SLEEPPID=$!
9661                 sleep 0.500s
9662                 kill $SLEEPPID
9663                 wait $SLEEPPID
9664         done
9665
9666         set_nodes_failloc "$(osts_nodes)" 0
9667         rm -rf $DIR/$tdir
9668 }
9669 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9670
9671 test_118l() # LU-646
9672 {
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674
9675         test_mkdir $DIR/$tdir
9676         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9677         rm -rf $DIR/$tdir
9678 }
9679 run_test 118l "fsync dir"
9680
9681 test_118m() # LU-3066
9682 {
9683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9684
9685         test_mkdir $DIR/$tdir
9686         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9687         rm -rf $DIR/$tdir
9688 }
9689 run_test 118m "fdatasync dir ========="
9690
9691 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9692
9693 test_118n()
9694 {
9695         local begin
9696         local end
9697
9698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9699         remote_ost_nodsh && skip "remote OSTs with nodsh"
9700
9701         # Sleep to avoid a cached response.
9702         #define OBD_STATFS_CACHE_SECONDS 1
9703         sleep 2
9704
9705         # Inject a 10 second delay in the OST_STATFS handler.
9706         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9707         set_nodes_failloc "$(osts_nodes)" 0x242
9708
9709         begin=$SECONDS
9710         stat --file-system $MOUNT > /dev/null
9711         end=$SECONDS
9712
9713         set_nodes_failloc "$(osts_nodes)" 0
9714
9715         if ((end - begin > 20)); then
9716             error "statfs took $((end - begin)) seconds, expected 10"
9717         fi
9718 }
9719 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9720
9721 test_119a() # bug 11737
9722 {
9723         BSIZE=$((512 * 1024))
9724         directio write $DIR/$tfile 0 1 $BSIZE
9725         # We ask to read two blocks, which is more than a file size.
9726         # directio will indicate an error when requested and actual
9727         # sizes aren't equeal (a normal situation in this case) and
9728         # print actual read amount.
9729         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9730         if [ "$NOB" != "$BSIZE" ]; then
9731                 error "read $NOB bytes instead of $BSIZE"
9732         fi
9733         rm -f $DIR/$tfile
9734 }
9735 run_test 119a "Short directIO read must return actual read amount"
9736
9737 test_119b() # bug 11737
9738 {
9739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9740
9741         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9743         sync
9744         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9745                 error "direct read failed"
9746         rm -f $DIR/$tfile
9747 }
9748 run_test 119b "Sparse directIO read must return actual read amount"
9749
9750 test_119c() # bug 13099
9751 {
9752         BSIZE=1048576
9753         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9754         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9755         rm -f $DIR/$tfile
9756 }
9757 run_test 119c "Testing for direct read hitting hole"
9758
9759 test_119d() # bug 15950
9760 {
9761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9762
9763         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9764         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9765         BSIZE=1048576
9766         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9767         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9768         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9769         lctl set_param fail_loc=0x40d
9770         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9771         pid_dio=$!
9772         sleep 1
9773         cat $DIR/$tfile > /dev/null &
9774         lctl set_param fail_loc=0
9775         pid_reads=$!
9776         wait $pid_dio
9777         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9778         sleep 2
9779         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9780         error "the read rpcs have not completed in 2s"
9781         rm -f $DIR/$tfile
9782         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9783 }
9784 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9785
9786 test_120a() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         remote_mds_nodsh && skip "remote MDS with nodsh"
9789         test_mkdir -i0 -c1 $DIR/$tdir
9790         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9791                 skip_env "no early lock cancel on server"
9792
9793         lru_resize_disable mdc
9794         lru_resize_disable osc
9795         cancel_lru_locks mdc
9796         # asynchronous object destroy at MDT could cause bl ast to client
9797         cancel_lru_locks osc
9798
9799         stat $DIR/$tdir > /dev/null
9800         can1=$(do_facet mds1 \
9801                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9802                awk '/ldlm_cancel/ {print $2}')
9803         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9804                awk '/ldlm_bl_callback/ {print $2}')
9805         test_mkdir -i0 -c1 $DIR/$tdir/d1
9806         can2=$(do_facet mds1 \
9807                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9808                awk '/ldlm_cancel/ {print $2}')
9809         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9810                awk '/ldlm_bl_callback/ {print $2}')
9811         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9812         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9813         lru_resize_enable mdc
9814         lru_resize_enable osc
9815 }
9816 run_test 120a "Early Lock Cancel: mkdir test"
9817
9818 test_120b() {
9819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9820         remote_mds_nodsh && skip "remote MDS with nodsh"
9821         test_mkdir $DIR/$tdir
9822         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9823                 skip_env "no early lock cancel on server"
9824
9825         lru_resize_disable mdc
9826         lru_resize_disable osc
9827         cancel_lru_locks mdc
9828         stat $DIR/$tdir > /dev/null
9829         can1=$(do_facet $SINGLEMDS \
9830                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9831                awk '/ldlm_cancel/ {print $2}')
9832         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9833                awk '/ldlm_bl_callback/ {print $2}')
9834         touch $DIR/$tdir/f1
9835         can2=$(do_facet $SINGLEMDS \
9836                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9837                awk '/ldlm_cancel/ {print $2}')
9838         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9839                awk '/ldlm_bl_callback/ {print $2}')
9840         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9841         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9842         lru_resize_enable mdc
9843         lru_resize_enable osc
9844 }
9845 run_test 120b "Early Lock Cancel: create test"
9846
9847 test_120c() {
9848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9849         remote_mds_nodsh && skip "remote MDS with nodsh"
9850         test_mkdir -i0 -c1 $DIR/$tdir
9851         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9852                 skip "no early lock cancel on server"
9853
9854         lru_resize_disable mdc
9855         lru_resize_disable osc
9856         test_mkdir -i0 -c1 $DIR/$tdir/d1
9857         test_mkdir -i0 -c1 $DIR/$tdir/d2
9858         touch $DIR/$tdir/d1/f1
9859         cancel_lru_locks mdc
9860         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9861         can1=$(do_facet mds1 \
9862                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9863                awk '/ldlm_cancel/ {print $2}')
9864         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9865                awk '/ldlm_bl_callback/ {print $2}')
9866         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9867         can2=$(do_facet mds1 \
9868                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9869                awk '/ldlm_cancel/ {print $2}')
9870         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9871                awk '/ldlm_bl_callback/ {print $2}')
9872         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9873         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9874         lru_resize_enable mdc
9875         lru_resize_enable osc
9876 }
9877 run_test 120c "Early Lock Cancel: link test"
9878
9879 test_120d() {
9880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9881         remote_mds_nodsh && skip "remote MDS with nodsh"
9882         test_mkdir -i0 -c1 $DIR/$tdir
9883         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9884                 skip_env "no early lock cancel on server"
9885
9886         lru_resize_disable mdc
9887         lru_resize_disable osc
9888         touch $DIR/$tdir
9889         cancel_lru_locks mdc
9890         stat $DIR/$tdir > /dev/null
9891         can1=$(do_facet mds1 \
9892                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9893                awk '/ldlm_cancel/ {print $2}')
9894         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9895                awk '/ldlm_bl_callback/ {print $2}')
9896         chmod a+x $DIR/$tdir
9897         can2=$(do_facet mds1 \
9898                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9899                awk '/ldlm_cancel/ {print $2}')
9900         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9901                awk '/ldlm_bl_callback/ {print $2}')
9902         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9903         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9904         lru_resize_enable mdc
9905         lru_resize_enable osc
9906 }
9907 run_test 120d "Early Lock Cancel: setattr test"
9908
9909 test_120e() {
9910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9911         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9912                 skip_env "no early lock cancel on server"
9913         remote_mds_nodsh && skip "remote MDS with nodsh"
9914
9915         local dlmtrace_set=false
9916
9917         test_mkdir -i0 -c1 $DIR/$tdir
9918         lru_resize_disable mdc
9919         lru_resize_disable osc
9920         ! $LCTL get_param debug | grep -q dlmtrace &&
9921                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9922         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9923         cancel_lru_locks mdc
9924         cancel_lru_locks osc
9925         dd if=$DIR/$tdir/f1 of=/dev/null
9926         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9927         # XXX client can not do early lock cancel of OST lock
9928         # during unlink (LU-4206), so cancel osc lock now.
9929         sleep 2
9930         cancel_lru_locks osc
9931         can1=$(do_facet mds1 \
9932                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9933                awk '/ldlm_cancel/ {print $2}')
9934         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9935                awk '/ldlm_bl_callback/ {print $2}')
9936         unlink $DIR/$tdir/f1
9937         sleep 5
9938         can2=$(do_facet mds1 \
9939                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9940                awk '/ldlm_cancel/ {print $2}')
9941         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9942                awk '/ldlm_bl_callback/ {print $2}')
9943         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9944                 $LCTL dk $TMP/cancel.debug.txt
9945         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9946                 $LCTL dk $TMP/blocking.debug.txt
9947         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9948         lru_resize_enable mdc
9949         lru_resize_enable osc
9950 }
9951 run_test 120e "Early Lock Cancel: unlink test"
9952
9953 test_120f() {
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9956                 skip_env "no early lock cancel on server"
9957         remote_mds_nodsh && skip "remote MDS with nodsh"
9958
9959         test_mkdir -i0 -c1 $DIR/$tdir
9960         lru_resize_disable mdc
9961         lru_resize_disable osc
9962         test_mkdir -i0 -c1 $DIR/$tdir/d1
9963         test_mkdir -i0 -c1 $DIR/$tdir/d2
9964         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9965         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9966         cancel_lru_locks mdc
9967         cancel_lru_locks osc
9968         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9969         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9970         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9971         # XXX client can not do early lock cancel of OST lock
9972         # during rename (LU-4206), so cancel osc lock now.
9973         sleep 2
9974         cancel_lru_locks osc
9975         can1=$(do_facet mds1 \
9976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9977                awk '/ldlm_cancel/ {print $2}')
9978         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9979                awk '/ldlm_bl_callback/ {print $2}')
9980         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9981         sleep 5
9982         can2=$(do_facet mds1 \
9983                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9984                awk '/ldlm_cancel/ {print $2}')
9985         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9986                awk '/ldlm_bl_callback/ {print $2}')
9987         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9988         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9989         lru_resize_enable mdc
9990         lru_resize_enable osc
9991 }
9992 run_test 120f "Early Lock Cancel: rename test"
9993
9994 test_120g() {
9995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9996         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9997                 skip_env "no early lock cancel on server"
9998         remote_mds_nodsh && skip "remote MDS with nodsh"
9999
10000         lru_resize_disable mdc
10001         lru_resize_disable osc
10002         count=10000
10003         echo create $count files
10004         test_mkdir $DIR/$tdir
10005         cancel_lru_locks mdc
10006         cancel_lru_locks osc
10007         t0=$(date +%s)
10008
10009         can0=$(do_facet $SINGLEMDS \
10010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10011                awk '/ldlm_cancel/ {print $2}')
10012         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10013                awk '/ldlm_bl_callback/ {print $2}')
10014         createmany -o $DIR/$tdir/f $count
10015         sync
10016         can1=$(do_facet $SINGLEMDS \
10017                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10018                awk '/ldlm_cancel/ {print $2}')
10019         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10020                awk '/ldlm_bl_callback/ {print $2}')
10021         t1=$(date +%s)
10022         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10023         echo rm $count files
10024         rm -r $DIR/$tdir
10025         sync
10026         can2=$(do_facet $SINGLEMDS \
10027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10028                awk '/ldlm_cancel/ {print $2}')
10029         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10030                awk '/ldlm_bl_callback/ {print $2}')
10031         t2=$(date +%s)
10032         echo total: $count removes in $((t2-t1))
10033         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10034         sleep 2
10035         # wait for commitment of removal
10036         lru_resize_enable mdc
10037         lru_resize_enable osc
10038 }
10039 run_test 120g "Early Lock Cancel: performance test"
10040
10041 test_121() { #bug #10589
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         rm -rf $DIR/$tfile
10045         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10046 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10047         lctl set_param fail_loc=0x310
10048         cancel_lru_locks osc > /dev/null
10049         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10050         lctl set_param fail_loc=0
10051         [[ $reads -eq $writes ]] ||
10052                 error "read $reads blocks, must be $writes blocks"
10053 }
10054 run_test 121 "read cancel race ========="
10055
10056 test_123a() { # was test 123, statahead(bug 11401)
10057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10058
10059         SLOWOK=0
10060         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10061                 log "testing UP system. Performance may be lower than expected."
10062                 SLOWOK=1
10063         fi
10064
10065         rm -rf $DIR/$tdir
10066         test_mkdir $DIR/$tdir
10067         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10068         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10069         MULT=10
10070         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10071                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10072
10073                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10074                 lctl set_param -n llite.*.statahead_max 0
10075                 lctl get_param llite.*.statahead_max
10076                 cancel_lru_locks mdc
10077                 cancel_lru_locks osc
10078                 stime=`date +%s`
10079                 time ls -l $DIR/$tdir | wc -l
10080                 etime=`date +%s`
10081                 delta=$((etime - stime))
10082                 log "ls $i files without statahead: $delta sec"
10083                 lctl set_param llite.*.statahead_max=$max
10084
10085                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10086                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10087                 cancel_lru_locks mdc
10088                 cancel_lru_locks osc
10089                 stime=`date +%s`
10090                 time ls -l $DIR/$tdir | wc -l
10091                 etime=`date +%s`
10092                 delta_sa=$((etime - stime))
10093                 log "ls $i files with statahead: $delta_sa sec"
10094                 lctl get_param -n llite.*.statahead_stats
10095                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10096
10097                 [[ $swrong -lt $ewrong ]] &&
10098                         log "statahead was stopped, maybe too many locks held!"
10099                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10100
10101                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10102                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10103                     lctl set_param -n llite.*.statahead_max 0
10104                     lctl get_param llite.*.statahead_max
10105                     cancel_lru_locks mdc
10106                     cancel_lru_locks osc
10107                     stime=`date +%s`
10108                     time ls -l $DIR/$tdir | wc -l
10109                     etime=`date +%s`
10110                     delta=$((etime - stime))
10111                     log "ls $i files again without statahead: $delta sec"
10112                     lctl set_param llite.*.statahead_max=$max
10113                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10114                         if [  $SLOWOK -eq 0 ]; then
10115                                 error "ls $i files is slower with statahead!"
10116                         else
10117                                 log "ls $i files is slower with statahead!"
10118                         fi
10119                         break
10120                     fi
10121                 fi
10122
10123                 [ $delta -gt 20 ] && break
10124                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10125                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10126         done
10127         log "ls done"
10128
10129         stime=`date +%s`
10130         rm -r $DIR/$tdir
10131         sync
10132         etime=`date +%s`
10133         delta=$((etime - stime))
10134         log "rm -r $DIR/$tdir/: $delta seconds"
10135         log "rm done"
10136         lctl get_param -n llite.*.statahead_stats
10137 }
10138 run_test 123a "verify statahead work"
10139
10140 test_123b () { # statahead(bug 15027)
10141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10142
10143         test_mkdir $DIR/$tdir
10144         createmany -o $DIR/$tdir/$tfile-%d 1000
10145
10146         cancel_lru_locks mdc
10147         cancel_lru_locks osc
10148
10149 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10150         lctl set_param fail_loc=0x80000803
10151         ls -lR $DIR/$tdir > /dev/null
10152         log "ls done"
10153         lctl set_param fail_loc=0x0
10154         lctl get_param -n llite.*.statahead_stats
10155         rm -r $DIR/$tdir
10156         sync
10157
10158 }
10159 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10160
10161 test_124a() {
10162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10163         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10164                 skip_env "no lru resize on server"
10165
10166         local NR=2000
10167
10168         test_mkdir $DIR/$tdir
10169
10170         log "create $NR files at $DIR/$tdir"
10171         createmany -o $DIR/$tdir/f $NR ||
10172                 error "failed to create $NR files in $DIR/$tdir"
10173
10174         cancel_lru_locks mdc
10175         ls -l $DIR/$tdir > /dev/null
10176
10177         local NSDIR=""
10178         local LRU_SIZE=0
10179         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10180                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10181                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10182                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10183                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10184                         log "NSDIR=$NSDIR"
10185                         log "NS=$(basename $NSDIR)"
10186                         break
10187                 fi
10188         done
10189
10190         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10191                 skip "Not enough cached locks created!"
10192         fi
10193         log "LRU=$LRU_SIZE"
10194
10195         local SLEEP=30
10196
10197         # We know that lru resize allows one client to hold $LIMIT locks
10198         # for 10h. After that locks begin to be killed by client.
10199         local MAX_HRS=10
10200         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10201         log "LIMIT=$LIMIT"
10202         if [ $LIMIT -lt $LRU_SIZE ]; then
10203                 skip "Limit is too small $LIMIT"
10204         fi
10205
10206         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10207         # killing locks. Some time was spent for creating locks. This means
10208         # that up to the moment of sleep finish we must have killed some of
10209         # them (10-100 locks). This depends on how fast ther were created.
10210         # Many of them were touched in almost the same moment and thus will
10211         # be killed in groups.
10212         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10213
10214         # Use $LRU_SIZE_B here to take into account real number of locks
10215         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10216         local LRU_SIZE_B=$LRU_SIZE
10217         log "LVF=$LVF"
10218         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10219         log "OLD_LVF=$OLD_LVF"
10220         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10221
10222         # Let's make sure that we really have some margin. Client checks
10223         # cached locks every 10 sec.
10224         SLEEP=$((SLEEP+20))
10225         log "Sleep ${SLEEP} sec"
10226         local SEC=0
10227         while ((SEC<$SLEEP)); do
10228                 echo -n "..."
10229                 sleep 5
10230                 SEC=$((SEC+5))
10231                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10232                 echo -n "$LRU_SIZE"
10233         done
10234         echo ""
10235         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10236         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10237
10238         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10239                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10240                 unlinkmany $DIR/$tdir/f $NR
10241                 return
10242         }
10243
10244         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10245         log "unlink $NR files at $DIR/$tdir"
10246         unlinkmany $DIR/$tdir/f $NR
10247 }
10248 run_test 124a "lru resize ======================================="
10249
10250 get_max_pool_limit()
10251 {
10252         local limit=$($LCTL get_param \
10253                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10254         local max=0
10255         for l in $limit; do
10256                 if [[ $l -gt $max ]]; then
10257                         max=$l
10258                 fi
10259         done
10260         echo $max
10261 }
10262
10263 test_124b() {
10264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10265         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10266                 skip_env "no lru resize on server"
10267
10268         LIMIT=$(get_max_pool_limit)
10269
10270         NR=$(($(default_lru_size)*20))
10271         if [[ $NR -gt $LIMIT ]]; then
10272                 log "Limit lock number by $LIMIT locks"
10273                 NR=$LIMIT
10274         fi
10275
10276         IFree=$(mdsrate_inodes_available)
10277         if [ $IFree -lt $NR ]; then
10278                 log "Limit lock number by $IFree inodes"
10279                 NR=$IFree
10280         fi
10281
10282         lru_resize_disable mdc
10283         test_mkdir -p $DIR/$tdir/disable_lru_resize
10284
10285         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10286         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10287         cancel_lru_locks mdc
10288         stime=`date +%s`
10289         PID=""
10290         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10291         PID="$PID $!"
10292         sleep 2
10293         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10294         PID="$PID $!"
10295         sleep 2
10296         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10297         PID="$PID $!"
10298         wait $PID
10299         etime=`date +%s`
10300         nolruresize_delta=$((etime-stime))
10301         log "ls -la time: $nolruresize_delta seconds"
10302         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10303         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10304
10305         lru_resize_enable mdc
10306         test_mkdir -p $DIR/$tdir/enable_lru_resize
10307
10308         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10309         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10310         cancel_lru_locks mdc
10311         stime=`date +%s`
10312         PID=""
10313         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10314         PID="$PID $!"
10315         sleep 2
10316         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10317         PID="$PID $!"
10318         sleep 2
10319         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10320         PID="$PID $!"
10321         wait $PID
10322         etime=`date +%s`
10323         lruresize_delta=$((etime-stime))
10324         log "ls -la time: $lruresize_delta seconds"
10325         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10326
10327         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10328                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10329         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10330                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10331         else
10332                 log "lru resize performs the same with no lru resize"
10333         fi
10334         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10335 }
10336 run_test 124b "lru resize (performance test) ======================="
10337
10338 test_124c() {
10339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10340         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10341                 skip_env "no lru resize on server"
10342
10343         # cache ununsed locks on client
10344         local nr=100
10345         cancel_lru_locks mdc
10346         test_mkdir $DIR/$tdir
10347         createmany -o $DIR/$tdir/f $nr ||
10348                 error "failed to create $nr files in $DIR/$tdir"
10349         ls -l $DIR/$tdir > /dev/null
10350
10351         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10352         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10353         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10354         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10355         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10356
10357         # set lru_max_age to 1 sec
10358         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10359         echo "sleep $((recalc_p * 2)) seconds..."
10360         sleep $((recalc_p * 2))
10361
10362         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10363         # restore lru_max_age
10364         $LCTL set_param -n $nsdir.lru_max_age $max_age
10365         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10366         unlinkmany $DIR/$tdir/f $nr
10367 }
10368 run_test 124c "LRUR cancel very aged locks"
10369
10370 test_125() { # 13358
10371         $LCTL get_param -n llite.*.client_type | grep -q local ||
10372                 skip "must run as local client"
10373         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10374                 skip_env "must have acl enabled"
10375         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10376
10377         test_mkdir $DIR/$tdir
10378         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10379         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10380         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10381 }
10382 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10383
10384 test_126() { # bug 12829/13455
10385         $GSS && skip_env "must run as gss disabled"
10386         $LCTL get_param -n llite.*.client_type | grep -q local ||
10387                 skip "must run as local client"
10388         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10389
10390         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10391         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10392         rm -f $DIR/$tfile
10393         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10394 }
10395 run_test 126 "check that the fsgid provided by the client is taken into account"
10396
10397 test_127a() { # bug 15521
10398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10399
10400         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10401         $LCTL set_param osc.*.stats=0
10402         FSIZE=$((2048 * 1024))
10403         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10404         cancel_lru_locks osc
10405         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10406
10407         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10408         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10409                 echo "got $COUNT $NAME"
10410                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10411                 eval $NAME=$COUNT || error "Wrong proc format"
10412
10413                 case $NAME in
10414                         read_bytes|write_bytes)
10415                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10416                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10417                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10418                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10419                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10420                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10421                                 error "sumsquare is too small: $SUMSQ"
10422                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10423                                 error "sumsquare is too big: $SUMSQ"
10424                         ;;
10425                         *) ;;
10426                 esac
10427         done < $DIR/${tfile}.tmp
10428
10429         #check that we actually got some stats
10430         [ "$read_bytes" ] || error "Missing read_bytes stats"
10431         [ "$write_bytes" ] || error "Missing write_bytes stats"
10432         [ "$read_bytes" != 0 ] || error "no read done"
10433         [ "$write_bytes" != 0 ] || error "no write done"
10434 }
10435 run_test 127a "verify the client stats are sane"
10436
10437 test_127b() { # bug LU-333
10438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10439         local name count samp unit min max sum sumsq
10440
10441         $LCTL set_param llite.*.stats=0
10442
10443         # perform 2 reads and writes so MAX is different from SUM.
10444         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10445         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10446         cancel_lru_locks osc
10447         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10448         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10449
10450         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10451         while read name count samp unit min max sum sumsq; do
10452                 echo "got $count $name"
10453                 eval $name=$count || error "Wrong proc format"
10454
10455                 case $name in
10456                 read_bytes)
10457                         [ $count -ne 2 ] && error "count is not 2: $count"
10458                         [ $min -ne $PAGE_SIZE ] &&
10459                                 error "min is not $PAGE_SIZE: $min"
10460                         [ $max -ne $PAGE_SIZE ] &&
10461                                 error "max is incorrect: $max"
10462                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10463                                 error "sum is wrong: $sum"
10464                         ;;
10465                 write_bytes)
10466                         [ $count -ne 2 ] && error "count is not 2: $count"
10467                         [ $min -ne $PAGE_SIZE ] &&
10468                                 error "min is not $PAGE_SIZE: $min"
10469                         [ $max -ne $PAGE_SIZE ] &&
10470                                 error "max is incorrect: $max"
10471                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10472                                 error "sum is wrong: $sum"
10473                         ;;
10474                 *) ;;
10475                 esac
10476         done < $TMP/$tfile.tmp
10477
10478         #check that we actually got some stats
10479         [ "$read_bytes" ] || error "Missing read_bytes stats"
10480         [ "$write_bytes" ] || error "Missing write_bytes stats"
10481         [ "$read_bytes" != 0 ] || error "no read done"
10482         [ "$write_bytes" != 0 ] || error "no write done"
10483
10484         rm -f $TMP/${tfile}.tmp
10485 }
10486 run_test 127b "verify the llite client stats are sane"
10487
10488 test_128() { # bug 15212
10489         touch $DIR/$tfile
10490         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10491                 find $DIR/$tfile
10492                 find $DIR/$tfile
10493         EOF
10494
10495         result=$(grep error $TMP/$tfile.log)
10496         rm -f $DIR/$tfile $TMP/$tfile.log
10497         [ -z "$result" ] ||
10498                 error "consecutive find's under interactive lfs failed"
10499 }
10500 run_test 128 "interactive lfs for 2 consecutive find's"
10501
10502 set_dir_limits () {
10503         local mntdev
10504         local canondev
10505         local node
10506
10507         local ldproc=/proc/fs/ldiskfs
10508         local facets=$(get_facets MDS)
10509
10510         for facet in ${facets//,/ }; do
10511                 canondev=$(ldiskfs_canon \
10512                            *.$(convert_facet2label $facet).mntdev $facet)
10513                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10514                         ldproc=/sys/fs/ldiskfs
10515                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10516                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10517         done
10518 }
10519
10520 check_mds_dmesg() {
10521         local facets=$(get_facets MDS)
10522         for facet in ${facets//,/ }; do
10523                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10524         done
10525         return 1
10526 }
10527
10528 test_129() {
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10531                 skip "Need MDS version with at least 2.5.56"
10532         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10533                 skip_env "ldiskfs only test"
10534         fi
10535         remote_mds_nodsh && skip "remote MDS with nodsh"
10536
10537         local ENOSPC=28
10538         local EFBIG=27
10539         local has_warning=false
10540
10541         rm -rf $DIR/$tdir
10542         mkdir -p $DIR/$tdir
10543
10544         # block size of mds1
10545         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10546         set_dir_limits $maxsize $maxsize
10547         local dirsize=$(stat -c%s "$DIR/$tdir")
10548         local nfiles=0
10549         while [[ $dirsize -le $maxsize ]]; do
10550                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10551                 rc=$?
10552                 if ! $has_warning; then
10553                         check_mds_dmesg '"is approaching"' && has_warning=true
10554                 fi
10555                 # check two errors:
10556                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10557                 # EFBIG for previous versions included in ldiskfs series
10558                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10559                         set_dir_limits 0 0
10560                         echo "return code $rc received as expected"
10561
10562                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10563                                 error_exit "create failed w/o dir size limit"
10564
10565                         check_mds_dmesg '"has reached"' ||
10566                                 error_exit "reached message should be output"
10567
10568                         [ $has_warning = "false" ] &&
10569                                 error_exit "warning message should be output"
10570
10571                         dirsize=$(stat -c%s "$DIR/$tdir")
10572
10573                         [[ $dirsize -ge $maxsize ]] && return 0
10574                         error_exit "current dir size $dirsize, " \
10575                                    "previous limit $maxsize"
10576                 elif [ $rc -ne 0 ]; then
10577                         set_dir_limits 0 0
10578                         error_exit "return $rc received instead of expected " \
10579                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10580                 fi
10581                 nfiles=$((nfiles + 1))
10582                 dirsize=$(stat -c%s "$DIR/$tdir")
10583         done
10584
10585         set_dir_limits 0 0
10586         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10587 }
10588 run_test 129 "test directory size limit ========================"
10589
10590 OLDIFS="$IFS"
10591 cleanup_130() {
10592         trap 0
10593         IFS="$OLDIFS"
10594 }
10595
10596 test_130a() {
10597         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10598         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10599
10600         trap cleanup_130 EXIT RETURN
10601
10602         local fm_file=$DIR/$tfile
10603         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10604         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10605                 error "dd failed for $fm_file"
10606
10607         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10608         filefrag -ves $fm_file
10609         RC=$?
10610         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10611                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10612         [ $RC != 0 ] && error "filefrag $fm_file failed"
10613
10614         filefrag_op=$(filefrag -ve -k $fm_file |
10615                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10616         lun=$($LFS getstripe -i $fm_file)
10617
10618         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10619         IFS=$'\n'
10620         tot_len=0
10621         for line in $filefrag_op
10622         do
10623                 frag_lun=`echo $line | cut -d: -f5`
10624                 ext_len=`echo $line | cut -d: -f4`
10625                 if (( $frag_lun != $lun )); then
10626                         cleanup_130
10627                         error "FIEMAP on 1-stripe file($fm_file) failed"
10628                         return
10629                 fi
10630                 (( tot_len += ext_len ))
10631         done
10632
10633         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10634                 cleanup_130
10635                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10636                 return
10637         fi
10638
10639         cleanup_130
10640
10641         echo "FIEMAP on single striped file succeeded"
10642 }
10643 run_test 130a "FIEMAP (1-stripe file)"
10644
10645 test_130b() {
10646         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10647
10648         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10649         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10650
10651         trap cleanup_130 EXIT RETURN
10652
10653         local fm_file=$DIR/$tfile
10654         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10655                         error "setstripe on $fm_file"
10656         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10657                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10658
10659         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10660                 error "dd failed on $fm_file"
10661
10662         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10663         filefrag_op=$(filefrag -ve -k $fm_file |
10664                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10665
10666         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10667                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10668
10669         IFS=$'\n'
10670         tot_len=0
10671         num_luns=1
10672         for line in $filefrag_op
10673         do
10674                 frag_lun=$(echo $line | cut -d: -f5 |
10675                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10676                 ext_len=$(echo $line | cut -d: -f4)
10677                 if (( $frag_lun != $last_lun )); then
10678                         if (( tot_len != 1024 )); then
10679                                 cleanup_130
10680                                 error "FIEMAP on $fm_file failed; returned " \
10681                                 "len $tot_len for OST $last_lun instead of 1024"
10682                                 return
10683                         else
10684                                 (( num_luns += 1 ))
10685                                 tot_len=0
10686                         fi
10687                 fi
10688                 (( tot_len += ext_len ))
10689                 last_lun=$frag_lun
10690         done
10691         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10692                 cleanup_130
10693                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10694                         "luns or wrong len for OST $last_lun"
10695                 return
10696         fi
10697
10698         cleanup_130
10699
10700         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10701 }
10702 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10703
10704 test_130c() {
10705         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10706
10707         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10708         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10709
10710         trap cleanup_130 EXIT RETURN
10711
10712         local fm_file=$DIR/$tfile
10713         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10714         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10715                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10716
10717         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10718                         error "dd failed on $fm_file"
10719
10720         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10721         filefrag_op=$(filefrag -ve -k $fm_file |
10722                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10723
10724         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10725                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10726
10727         IFS=$'\n'
10728         tot_len=0
10729         num_luns=1
10730         for line in $filefrag_op
10731         do
10732                 frag_lun=$(echo $line | cut -d: -f5 |
10733                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10734                 ext_len=$(echo $line | cut -d: -f4)
10735                 if (( $frag_lun != $last_lun )); then
10736                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10737                         if (( logical != 512 )); then
10738                                 cleanup_130
10739                                 error "FIEMAP on $fm_file failed; returned " \
10740                                 "logical start for lun $logical instead of 512"
10741                                 return
10742                         fi
10743                         if (( tot_len != 512 )); then
10744                                 cleanup_130
10745                                 error "FIEMAP on $fm_file failed; returned " \
10746                                 "len $tot_len for OST $last_lun instead of 1024"
10747                                 return
10748                         else
10749                                 (( num_luns += 1 ))
10750                                 tot_len=0
10751                         fi
10752                 fi
10753                 (( tot_len += ext_len ))
10754                 last_lun=$frag_lun
10755         done
10756         if (( num_luns != 2 || tot_len != 512 )); then
10757                 cleanup_130
10758                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10759                         "luns or wrong len for OST $last_lun"
10760                 return
10761         fi
10762
10763         cleanup_130
10764
10765         echo "FIEMAP on 2-stripe file with hole succeeded"
10766 }
10767 run_test 130c "FIEMAP (2-stripe file with hole)"
10768
10769 test_130d() {
10770         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10771
10772         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10773         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10774
10775         trap cleanup_130 EXIT RETURN
10776
10777         local fm_file=$DIR/$tfile
10778         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10779                         error "setstripe on $fm_file"
10780         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10781                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10782
10783         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10784         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10785                 error "dd failed on $fm_file"
10786
10787         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10788         filefrag_op=$(filefrag -ve -k $fm_file |
10789                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10790
10791         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10792                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10793
10794         IFS=$'\n'
10795         tot_len=0
10796         num_luns=1
10797         for line in $filefrag_op
10798         do
10799                 frag_lun=$(echo $line | cut -d: -f5 |
10800                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10801                 ext_len=$(echo $line | cut -d: -f4)
10802                 if (( $frag_lun != $last_lun )); then
10803                         if (( tot_len != 1024 )); then
10804                                 cleanup_130
10805                                 error "FIEMAP on $fm_file failed; returned " \
10806                                 "len $tot_len for OST $last_lun instead of 1024"
10807                                 return
10808                         else
10809                                 (( num_luns += 1 ))
10810                                 tot_len=0
10811                         fi
10812                 fi
10813                 (( tot_len += ext_len ))
10814                 last_lun=$frag_lun
10815         done
10816         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10817                 cleanup_130
10818                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10819                         "luns or wrong len for OST $last_lun"
10820                 return
10821         fi
10822
10823         cleanup_130
10824
10825         echo "FIEMAP on N-stripe file succeeded"
10826 }
10827 run_test 130d "FIEMAP (N-stripe file)"
10828
10829 test_130e() {
10830         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10831
10832         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10833         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10834
10835         trap cleanup_130 EXIT RETURN
10836
10837         local fm_file=$DIR/$tfile
10838         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10839         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10840                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10841
10842         NUM_BLKS=512
10843         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10844         for ((i = 0; i < $NUM_BLKS; i++))
10845         do
10846                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10847         done
10848
10849         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10850         filefrag_op=$(filefrag -ve -k $fm_file |
10851                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10852
10853         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10854                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10855
10856         IFS=$'\n'
10857         tot_len=0
10858         num_luns=1
10859         for line in $filefrag_op
10860         do
10861                 frag_lun=$(echo $line | cut -d: -f5 |
10862                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10863                 ext_len=$(echo $line | cut -d: -f4)
10864                 if (( $frag_lun != $last_lun )); then
10865                         if (( tot_len != $EXPECTED_LEN )); then
10866                                 cleanup_130
10867                                 error "FIEMAP on $fm_file failed; returned " \
10868                                 "len $tot_len for OST $last_lun instead " \
10869                                 "of $EXPECTED_LEN"
10870                                 return
10871                         else
10872                                 (( num_luns += 1 ))
10873                                 tot_len=0
10874                         fi
10875                 fi
10876                 (( tot_len += ext_len ))
10877                 last_lun=$frag_lun
10878         done
10879         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10880                 cleanup_130
10881                 error "FIEMAP on $fm_file failed; returned wrong number " \
10882                         "of luns or wrong len for OST $last_lun"
10883                 return
10884         fi
10885
10886         cleanup_130
10887
10888         echo "FIEMAP with continuation calls succeeded"
10889 }
10890 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10891
10892 test_130f() {
10893         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10894         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10895
10896         local fm_file=$DIR/$tfile
10897         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10898                 error "multiop create with lov_delay_create on $fm_file"
10899
10900         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10901         filefrag_extents=$(filefrag -vek $fm_file |
10902                            awk '/extents? found/ { print $2 }')
10903         if [[ "$filefrag_extents" != "0" ]]; then
10904                 error "FIEMAP on $fm_file failed; " \
10905                       "returned $filefrag_extents expected 0"
10906         fi
10907
10908         rm -f $fm_file
10909 }
10910 run_test 130f "FIEMAP (unstriped file)"
10911
10912 # Test for writev/readv
10913 test_131a() {
10914         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10915                 error "writev test failed"
10916         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10917                 error "readv failed"
10918         rm -f $DIR/$tfile
10919 }
10920 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10921
10922 test_131b() {
10923         local fsize=$((524288 + 1048576 + 1572864))
10924         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10925                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10926                         error "append writev test failed"
10927
10928         ((fsize += 1572864 + 1048576))
10929         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10930                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10931                         error "append writev test failed"
10932         rm -f $DIR/$tfile
10933 }
10934 run_test 131b "test append writev"
10935
10936 test_131c() {
10937         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10938         error "NOT PASS"
10939 }
10940 run_test 131c "test read/write on file w/o objects"
10941
10942 test_131d() {
10943         rwv -f $DIR/$tfile -w -n 1 1572864
10944         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10945         if [ "$NOB" != 1572864 ]; then
10946                 error "Short read filed: read $NOB bytes instead of 1572864"
10947         fi
10948         rm -f $DIR/$tfile
10949 }
10950 run_test 131d "test short read"
10951
10952 test_131e() {
10953         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10954         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10955         error "read hitting hole failed"
10956         rm -f $DIR/$tfile
10957 }
10958 run_test 131e "test read hitting hole"
10959
10960 check_stats() {
10961         local facet=$1
10962         local op=$2
10963         local want=${3:-0}
10964         local res
10965
10966         case $facet in
10967         mds*) res=$(do_facet $facet \
10968                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10969                  ;;
10970         ost*) res=$(do_facet $facet \
10971                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10972                  ;;
10973         *) error "Wrong facet '$facet'" ;;
10974         esac
10975         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10976         # if the argument $3 is zero, it means any stat increment is ok.
10977         if [[ $want -gt 0 ]]; then
10978                 local count=$(echo $res | awk '{ print $2 }')
10979                 [[ $count -ne $want ]] &&
10980                         error "The $op counter on $facet is $count, not $want"
10981         fi
10982 }
10983
10984 test_133a() {
10985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10986         remote_ost_nodsh && skip "remote OST with nodsh"
10987         remote_mds_nodsh && skip "remote MDS with nodsh"
10988         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10989                 skip_env "MDS doesn't support rename stats"
10990
10991         local testdir=$DIR/${tdir}/stats_testdir
10992
10993         mkdir -p $DIR/${tdir}
10994
10995         # clear stats.
10996         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10997         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10998
10999         # verify mdt stats first.
11000         mkdir ${testdir} || error "mkdir failed"
11001         check_stats $SINGLEMDS "mkdir" 1
11002         touch ${testdir}/${tfile} || error "touch failed"
11003         check_stats $SINGLEMDS "open" 1
11004         check_stats $SINGLEMDS "close" 1
11005         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11006                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11007                 check_stats $SINGLEMDS "mknod" 2
11008         }
11009         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11010         check_stats $SINGLEMDS "unlink" 1
11011         rm -f ${testdir}/${tfile} || error "file remove failed"
11012         check_stats $SINGLEMDS "unlink" 2
11013
11014         # remove working dir and check mdt stats again.
11015         rmdir ${testdir} || error "rmdir failed"
11016         check_stats $SINGLEMDS "rmdir" 1
11017
11018         local testdir1=$DIR/${tdir}/stats_testdir1
11019         mkdir -p ${testdir}
11020         mkdir -p ${testdir1}
11021         touch ${testdir1}/test1
11022         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11023         check_stats $SINGLEMDS "crossdir_rename" 1
11024
11025         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11026         check_stats $SINGLEMDS "samedir_rename" 1
11027
11028         rm -rf $DIR/${tdir}
11029 }
11030 run_test 133a "Verifying MDT stats ========================================"
11031
11032 test_133b() {
11033         local res
11034
11035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11036         remote_ost_nodsh && skip "remote OST with nodsh"
11037         remote_mds_nodsh && skip "remote MDS with nodsh"
11038
11039         local testdir=$DIR/${tdir}/stats_testdir
11040
11041         mkdir -p ${testdir} || error "mkdir failed"
11042         touch ${testdir}/${tfile} || error "touch failed"
11043         cancel_lru_locks mdc
11044
11045         # clear stats.
11046         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11047         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11048
11049         # extra mdt stats verification.
11050         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11051         check_stats $SINGLEMDS "setattr" 1
11052         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11053         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11054         then            # LU-1740
11055                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11056                 check_stats $SINGLEMDS "getattr" 1
11057         fi
11058         rm -rf $DIR/${tdir}
11059
11060         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11061         # so the check below is not reliable
11062         [ $MDSCOUNT -eq 1 ] || return 0
11063
11064         # Sleep to avoid a cached response.
11065         #define OBD_STATFS_CACHE_SECONDS 1
11066         sleep 2
11067         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11068         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11069         $LFS df || error "lfs failed"
11070         check_stats $SINGLEMDS "statfs" 1
11071
11072         # check aggregated statfs (LU-10018)
11073         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11074                 return 0
11075         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11076                 return 0
11077         sleep 2
11078         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11079         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11080         df $DIR
11081         check_stats $SINGLEMDS "statfs" 1
11082
11083         # We want to check that the client didn't send OST_STATFS to
11084         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11085         # extra care is needed here.
11086         if remote_mds; then
11087                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11088                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11089
11090                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11091                 [ "$res" ] && error "OST got STATFS"
11092         fi
11093
11094         return 0
11095 }
11096 run_test 133b "Verifying extra MDT stats =================================="
11097
11098 test_133c() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         remote_ost_nodsh && skip "remote OST with nodsh"
11101         remote_mds_nodsh && skip "remote MDS with nodsh"
11102
11103         local testdir=$DIR/$tdir/stats_testdir
11104
11105         test_mkdir -p $testdir
11106
11107         # verify obdfilter stats.
11108         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11109         sync
11110         cancel_lru_locks osc
11111         wait_delete_completed
11112
11113         # clear stats.
11114         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11115         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11116
11117         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11118                 error "dd failed"
11119         sync
11120         cancel_lru_locks osc
11121         check_stats ost1 "write" 1
11122
11123         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11124         check_stats ost1 "read" 1
11125
11126         > $testdir/$tfile || error "truncate failed"
11127         check_stats ost1 "punch" 1
11128
11129         rm -f $testdir/$tfile || error "file remove failed"
11130         wait_delete_completed
11131         check_stats ost1 "destroy" 1
11132
11133         rm -rf $DIR/$tdir
11134 }
11135 run_test 133c "Verifying OST stats ========================================"
11136
11137 order_2() {
11138         local value=$1
11139         local orig=$value
11140         local order=1
11141
11142         while [ $value -ge 2 ]; do
11143                 order=$((order*2))
11144                 value=$((value/2))
11145         done
11146
11147         if [ $orig -gt $order ]; then
11148                 order=$((order*2))
11149         fi
11150         echo $order
11151 }
11152
11153 size_in_KMGT() {
11154     local value=$1
11155     local size=('K' 'M' 'G' 'T');
11156     local i=0
11157     local size_string=$value
11158
11159     while [ $value -ge 1024 ]; do
11160         if [ $i -gt 3 ]; then
11161             #T is the biggest unit we get here, if that is bigger,
11162             #just return XXXT
11163             size_string=${value}T
11164             break
11165         fi
11166         value=$((value >> 10))
11167         if [ $value -lt 1024 ]; then
11168             size_string=${value}${size[$i]}
11169             break
11170         fi
11171         i=$((i + 1))
11172     done
11173
11174     echo $size_string
11175 }
11176
11177 get_rename_size() {
11178         local size=$1
11179         local context=${2:-.}
11180         local sample=$(do_facet $SINGLEMDS $LCTL \
11181                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11182                 grep -A1 $context |
11183                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11184         echo $sample
11185 }
11186
11187 test_133d() {
11188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11189         remote_ost_nodsh && skip "remote OST with nodsh"
11190         remote_mds_nodsh && skip "remote MDS with nodsh"
11191         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11192                 skip_env "MDS doesn't support rename stats"
11193
11194         local testdir1=$DIR/${tdir}/stats_testdir1
11195         local testdir2=$DIR/${tdir}/stats_testdir2
11196         mkdir -p $DIR/${tdir}
11197
11198         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11199
11200         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11201         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11202
11203         createmany -o $testdir1/test 512 || error "createmany failed"
11204
11205         # check samedir rename size
11206         mv ${testdir1}/test0 ${testdir1}/test_0
11207
11208         local testdir1_size=$(ls -l $DIR/${tdir} |
11209                 awk '/stats_testdir1/ {print $5}')
11210         local testdir2_size=$(ls -l $DIR/${tdir} |
11211                 awk '/stats_testdir2/ {print $5}')
11212
11213         testdir1_size=$(order_2 $testdir1_size)
11214         testdir2_size=$(order_2 $testdir2_size)
11215
11216         testdir1_size=$(size_in_KMGT $testdir1_size)
11217         testdir2_size=$(size_in_KMGT $testdir2_size)
11218
11219         echo "source rename dir size: ${testdir1_size}"
11220         echo "target rename dir size: ${testdir2_size}"
11221
11222         local cmd="do_facet $SINGLEMDS $LCTL "
11223         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11224
11225         eval $cmd || error "$cmd failed"
11226         local samedir=$($cmd | grep 'same_dir')
11227         local same_sample=$(get_rename_size $testdir1_size)
11228         [ -z "$samedir" ] && error "samedir_rename_size count error"
11229         [[ $same_sample -eq 1 ]] ||
11230                 error "samedir_rename_size error $same_sample"
11231         echo "Check same dir rename stats success"
11232
11233         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11234
11235         # check crossdir rename size
11236         mv ${testdir1}/test_0 ${testdir2}/test_0
11237
11238         testdir1_size=$(ls -l $DIR/${tdir} |
11239                 awk '/stats_testdir1/ {print $5}')
11240         testdir2_size=$(ls -l $DIR/${tdir} |
11241                 awk '/stats_testdir2/ {print $5}')
11242
11243         testdir1_size=$(order_2 $testdir1_size)
11244         testdir2_size=$(order_2 $testdir2_size)
11245
11246         testdir1_size=$(size_in_KMGT $testdir1_size)
11247         testdir2_size=$(size_in_KMGT $testdir2_size)
11248
11249         echo "source rename dir size: ${testdir1_size}"
11250         echo "target rename dir size: ${testdir2_size}"
11251
11252         eval $cmd || error "$cmd failed"
11253         local crossdir=$($cmd | grep 'crossdir')
11254         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11255         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11256         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11257         [[ $src_sample -eq 1 ]] ||
11258                 error "crossdir_rename_size error $src_sample"
11259         [[ $tgt_sample -eq 1 ]] ||
11260                 error "crossdir_rename_size error $tgt_sample"
11261         echo "Check cross dir rename stats success"
11262         rm -rf $DIR/${tdir}
11263 }
11264 run_test 133d "Verifying rename_stats ========================================"
11265
11266 test_133e() {
11267         remote_mds_nodsh && skip "remote MDS with nodsh"
11268         remote_ost_nodsh && skip "remote OST with nodsh"
11269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11270
11271         local testdir=$DIR/${tdir}/stats_testdir
11272         local ctr f0 f1 bs=32768 count=42 sum
11273
11274         mkdir -p ${testdir} || error "mkdir failed"
11275
11276         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11277
11278         for ctr in {write,read}_bytes; do
11279                 sync
11280                 cancel_lru_locks osc
11281
11282                 do_facet ost1 $LCTL set_param -n \
11283                         "obdfilter.*.exports.clear=clear"
11284
11285                 if [ $ctr = write_bytes ]; then
11286                         f0=/dev/zero
11287                         f1=${testdir}/${tfile}
11288                 else
11289                         f0=${testdir}/${tfile}
11290                         f1=/dev/null
11291                 fi
11292
11293                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11294                         error "dd failed"
11295                 sync
11296                 cancel_lru_locks osc
11297
11298                 sum=$(do_facet ost1 $LCTL get_param \
11299                         "obdfilter.*.exports.*.stats" |
11300                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11301                                 $1 == ctr { sum += $7 }
11302                                 END { printf("%0.0f", sum) }')
11303
11304                 if ((sum != bs * count)); then
11305                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11306                 fi
11307         done
11308
11309         rm -rf $DIR/${tdir}
11310 }
11311 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11312
11313 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11314
11315 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11316 # not honor the -ignore_readdir_race option correctly. So we call
11317 # error_ignore() rather than error() in these cases. See LU-11152.
11318 error_133() {
11319         if (find --version; do_facet mds1 find --version) |
11320                 grep -q '\b4\.5\.1[1-4]\b'; then
11321                 error_ignore LU-11152 "$@"
11322         else
11323                 error "$@"
11324         fi
11325 }
11326
11327 test_133f() {
11328         # First without trusting modes.
11329         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11330         echo "proc_dirs='$proc_dirs'"
11331         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11332         find $proc_dirs -exec cat '{}' \; &> /dev/null
11333
11334         # Second verifying readability.
11335         $LCTL get_param -R '*' &> /dev/null
11336
11337         # Verifing writability with badarea_io.
11338         find $proc_dirs \
11339                 -ignore_readdir_race \
11340                 -type f \
11341                 -not -name force_lbug \
11342                 -not -name changelog_mask \
11343                 -exec badarea_io '{}' \; ||
11344                         error_133 "find $proc_dirs failed"
11345 }
11346 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11347
11348 test_133g() {
11349         remote_mds_nodsh && skip "remote MDS with nodsh"
11350         remote_ost_nodsh && skip "remote OST with nodsh"
11351
11352         # eventually, this can also be replaced with "lctl get_param -R",
11353         # but not until that option is always available on the server
11354         local facet
11355         for facet in mds1 ost1; do
11356                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11357                         skip_noexit "Too old lustre on $facet"
11358                 local facet_proc_dirs=$(do_facet $facet \
11359                                         \\\ls -d $proc_regexp 2>/dev/null)
11360                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11361                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11362                 do_facet $facet find $facet_proc_dirs \
11363                         ! -name req_history \
11364                         -exec cat '{}' \\\; &> /dev/null
11365
11366                 do_facet $facet find $facet_proc_dirs \
11367                         ! -name req_history \
11368                         -type f \
11369                         -exec cat '{}' \\\; &> /dev/null ||
11370                                 error "proc file read failed"
11371
11372                 do_facet $facet find $facet_proc_dirs \
11373                         -ignore_readdir_race \
11374                         -type f \
11375                         -not -name force_lbug \
11376                         -not -name changelog_mask \
11377                         -exec badarea_io '{}' \\\; ||
11378                                 error_133 "$facet find $facet_proc_dirs failed"
11379         done
11380
11381         # remount the FS in case writes/reads /proc break the FS
11382         cleanup || error "failed to unmount"
11383         setup || error "failed to setup"
11384         true
11385 }
11386 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11387
11388 test_133h() {
11389         remote_mds_nodsh && skip "remote MDS with nodsh"
11390         remote_ost_nodsh && skip "remote OST with nodsh"
11391         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11392                 skip "Need MDS version at least 2.9.54"
11393
11394         local facet
11395
11396         for facet in client mds1 ost1; do
11397                 local facet_proc_dirs=$(do_facet $facet \
11398                                         \\\ls -d $proc_regexp 2> /dev/null)
11399                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11400                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11401                 # Get the list of files that are missing the terminating newline
11402                 local missing=($(do_facet $facet \
11403                         find ${facet_proc_dirs} -type f \|              \
11404                                 while read F\; do                       \
11405                                         awk -v FS='\v' -v RS='\v\v'     \
11406                                         "'END { if(NR>0 &&              \
11407                                         \\\$NF !~ /.*\\\n\$/)           \
11408                                                 print FILENAME}'"       \
11409                                         '\$F'\;                         \
11410                                 done 2>/dev/null))
11411                 [ ${#missing[*]} -eq 0 ] ||
11412                         error "files do not end with newline: ${missing[*]}"
11413         done
11414 }
11415 run_test 133h "Proc files should end with newlines"
11416
11417 test_134a() {
11418         remote_mds_nodsh && skip "remote MDS with nodsh"
11419         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11420                 skip "Need MDS version at least 2.7.54"
11421
11422         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11423         cancel_lru_locks mdc
11424
11425         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11426         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11427         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11428
11429         local nr=1000
11430         createmany -o $DIR/$tdir/f $nr ||
11431                 error "failed to create $nr files in $DIR/$tdir"
11432         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11433
11434         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11435         do_facet mds1 $LCTL set_param fail_loc=0x327
11436         do_facet mds1 $LCTL set_param fail_val=500
11437         touch $DIR/$tdir/m
11438
11439         echo "sleep 10 seconds ..."
11440         sleep 10
11441         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11442
11443         do_facet mds1 $LCTL set_param fail_loc=0
11444         do_facet mds1 $LCTL set_param fail_val=0
11445         [ $lck_cnt -lt $unused ] ||
11446                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11447
11448         rm $DIR/$tdir/m
11449         unlinkmany $DIR/$tdir/f $nr
11450 }
11451 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11452
11453 test_134b() {
11454         remote_mds_nodsh && skip "remote MDS with nodsh"
11455         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11456                 skip "Need MDS version at least 2.7.54"
11457
11458         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11459         cancel_lru_locks mdc
11460
11461         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11462                         ldlm.lock_reclaim_threshold_mb)
11463         # disable reclaim temporarily
11464         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11465
11466         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11467         do_facet mds1 $LCTL set_param fail_loc=0x328
11468         do_facet mds1 $LCTL set_param fail_val=500
11469
11470         $LCTL set_param debug=+trace
11471
11472         local nr=600
11473         createmany -o $DIR/$tdir/f $nr &
11474         local create_pid=$!
11475
11476         echo "Sleep $TIMEOUT seconds ..."
11477         sleep $TIMEOUT
11478         if ! ps -p $create_pid  > /dev/null 2>&1; then
11479                 do_facet mds1 $LCTL set_param fail_loc=0
11480                 do_facet mds1 $LCTL set_param fail_val=0
11481                 do_facet mds1 $LCTL set_param \
11482                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11483                 error "createmany finished incorrectly!"
11484         fi
11485         do_facet mds1 $LCTL set_param fail_loc=0
11486         do_facet mds1 $LCTL set_param fail_val=0
11487         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11488         wait $create_pid || return 1
11489
11490         unlinkmany $DIR/$tdir/f $nr
11491 }
11492 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11493
11494 test_140() { #bug-17379
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496
11497         test_mkdir $DIR/$tdir
11498         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11499         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11500
11501         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11502         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11503         local i=0
11504         while i=$((i + 1)); do
11505                 test_mkdir $i
11506                 cd $i || error "Changing to $i"
11507                 ln -s ../stat stat || error "Creating stat symlink"
11508                 # Read the symlink until ELOOP present,
11509                 # not LBUGing the system is considered success,
11510                 # we didn't overrun the stack.
11511                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11512                 if [ $ret -ne 0 ]; then
11513                         if [ $ret -eq 40 ]; then
11514                                 break  # -ELOOP
11515                         else
11516                                 error "Open stat symlink"
11517                                         return
11518                         fi
11519                 fi
11520         done
11521         i=$((i - 1))
11522         echo "The symlink depth = $i"
11523         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11524                 error "Invalid symlink depth"
11525
11526         # Test recursive symlink
11527         ln -s symlink_self symlink_self
11528         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11529         echo "open symlink_self returns $ret"
11530         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11531 }
11532 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11533
11534 test_150() {
11535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11536
11537         local TF="$TMP/$tfile"
11538
11539         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11540         cp $TF $DIR/$tfile
11541         cancel_lru_locks $OSC
11542         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11543         remount_client $MOUNT
11544         df -P $MOUNT
11545         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11546
11547         $TRUNCATE $TF 6000
11548         $TRUNCATE $DIR/$tfile 6000
11549         cancel_lru_locks $OSC
11550         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11551
11552         echo "12345" >>$TF
11553         echo "12345" >>$DIR/$tfile
11554         cancel_lru_locks $OSC
11555         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11556
11557         echo "12345" >>$TF
11558         echo "12345" >>$DIR/$tfile
11559         cancel_lru_locks $OSC
11560         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11561
11562         rm -f $TF
11563         true
11564 }
11565 run_test 150 "truncate/append tests"
11566
11567 #LU-2902 roc_hit was not able to read all values from lproc
11568 function roc_hit_init() {
11569         local list=$(comma_list $(osts_nodes))
11570         local dir=$DIR/$tdir-check
11571         local file=$dir/$tfile
11572         local BEFORE
11573         local AFTER
11574         local idx
11575
11576         test_mkdir $dir
11577         #use setstripe to do a write to every ost
11578         for i in $(seq 0 $((OSTCOUNT-1))); do
11579                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11580                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11581                 idx=$(printf %04x $i)
11582                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11583                         awk '$1 == "cache_access" {sum += $7}
11584                                 END { printf("%0.0f", sum) }')
11585
11586                 cancel_lru_locks osc
11587                 cat $file >/dev/null
11588
11589                 AFTER=$(get_osd_param $list *OST*$idx stats |
11590                         awk '$1 == "cache_access" {sum += $7}
11591                                 END { printf("%0.0f", sum) }')
11592
11593                 echo BEFORE:$BEFORE AFTER:$AFTER
11594                 if ! let "AFTER - BEFORE == 4"; then
11595                         rm -rf $dir
11596                         error "roc_hit is not safe to use"
11597                 fi
11598                 rm $file
11599         done
11600
11601         rm -rf $dir
11602 }
11603
11604 function roc_hit() {
11605         local list=$(comma_list $(osts_nodes))
11606         echo $(get_osd_param $list '' stats |
11607                 awk '$1 == "cache_hit" {sum += $7}
11608                         END { printf("%0.0f", sum) }')
11609 }
11610
11611 function set_cache() {
11612         local on=1
11613
11614         if [ "$2" == "off" ]; then
11615                 on=0;
11616         fi
11617         local list=$(comma_list $(osts_nodes))
11618         set_osd_param $list '' $1_cache_enable $on
11619
11620         cancel_lru_locks osc
11621 }
11622
11623 test_151() {
11624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11625         remote_ost_nodsh && skip "remote OST with nodsh"
11626
11627         local CPAGES=3
11628         local list=$(comma_list $(osts_nodes))
11629
11630         # check whether obdfilter is cache capable at all
11631         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11632                 skip "not cache-capable obdfilter"
11633         fi
11634
11635         # check cache is enabled on all obdfilters
11636         if get_osd_param $list '' read_cache_enable | grep 0; then
11637                 skip "oss cache is disabled"
11638         fi
11639
11640         set_osd_param $list '' writethrough_cache_enable 1
11641
11642         # check write cache is enabled on all obdfilters
11643         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11644                 skip "oss write cache is NOT enabled"
11645         fi
11646
11647         roc_hit_init
11648
11649         #define OBD_FAIL_OBD_NO_LRU  0x609
11650         do_nodes $list $LCTL set_param fail_loc=0x609
11651
11652         # pages should be in the case right after write
11653         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11654                 error "dd failed"
11655
11656         local BEFORE=$(roc_hit)
11657         cancel_lru_locks osc
11658         cat $DIR/$tfile >/dev/null
11659         local AFTER=$(roc_hit)
11660
11661         do_nodes $list $LCTL set_param fail_loc=0
11662
11663         if ! let "AFTER - BEFORE == CPAGES"; then
11664                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11665         fi
11666
11667         # the following read invalidates the cache
11668         cancel_lru_locks osc
11669         set_osd_param $list '' read_cache_enable 0
11670         cat $DIR/$tfile >/dev/null
11671
11672         # now data shouldn't be found in the cache
11673         BEFORE=$(roc_hit)
11674         cancel_lru_locks osc
11675         cat $DIR/$tfile >/dev/null
11676         AFTER=$(roc_hit)
11677         if let "AFTER - BEFORE != 0"; then
11678                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11679         fi
11680
11681         set_osd_param $list '' read_cache_enable 1
11682         rm -f $DIR/$tfile
11683 }
11684 run_test 151 "test cache on oss and controls ==============================="
11685
11686 test_152() {
11687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11688
11689         local TF="$TMP/$tfile"
11690
11691         # simulate ENOMEM during write
11692 #define OBD_FAIL_OST_NOMEM      0x226
11693         lctl set_param fail_loc=0x80000226
11694         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11695         cp $TF $DIR/$tfile
11696         sync || error "sync failed"
11697         lctl set_param fail_loc=0
11698
11699         # discard client's cache
11700         cancel_lru_locks osc
11701
11702         # simulate ENOMEM during read
11703         lctl set_param fail_loc=0x80000226
11704         cmp $TF $DIR/$tfile || error "cmp failed"
11705         lctl set_param fail_loc=0
11706
11707         rm -f $TF
11708 }
11709 run_test 152 "test read/write with enomem ============================"
11710
11711 test_153() {
11712         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11713 }
11714 run_test 153 "test if fdatasync does not crash ======================="
11715
11716 dot_lustre_fid_permission_check() {
11717         local fid=$1
11718         local ffid=$MOUNT/.lustre/fid/$fid
11719         local test_dir=$2
11720
11721         echo "stat fid $fid"
11722         stat $ffid > /dev/null || error "stat $ffid failed."
11723         echo "touch fid $fid"
11724         touch $ffid || error "touch $ffid failed."
11725         echo "write to fid $fid"
11726         cat /etc/hosts > $ffid || error "write $ffid failed."
11727         echo "read fid $fid"
11728         diff /etc/hosts $ffid || error "read $ffid failed."
11729         echo "append write to fid $fid"
11730         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11731         echo "rename fid $fid"
11732         mv $ffid $test_dir/$tfile.1 &&
11733                 error "rename $ffid to $tfile.1 should fail."
11734         touch $test_dir/$tfile.1
11735         mv $test_dir/$tfile.1 $ffid &&
11736                 error "rename $tfile.1 to $ffid should fail."
11737         rm -f $test_dir/$tfile.1
11738         echo "truncate fid $fid"
11739         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11740         echo "link fid $fid"
11741         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11742         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11743                 echo "setfacl fid $fid"
11744                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11745                 echo "getfacl fid $fid"
11746                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11747         fi
11748         echo "unlink fid $fid"
11749         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11750         echo "mknod fid $fid"
11751         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11752
11753         fid=[0xf00000400:0x1:0x0]
11754         ffid=$MOUNT/.lustre/fid/$fid
11755
11756         echo "stat non-exist fid $fid"
11757         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11758         echo "write to non-exist fid $fid"
11759         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11760         echo "link new fid $fid"
11761         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11762
11763         mkdir -p $test_dir/$tdir
11764         touch $test_dir/$tdir/$tfile
11765         fid=$($LFS path2fid $test_dir/$tdir)
11766         rc=$?
11767         [ $rc -ne 0 ] &&
11768                 error "error: could not get fid for $test_dir/$dir/$tfile."
11769
11770         ffid=$MOUNT/.lustre/fid/$fid
11771
11772         echo "ls $fid"
11773         ls $ffid > /dev/null || error "ls $ffid failed."
11774         echo "touch $fid/$tfile.1"
11775         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11776
11777         echo "touch $MOUNT/.lustre/fid/$tfile"
11778         touch $MOUNT/.lustre/fid/$tfile && \
11779                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11780
11781         echo "setxattr to $MOUNT/.lustre/fid"
11782         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11783
11784         echo "listxattr for $MOUNT/.lustre/fid"
11785         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11786
11787         echo "delxattr from $MOUNT/.lustre/fid"
11788         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11789
11790         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11791         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11792                 error "touch invalid fid should fail."
11793
11794         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11795         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11796                 error "touch non-normal fid should fail."
11797
11798         echo "rename $tdir to $MOUNT/.lustre/fid"
11799         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11800                 error "rename to $MOUNT/.lustre/fid should fail."
11801
11802         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11803         then            # LU-3547
11804                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11805                 local new_obf_mode=777
11806
11807                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11808                 chmod $new_obf_mode $DIR/.lustre/fid ||
11809                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11810
11811                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11812                 [ $obf_mode -eq $new_obf_mode ] ||
11813                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11814
11815                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11816                 chmod $old_obf_mode $DIR/.lustre/fid ||
11817                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11818         fi
11819
11820         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11821         fid=$($LFS path2fid $test_dir/$tfile-2)
11822
11823         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11824         then # LU-5424
11825                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11826                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11827                         error "create lov data thru .lustre failed"
11828         fi
11829         echo "cp /etc/passwd $test_dir/$tfile-2"
11830         cp /etc/passwd $test_dir/$tfile-2 ||
11831                 error "copy to $test_dir/$tfile-2 failed."
11832         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11833         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11834                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11835
11836         rm -rf $test_dir/tfile.lnk
11837         rm -rf $test_dir/$tfile-2
11838 }
11839
11840 test_154A() {
11841         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11842                 skip "Need MDS version at least 2.4.1"
11843
11844         local tf=$DIR/$tfile
11845         touch $tf
11846
11847         local fid=$($LFS path2fid $tf)
11848         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11849
11850         # check that we get the same pathname back
11851         local found=$($LFS fid2path $MOUNT "$fid")
11852         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11853         [ "$found" == "$tf" ] ||
11854                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11855 }
11856 run_test 154A "lfs path2fid and fid2path basic checks"
11857
11858 test_154B() {
11859         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11860                 skip "Need MDS version at least 2.4.1"
11861
11862         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11863         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11864         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11865         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11866
11867         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11868         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11869
11870         # check that we get the same pathname
11871         echo "PFID: $PFID, name: $name"
11872         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11873         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11874         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11875                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11876
11877         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11878 }
11879 run_test 154B "verify the ll_decode_linkea tool"
11880
11881 test_154a() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11884         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11885                 skip "Need MDS version at least 2.2.51"
11886         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11887
11888         cp /etc/hosts $DIR/$tfile
11889
11890         fid=$($LFS path2fid $DIR/$tfile)
11891         rc=$?
11892         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11893
11894         dot_lustre_fid_permission_check "$fid" $DIR ||
11895                 error "dot lustre permission check $fid failed"
11896
11897         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11898
11899         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11900
11901         touch $MOUNT/.lustre/file &&
11902                 error "creation is not allowed under .lustre"
11903
11904         mkdir $MOUNT/.lustre/dir &&
11905                 error "mkdir is not allowed under .lustre"
11906
11907         rm -rf $DIR/$tfile
11908 }
11909 run_test 154a "Open-by-FID"
11910
11911 test_154b() {
11912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11913         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11915         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11916                 skip "Need MDS version at least 2.2.51"
11917
11918         local remote_dir=$DIR/$tdir/remote_dir
11919         local MDTIDX=1
11920         local rc=0
11921
11922         mkdir -p $DIR/$tdir
11923         $LFS mkdir -i $MDTIDX $remote_dir ||
11924                 error "create remote directory failed"
11925
11926         cp /etc/hosts $remote_dir/$tfile
11927
11928         fid=$($LFS path2fid $remote_dir/$tfile)
11929         rc=$?
11930         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11931
11932         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11933                 error "dot lustre permission check $fid failed"
11934         rm -rf $DIR/$tdir
11935 }
11936 run_test 154b "Open-by-FID for remote directory"
11937
11938 test_154c() {
11939         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11940                 skip "Need MDS version at least 2.4.1"
11941
11942         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11943         local FID1=$($LFS path2fid $DIR/$tfile.1)
11944         local FID2=$($LFS path2fid $DIR/$tfile.2)
11945         local FID3=$($LFS path2fid $DIR/$tfile.3)
11946
11947         local N=1
11948         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11949                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11950                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11951                 local want=FID$N
11952                 [ "$FID" = "${!want}" ] ||
11953                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11954                 N=$((N + 1))
11955         done
11956
11957         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11958         do
11959                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11960                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11961                 N=$((N + 1))
11962         done
11963 }
11964 run_test 154c "lfs path2fid and fid2path multiple arguments"
11965
11966 test_154d() {
11967         remote_mds_nodsh && skip "remote MDS with nodsh"
11968         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11969                 skip "Need MDS version at least 2.5.53"
11970
11971         if remote_mds; then
11972                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11973         else
11974                 nid="0@lo"
11975         fi
11976         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11977         local fd
11978         local cmd
11979
11980         rm -f $DIR/$tfile
11981         touch $DIR/$tfile
11982
11983         local fid=$($LFS path2fid $DIR/$tfile)
11984         # Open the file
11985         fd=$(free_fd)
11986         cmd="exec $fd<$DIR/$tfile"
11987         eval $cmd
11988         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11989         echo "$fid_list" | grep "$fid"
11990         rc=$?
11991
11992         cmd="exec $fd>/dev/null"
11993         eval $cmd
11994         if [ $rc -ne 0 ]; then
11995                 error "FID $fid not found in open files list $fid_list"
11996         fi
11997 }
11998 run_test 154d "Verify open file fid"
11999
12000 test_154e()
12001 {
12002         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12003                 skip "Need MDS version at least 2.6.50"
12004
12005         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12006                 error ".lustre returned by readdir"
12007         fi
12008 }
12009 run_test 154e ".lustre is not returned by readdir"
12010
12011 test_154f() {
12012         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12013
12014         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12015         test_mkdir -p -c1 $DIR/$tdir/d
12016         # test dirs inherit from its stripe
12017         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12018         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12019         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12020         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12021         touch $DIR/f
12022
12023         # get fid of parents
12024         local FID0=$($LFS path2fid $DIR/$tdir/d)
12025         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12026         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12027         local FID3=$($LFS path2fid $DIR)
12028
12029         # check that path2fid --parents returns expected <parent_fid>/name
12030         # 1) test for a directory (single parent)
12031         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12032         [ "$parent" == "$FID0/foo1" ] ||
12033                 error "expected parent: $FID0/foo1, got: $parent"
12034
12035         # 2) test for a file with nlink > 1 (multiple parents)
12036         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12037         echo "$parent" | grep -F "$FID1/$tfile" ||
12038                 error "$FID1/$tfile not returned in parent list"
12039         echo "$parent" | grep -F "$FID2/link" ||
12040                 error "$FID2/link not returned in parent list"
12041
12042         # 3) get parent by fid
12043         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12044         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12045         echo "$parent" | grep -F "$FID1/$tfile" ||
12046                 error "$FID1/$tfile not returned in parent list (by fid)"
12047         echo "$parent" | grep -F "$FID2/link" ||
12048                 error "$FID2/link not returned in parent list (by fid)"
12049
12050         # 4) test for entry in root directory
12051         parent=$($LFS path2fid --parents $DIR/f)
12052         echo "$parent" | grep -F "$FID3/f" ||
12053                 error "$FID3/f not returned in parent list"
12054
12055         # 5) test it on root directory
12056         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12057                 error "$MOUNT should not have parents"
12058
12059         # enable xattr caching and check that linkea is correctly updated
12060         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12061         save_lustre_params client "llite.*.xattr_cache" > $save
12062         lctl set_param llite.*.xattr_cache 1
12063
12064         # 6.1) linkea update on rename
12065         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12066
12067         # get parents by fid
12068         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12069         # foo1 should no longer be returned in parent list
12070         echo "$parent" | grep -F "$FID1" &&
12071                 error "$FID1 should no longer be in parent list"
12072         # the new path should appear
12073         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12074                 error "$FID2/$tfile.moved is not in parent list"
12075
12076         # 6.2) linkea update on unlink
12077         rm -f $DIR/$tdir/d/foo2/link
12078         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12079         # foo2/link should no longer be returned in parent list
12080         echo "$parent" | grep -F "$FID2/link" &&
12081                 error "$FID2/link should no longer be in parent list"
12082         true
12083
12084         rm -f $DIR/f
12085         restore_lustre_params < $save
12086         rm -f $save
12087 }
12088 run_test 154f "get parent fids by reading link ea"
12089
12090 test_154g()
12091 {
12092         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12093         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12094            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12095                 skip "Need MDS version at least 2.6.92"
12096
12097         mkdir -p $DIR/$tdir
12098         llapi_fid_test -d $DIR/$tdir
12099 }
12100 run_test 154g "various llapi FID tests"
12101
12102 test_155_small_load() {
12103     local temp=$TMP/$tfile
12104     local file=$DIR/$tfile
12105
12106     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12107         error "dd of=$temp bs=6096 count=1 failed"
12108     cp $temp $file
12109     cancel_lru_locks $OSC
12110     cmp $temp $file || error "$temp $file differ"
12111
12112     $TRUNCATE $temp 6000
12113     $TRUNCATE $file 6000
12114     cmp $temp $file || error "$temp $file differ (truncate1)"
12115
12116     echo "12345" >>$temp
12117     echo "12345" >>$file
12118     cmp $temp $file || error "$temp $file differ (append1)"
12119
12120     echo "12345" >>$temp
12121     echo "12345" >>$file
12122     cmp $temp $file || error "$temp $file differ (append2)"
12123
12124     rm -f $temp $file
12125     true
12126 }
12127
12128 test_155_big_load() {
12129         remote_ost_nodsh && skip "remote OST with nodsh"
12130
12131         local temp=$TMP/$tfile
12132         local file=$DIR/$tfile
12133
12134         free_min_max
12135         local cache_size=$(do_facet ost$((MAXI+1)) \
12136                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12137         local large_file_size=$((cache_size * 2))
12138
12139         echo "OSS cache size: $cache_size KB"
12140         echo "Large file size: $large_file_size KB"
12141
12142         [ $MAXV -le $large_file_size ] &&
12143                 skip_env "max available OST size needs > $large_file_size KB"
12144
12145         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12146
12147         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12148                 error "dd of=$temp bs=$large_file_size count=1k failed"
12149         cp $temp $file
12150         ls -lh $temp $file
12151         cancel_lru_locks osc
12152         cmp $temp $file || error "$temp $file differ"
12153
12154         rm -f $temp $file
12155         true
12156 }
12157
12158 save_writethrough() {
12159         local facets=$(get_facets OST)
12160
12161         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12162 }
12163
12164 test_155a() {
12165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12166
12167         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12168
12169         save_writethrough $p
12170
12171         set_cache read on
12172         set_cache writethrough on
12173         test_155_small_load
12174         restore_lustre_params < $p
12175         rm -f $p
12176 }
12177 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12178
12179 test_155b() {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181
12182         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12183
12184         save_writethrough $p
12185
12186         set_cache read on
12187         set_cache writethrough off
12188         test_155_small_load
12189         restore_lustre_params < $p
12190         rm -f $p
12191 }
12192 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12193
12194 test_155c() {
12195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12196
12197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12198
12199         save_writethrough $p
12200
12201         set_cache read off
12202         set_cache writethrough on
12203         test_155_small_load
12204         restore_lustre_params < $p
12205         rm -f $p
12206 }
12207 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12208
12209 test_155d() {
12210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12211
12212         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12213
12214         save_writethrough $p
12215
12216         set_cache read off
12217         set_cache writethrough off
12218         test_155_small_load
12219         restore_lustre_params < $p
12220         rm -f $p
12221 }
12222 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12223
12224 test_155e() {
12225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12226
12227         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12228
12229         save_writethrough $p
12230
12231         set_cache read on
12232         set_cache writethrough on
12233         test_155_big_load
12234         restore_lustre_params < $p
12235         rm -f $p
12236 }
12237 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12238
12239 test_155f() {
12240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12241
12242         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12243
12244         save_writethrough $p
12245
12246         set_cache read on
12247         set_cache writethrough off
12248         test_155_big_load
12249         restore_lustre_params < $p
12250         rm -f $p
12251 }
12252 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12253
12254 test_155g() {
12255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12256
12257         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12258
12259         save_writethrough $p
12260
12261         set_cache read off
12262         set_cache writethrough on
12263         test_155_big_load
12264         restore_lustre_params < $p
12265         rm -f $p
12266 }
12267 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12268
12269 test_155h() {
12270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12271
12272         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12273
12274         save_writethrough $p
12275
12276         set_cache read off
12277         set_cache writethrough off
12278         test_155_big_load
12279         restore_lustre_params < $p
12280         rm -f $p
12281 }
12282 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12283
12284 test_156() {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286         remote_ost_nodsh && skip "remote OST with nodsh"
12287         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12288                 skip "stats not implemented on old servers"
12289         [ "$ost1_FSTYPE" = "zfs" ] &&
12290                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12291
12292         local CPAGES=3
12293         local BEFORE
12294         local AFTER
12295         local file="$DIR/$tfile"
12296         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12297
12298         save_writethrough $p
12299         roc_hit_init
12300
12301         log "Turn on read and write cache"
12302         set_cache read on
12303         set_cache writethrough on
12304
12305         log "Write data and read it back."
12306         log "Read should be satisfied from the cache."
12307         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12308         BEFORE=$(roc_hit)
12309         cancel_lru_locks osc
12310         cat $file >/dev/null
12311         AFTER=$(roc_hit)
12312         if ! let "AFTER - BEFORE == CPAGES"; then
12313                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12314         else
12315                 log "cache hits:: before: $BEFORE, after: $AFTER"
12316         fi
12317
12318         log "Read again; it should be satisfied from the cache."
12319         BEFORE=$AFTER
12320         cancel_lru_locks osc
12321         cat $file >/dev/null
12322         AFTER=$(roc_hit)
12323         if ! let "AFTER - BEFORE == CPAGES"; then
12324                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12325         else
12326                 log "cache hits:: before: $BEFORE, after: $AFTER"
12327         fi
12328
12329         log "Turn off the read cache and turn on the write cache"
12330         set_cache read off
12331         set_cache writethrough on
12332
12333         log "Read again; it should be satisfied from the cache."
12334         BEFORE=$(roc_hit)
12335         cancel_lru_locks osc
12336         cat $file >/dev/null
12337         AFTER=$(roc_hit)
12338         if ! let "AFTER - BEFORE == CPAGES"; then
12339                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12340         else
12341                 log "cache hits:: before: $BEFORE, after: $AFTER"
12342         fi
12343
12344         log "Read again; it should not be satisfied from the cache."
12345         BEFORE=$AFTER
12346         cancel_lru_locks osc
12347         cat $file >/dev/null
12348         AFTER=$(roc_hit)
12349         if ! let "AFTER - BEFORE == 0"; then
12350                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12351         else
12352                 log "cache hits:: before: $BEFORE, after: $AFTER"
12353         fi
12354
12355         log "Write data and read it back."
12356         log "Read should be satisfied from the cache."
12357         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12358         BEFORE=$(roc_hit)
12359         cancel_lru_locks osc
12360         cat $file >/dev/null
12361         AFTER=$(roc_hit)
12362         if ! let "AFTER - BEFORE == CPAGES"; then
12363                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12364         else
12365                 log "cache hits:: before: $BEFORE, after: $AFTER"
12366         fi
12367
12368         log "Read again; it should not be satisfied from the cache."
12369         BEFORE=$AFTER
12370         cancel_lru_locks osc
12371         cat $file >/dev/null
12372         AFTER=$(roc_hit)
12373         if ! let "AFTER - BEFORE == 0"; then
12374                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12375         else
12376                 log "cache hits:: before: $BEFORE, after: $AFTER"
12377         fi
12378
12379         log "Turn off read and write cache"
12380         set_cache read off
12381         set_cache writethrough off
12382
12383         log "Write data and read it back"
12384         log "It should not be satisfied from the cache."
12385         rm -f $file
12386         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12387         cancel_lru_locks osc
12388         BEFORE=$(roc_hit)
12389         cat $file >/dev/null
12390         AFTER=$(roc_hit)
12391         if ! let "AFTER - BEFORE == 0"; then
12392                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12393         else
12394                 log "cache hits:: before: $BEFORE, after: $AFTER"
12395         fi
12396
12397         log "Turn on the read cache and turn off the write cache"
12398         set_cache read on
12399         set_cache writethrough off
12400
12401         log "Write data and read it back"
12402         log "It should not be satisfied from the cache."
12403         rm -f $file
12404         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12405         BEFORE=$(roc_hit)
12406         cancel_lru_locks osc
12407         cat $file >/dev/null
12408         AFTER=$(roc_hit)
12409         if ! let "AFTER - BEFORE == 0"; then
12410                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12411         else
12412                 log "cache hits:: before: $BEFORE, after: $AFTER"
12413         fi
12414
12415         log "Read again; it should be satisfied from the cache."
12416         BEFORE=$(roc_hit)
12417         cancel_lru_locks osc
12418         cat $file >/dev/null
12419         AFTER=$(roc_hit)
12420         if ! let "AFTER - BEFORE == CPAGES"; then
12421                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12422         else
12423                 log "cache hits:: before: $BEFORE, after: $AFTER"
12424         fi
12425
12426         restore_lustre_params < $p
12427         rm -f $p $file
12428 }
12429 run_test 156 "Verification of tunables"
12430
12431 test_160a() {
12432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12433         remote_mds_nodsh && skip "remote MDS with nodsh"
12434         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12435                 skip "Need MDS version at least 2.2.0"
12436
12437         changelog_register || error "changelog_register failed"
12438         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12439         changelog_users $SINGLEMDS | grep -q $cl_user ||
12440                 error "User $cl_user not found in changelog_users"
12441
12442         # change something
12443         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12444         changelog_clear 0 || error "changelog_clear failed"
12445         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12446         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12447         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12448         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12449         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12450         rm $DIR/$tdir/pics/desktop.jpg
12451
12452         changelog_dump | tail -10
12453
12454         echo "verifying changelog mask"
12455         changelog_chmask "-MKDIR"
12456         changelog_chmask "-CLOSE"
12457
12458         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12459         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12460
12461         changelog_chmask "+MKDIR"
12462         changelog_chmask "+CLOSE"
12463
12464         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12465         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12466
12467         changelog_dump | tail -10
12468         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12469         CLOSES=$(changelog_dump | grep -c "CLOSE")
12470         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12471         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12472
12473         # verify contents
12474         echo "verifying target fid"
12475         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12476         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12477         [ "$fidc" == "$fidf" ] ||
12478                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12479         echo "verifying parent fid"
12480         # The FID returned from the Changelog may be the directory shard on
12481         # a different MDT, and not the FID returned by path2fid on the parent.
12482         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12483         # since this is what will matter when recreating this file in the tree.
12484         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12485         local pathp=$($LFS fid2path $MOUNT "$fidp")
12486         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12487                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12488
12489         echo "getting records for $cl_user"
12490         changelog_users $SINGLEMDS
12491         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12492         local nclr=3
12493         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12494                 error "changelog_clear failed"
12495         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12496         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12497         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12498                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12499
12500         local min0_rec=$(changelog_users $SINGLEMDS |
12501                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12502         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12503                           awk '{ print $1; exit; }')
12504
12505         changelog_dump | tail -n 5
12506         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12507         [ $first_rec == $((min0_rec + 1)) ] ||
12508                 error "first index should be $min0_rec + 1 not $first_rec"
12509
12510         # LU-3446 changelog index reset on MDT restart
12511         local cur_rec1=$(changelog_users $SINGLEMDS |
12512                          awk '/^current.index:/ { print $NF }')
12513         changelog_clear 0 ||
12514                 error "clear all changelog records for $cl_user failed"
12515         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12516         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12517                 error "Fail to start $SINGLEMDS"
12518         local cur_rec2=$(changelog_users $SINGLEMDS |
12519                          awk '/^current.index:/ { print $NF }')
12520         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12521         [ $cur_rec1 == $cur_rec2 ] ||
12522                 error "current index should be $cur_rec1 not $cur_rec2"
12523
12524         echo "verifying users from this test are deregistered"
12525         changelog_deregister || error "changelog_deregister failed"
12526         changelog_users $SINGLEMDS | grep -q $cl_user &&
12527                 error "User '$cl_user' still in changelog_users"
12528
12529         # lctl get_param -n mdd.*.changelog_users
12530         # current index: 144
12531         # ID    index (idle seconds)
12532         # cl3   144 (2)
12533         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12534                 # this is the normal case where all users were deregistered
12535                 # make sure no new records are added when no users are present
12536                 local last_rec1=$(changelog_users $SINGLEMDS |
12537                                   awk '/^current.index:/ { print $NF }')
12538                 touch $DIR/$tdir/chloe
12539                 local last_rec2=$(changelog_users $SINGLEMDS |
12540                                   awk '/^current.index:/ { print $NF }')
12541                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12542                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12543         else
12544                 # any changelog users must be leftovers from a previous test
12545                 changelog_users $SINGLEMDS
12546                 echo "other changelog users; can't verify off"
12547         fi
12548 }
12549 run_test 160a "changelog sanity"
12550
12551 test_160b() { # LU-3587
12552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12553         remote_mds_nodsh && skip "remote MDS with nodsh"
12554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12555                 skip "Need MDS version at least 2.2.0"
12556
12557         changelog_register || error "changelog_register failed"
12558         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12559         changelog_users $SINGLEMDS | grep -q $cl_user ||
12560                 error "User '$cl_user' not found in changelog_users"
12561
12562         local longname1=$(str_repeat a 255)
12563         local longname2=$(str_repeat b 255)
12564
12565         cd $DIR
12566         echo "creating very long named file"
12567         touch $longname1 || error "create of '$longname1' failed"
12568         echo "renaming very long named file"
12569         mv $longname1 $longname2
12570
12571         changelog_dump | grep RENME | tail -n 5
12572         rm -f $longname2
12573 }
12574 run_test 160b "Verify that very long rename doesn't crash in changelog"
12575
12576 test_160c() {
12577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12578         remote_mds_nodsh && skip "remote MDS with nodsh"
12579
12580         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12581                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12582                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12583                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12584
12585         local rc=0
12586
12587         # Registration step
12588         changelog_register || error "changelog_register failed"
12589
12590         rm -rf $DIR/$tdir
12591         mkdir -p $DIR/$tdir
12592         $MCREATE $DIR/$tdir/foo_160c
12593         changelog_chmask "-TRUNC"
12594         $TRUNCATE $DIR/$tdir/foo_160c 200
12595         changelog_chmask "+TRUNC"
12596         $TRUNCATE $DIR/$tdir/foo_160c 199
12597         changelog_dump | tail -n 5
12598         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12599         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12600 }
12601 run_test 160c "verify that changelog log catch the truncate event"
12602
12603 test_160d() {
12604         remote_mds_nodsh && skip "remote MDS with nodsh"
12605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12607         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12608                 skip "Need MDS version at least 2.7.60"
12609
12610         # Registration step
12611         changelog_register || error "changelog_register failed"
12612
12613         mkdir -p $DIR/$tdir/migrate_dir
12614         changelog_clear 0 || error "changelog_clear failed"
12615
12616         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12617         changelog_dump | tail -n 5
12618         local migrates=$(changelog_dump | grep -c "MIGRT")
12619         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12620 }
12621 run_test 160d "verify that changelog log catch the migrate event"
12622
12623 test_160e() {
12624         remote_mds_nodsh && skip "remote MDS with nodsh"
12625
12626         # Create a user
12627         changelog_register || error "changelog_register failed"
12628
12629         # Delete a future user (expect fail)
12630         local MDT0=$(facet_svc $SINGLEMDS)
12631         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12632         local rc=$?
12633
12634         if [ $rc -eq 0 ]; then
12635                 error "Deleted non-existant user cl77"
12636         elif [ $rc -ne 2 ]; then
12637                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12638         fi
12639
12640         # Clear to a bad index (1 billion should be safe)
12641         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12642         rc=$?
12643
12644         if [ $rc -eq 0 ]; then
12645                 error "Successfully cleared to invalid CL index"
12646         elif [ $rc -ne 22 ]; then
12647                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12648         fi
12649 }
12650 run_test 160e "changelog negative testing (should return errors)"
12651
12652 test_160f() {
12653         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12654         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12655                 skip "Need MDS version at least 2.10.56"
12656
12657         local mdts=$(comma_list $(mdts_nodes))
12658
12659         # Create a user
12660         changelog_register || error "first changelog_register failed"
12661         changelog_register || error "second changelog_register failed"
12662         local cl_users
12663         declare -A cl_user1
12664         declare -A cl_user2
12665         local user_rec1
12666         local user_rec2
12667         local i
12668
12669         # generate some changelog records to accumulate on each MDT
12670         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12671         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12672                 error "create $DIR/$tdir/$tfile failed"
12673
12674         # check changelogs have been generated
12675         local nbcl=$(changelog_dump | wc -l)
12676         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12677
12678         for param in "changelog_max_idle_time=10" \
12679                      "changelog_gc=1" \
12680                      "changelog_min_gc_interval=2" \
12681                      "changelog_min_free_cat_entries=3"; do
12682                 local MDT0=$(facet_svc $SINGLEMDS)
12683                 local var="${param%=*}"
12684                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12685
12686                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12687                 do_nodes $mdts $LCTL set_param mdd.*.$param
12688         done
12689
12690         # force cl_user2 to be idle (1st part)
12691         sleep 9
12692
12693         # simulate changelog catalog almost full
12694         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12695         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12696
12697         for i in $(seq $MDSCOUNT); do
12698                 cl_users=(${CL_USERS[mds$i]})
12699                 cl_user1[mds$i]="${cl_users[0]}"
12700                 cl_user2[mds$i]="${cl_users[1]}"
12701
12702                 [ -n "${cl_user1[mds$i]}" ] ||
12703                         error "mds$i: no user registered"
12704                 [ -n "${cl_user2[mds$i]}" ] ||
12705                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12706
12707                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12708                 [ -n "$user_rec1" ] ||
12709                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12710                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12711                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12712                 [ -n "$user_rec2" ] ||
12713                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12714                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12715                      "$user_rec1 + 2 == $user_rec2"
12716                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12717                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12718                               "$user_rec1 + 2, but is $user_rec2"
12719                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12720                 [ -n "$user_rec2" ] ||
12721                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12722                 [ $user_rec1 == $user_rec2 ] ||
12723                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12724                               "$user_rec1, but is $user_rec2"
12725         done
12726
12727         # force cl_user2 to be idle (2nd part) and to reach
12728         # changelog_max_idle_time
12729         sleep 2
12730
12731         # generate one more changelog to trigger fail_loc
12732         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12733                 error "create $DIR/$tdir/${tfile}bis failed"
12734
12735         # ensure gc thread is done
12736         for i in $(mdts_nodes); do
12737                 wait_update $i \
12738                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12739                         error "$i: GC-thread not done"
12740         done
12741
12742         local first_rec
12743         for i in $(seq $MDSCOUNT); do
12744                 # check cl_user1 still registered
12745                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12747                 # check cl_user2 unregistered
12748                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12749                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12750
12751                 # check changelogs are present and starting at $user_rec1 + 1
12752                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12753                 [ -n "$user_rec1" ] ||
12754                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12755                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12756                             awk '{ print $1; exit; }')
12757
12758                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12759                 [ $((user_rec1 + 1)) == $first_rec ] ||
12760                         error "mds$i: first index should be $user_rec1 + 1, " \
12761                               "but is $first_rec"
12762         done
12763 }
12764 run_test 160f "changelog garbage collect (timestamped users)"
12765
12766 test_160g() {
12767         remote_mds_nodsh && skip "remote MDS with nodsh"
12768         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12769                 skip "Need MDS version at least 2.10.56"
12770
12771         local mdts=$(comma_list $(mdts_nodes))
12772
12773         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12774         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12775
12776         # Create a user
12777         changelog_register || error "first changelog_register failed"
12778         changelog_register || error "second changelog_register failed"
12779         local cl_users
12780         declare -A cl_user1
12781         declare -A cl_user2
12782         local user_rec1
12783         local user_rec2
12784         local i
12785
12786         # generate some changelog records to accumulate on each MDT
12787         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12788         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12789                 error "create $DIR/$tdir/$tfile failed"
12790
12791         # check changelogs have been generated
12792         local nbcl=$(changelog_dump | wc -l)
12793         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12794
12795         # reduce the max_idle_indexes value to make sure we exceed it
12796         max_ndx=$((nbcl / 2 - 1))
12797
12798         for param in "changelog_max_idle_indexes=$max_ndx" \
12799                      "changelog_gc=1" \
12800                      "changelog_min_gc_interval=2" \
12801                      "changelog_min_free_cat_entries=3"; do
12802                 local MDT0=$(facet_svc $SINGLEMDS)
12803                 local var="${param%=*}"
12804                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12805
12806                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12807                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12808                         error "unable to set mdd.*.$param"
12809         done
12810
12811         # simulate changelog catalog almost full
12812         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12813         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12814
12815         for i in $(seq $MDSCOUNT); do
12816                 cl_users=(${CL_USERS[mds$i]})
12817                 cl_user1[mds$i]="${cl_users[0]}"
12818                 cl_user2[mds$i]="${cl_users[1]}"
12819
12820                 [ -n "${cl_user1[mds$i]}" ] ||
12821                         error "mds$i: no user registered"
12822                 [ -n "${cl_user2[mds$i]}" ] ||
12823                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12824
12825                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12826                 [ -n "$user_rec1" ] ||
12827                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12828                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12829                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12830                 [ -n "$user_rec2" ] ||
12831                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12832                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12833                      "$user_rec1 + 2 == $user_rec2"
12834                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12835                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12836                               "$user_rec1 + 2, but is $user_rec2"
12837                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12838                 [ -n "$user_rec2" ] ||
12839                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12840                 [ $user_rec1 == $user_rec2 ] ||
12841                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12842                               "$user_rec1, but is $user_rec2"
12843         done
12844
12845         # ensure we are past the previous changelog_min_gc_interval set above
12846         sleep 2
12847
12848         # generate one more changelog to trigger fail_loc
12849         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12850                 error "create $DIR/$tdir/${tfile}bis failed"
12851
12852         # ensure gc thread is done
12853         for i in $(mdts_nodes); do
12854                 wait_update $i \
12855                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12856                         error "$i: GC-thread not done"
12857         done
12858
12859         local first_rec
12860         for i in $(seq $MDSCOUNT); do
12861                 # check cl_user1 still registered
12862                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12863                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12864                 # check cl_user2 unregistered
12865                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12866                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12867
12868                 # check changelogs are present and starting at $user_rec1 + 1
12869                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12870                 [ -n "$user_rec1" ] ||
12871                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12872                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12873                             awk '{ print $1; exit; }')
12874
12875                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12876                 [ $((user_rec1 + 1)) == $first_rec ] ||
12877                         error "mds$i: first index should be $user_rec1 + 1, " \
12878                               "but is $first_rec"
12879         done
12880 }
12881 run_test 160g "changelog garbage collect (old users)"
12882
12883 test_160h() {
12884         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12885         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12886                 skip "Need MDS version at least 2.10.56"
12887
12888         local mdts=$(comma_list $(mdts_nodes))
12889
12890         # Create a user
12891         changelog_register || error "first changelog_register failed"
12892         changelog_register || error "second changelog_register failed"
12893         local cl_users
12894         declare -A cl_user1
12895         declare -A cl_user2
12896         local user_rec1
12897         local user_rec2
12898         local i
12899
12900         # generate some changelog records to accumulate on each MDT
12901         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12902         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12903                 error "create $DIR/$tdir/$tfile failed"
12904
12905         # check changelogs have been generated
12906         local nbcl=$(changelog_dump | wc -l)
12907         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12908
12909         for param in "changelog_max_idle_time=10" \
12910                      "changelog_gc=1" \
12911                      "changelog_min_gc_interval=2"; do
12912                 local MDT0=$(facet_svc $SINGLEMDS)
12913                 local var="${param%=*}"
12914                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12915
12916                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12917                 do_nodes $mdts $LCTL set_param mdd.*.$param
12918         done
12919
12920         # force cl_user2 to be idle (1st part)
12921         sleep 9
12922
12923         for i in $(seq $MDSCOUNT); do
12924                 cl_users=(${CL_USERS[mds$i]})
12925                 cl_user1[mds$i]="${cl_users[0]}"
12926                 cl_user2[mds$i]="${cl_users[1]}"
12927
12928                 [ -n "${cl_user1[mds$i]}" ] ||
12929                         error "mds$i: no user registered"
12930                 [ -n "${cl_user2[mds$i]}" ] ||
12931                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12932
12933                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12934                 [ -n "$user_rec1" ] ||
12935                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12936                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12937                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12938                 [ -n "$user_rec2" ] ||
12939                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12940                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12941                      "$user_rec1 + 2 == $user_rec2"
12942                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12943                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12944                               "$user_rec1 + 2, but is $user_rec2"
12945                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12946                 [ -n "$user_rec2" ] ||
12947                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12948                 [ $user_rec1 == $user_rec2 ] ||
12949                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12950                               "$user_rec1, but is $user_rec2"
12951         done
12952
12953         # force cl_user2 to be idle (2nd part) and to reach
12954         # changelog_max_idle_time
12955         sleep 2
12956
12957         # force each GC-thread start and block then
12958         # one per MDT/MDD, set fail_val accordingly
12959         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12960         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12961
12962         # generate more changelogs to trigger fail_loc
12963         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12964                 error "create $DIR/$tdir/${tfile}bis failed"
12965
12966         # stop MDT to stop GC-thread, should be done in back-ground as it will
12967         # block waiting for the thread to be released and exit
12968         declare -A stop_pids
12969         for i in $(seq $MDSCOUNT); do
12970                 stop mds$i &
12971                 stop_pids[mds$i]=$!
12972         done
12973
12974         for i in $(mdts_nodes); do
12975                 local facet
12976                 local nb=0
12977                 local facets=$(facets_up_on_host $i)
12978
12979                 for facet in ${facets//,/ }; do
12980                         if [[ $facet == mds* ]]; then
12981                                 nb=$((nb + 1))
12982                         fi
12983                 done
12984                 # ensure each MDS's gc threads are still present and all in "R"
12985                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12986                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12987                         error "$i: expected $nb GC-thread"
12988                 wait_update $i \
12989                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12990                         "R" 20 ||
12991                         error "$i: GC-thread not found in R-state"
12992                 # check umounts of each MDT on MDS have reached kthread_stop()
12993                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12994                         error "$i: expected $nb umount"
12995                 wait_update $i \
12996                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12997                         error "$i: umount not found in D-state"
12998         done
12999
13000         # release all GC-threads
13001         do_nodes $mdts $LCTL set_param fail_loc=0
13002
13003         # wait for MDT stop to complete
13004         for i in $(seq $MDSCOUNT); do
13005                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13006         done
13007
13008         # XXX
13009         # may try to check if any orphan changelog records are present
13010         # via ldiskfs/zfs and llog_reader...
13011
13012         # re-start/mount MDTs
13013         for i in $(seq $MDSCOUNT); do
13014                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13015                         error "Fail to start mds$i"
13016         done
13017
13018         local first_rec
13019         for i in $(seq $MDSCOUNT); do
13020                 # check cl_user1 still registered
13021                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13022                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13023                 # check cl_user2 unregistered
13024                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13025                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13026
13027                 # check changelogs are present and starting at $user_rec1 + 1
13028                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13029                 [ -n "$user_rec1" ] ||
13030                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13031                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13032                             awk '{ print $1; exit; }')
13033
13034                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13035                 [ $((user_rec1 + 1)) == $first_rec ] ||
13036                         error "mds$i: first index should be $user_rec1 + 1, " \
13037                               "but is $first_rec"
13038         done
13039 }
13040 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13041               "during mount"
13042
13043 test_160i() {
13044
13045         local mdts=$(comma_list $(mdts_nodes))
13046
13047         changelog_register || error "first changelog_register failed"
13048
13049         # generate some changelog records to accumulate on each MDT
13050         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13051         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13052                 error "create $DIR/$tdir/$tfile failed"
13053
13054         # check changelogs have been generated
13055         local nbcl=$(changelog_dump | wc -l)
13056         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13057
13058         # simulate race between register and unregister
13059         # XXX as fail_loc is set per-MDS, with DNE configs the race
13060         # simulation will only occur for one MDT per MDS and for the
13061         # others the normal race scenario will take place
13062         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13063         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13064         do_nodes $mdts $LCTL set_param fail_val=1
13065
13066         # unregister 1st user
13067         changelog_deregister &
13068         local pid1=$!
13069         # wait some time for deregister work to reach race rdv
13070         sleep 2
13071         # register 2nd user
13072         changelog_register || error "2nd user register failed"
13073
13074         wait $pid1 || error "1st user deregister failed"
13075
13076         local i
13077         local last_rec
13078         declare -A LAST_REC
13079         for i in $(seq $MDSCOUNT); do
13080                 if changelog_users mds$i | grep "^cl"; then
13081                         # make sure new records are added with one user present
13082                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13083                                           awk '/^current.index:/ { print $NF }')
13084                 else
13085                         error "mds$i has no user registered"
13086                 fi
13087         done
13088
13089         # generate more changelog records to accumulate on each MDT
13090         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13091                 error "create $DIR/$tdir/${tfile}bis failed"
13092
13093         for i in $(seq $MDSCOUNT); do
13094                 last_rec=$(changelog_users $SINGLEMDS |
13095                            awk '/^current.index:/ { print $NF }')
13096                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13097                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13098                         error "changelogs are off on mds$i"
13099         done
13100 }
13101 run_test 160i "changelog user register/unregister race"
13102
13103 test_161a() {
13104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13105
13106         test_mkdir -c1 $DIR/$tdir
13107         cp /etc/hosts $DIR/$tdir/$tfile
13108         test_mkdir -c1 $DIR/$tdir/foo1
13109         test_mkdir -c1 $DIR/$tdir/foo2
13110         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13111         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13112         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13113         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13114         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13115         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13116                 $LFS fid2path $DIR $FID
13117                 error "bad link ea"
13118         fi
13119         # middle
13120         rm $DIR/$tdir/foo2/zachary
13121         # last
13122         rm $DIR/$tdir/foo2/thor
13123         # first
13124         rm $DIR/$tdir/$tfile
13125         # rename
13126         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13127         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13128                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13129         rm $DIR/$tdir/foo2/maggie
13130
13131         # overflow the EA
13132         local longname=$tfile.avg_len_is_thirty_two_
13133         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13134                 error_noexit 'failed to unlink many hardlinks'" EXIT
13135         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13136                 error "failed to hardlink many files"
13137         links=$($LFS fid2path $DIR $FID | wc -l)
13138         echo -n "${links}/1000 links in link EA"
13139         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13140 }
13141 run_test 161a "link ea sanity"
13142
13143 test_161b() {
13144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13145         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13146
13147         local MDTIDX=1
13148         local remote_dir=$DIR/$tdir/remote_dir
13149
13150         mkdir -p $DIR/$tdir
13151         $LFS mkdir -i $MDTIDX $remote_dir ||
13152                 error "create remote directory failed"
13153
13154         cp /etc/hosts $remote_dir/$tfile
13155         mkdir -p $remote_dir/foo1
13156         mkdir -p $remote_dir/foo2
13157         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13158         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13159         ln $remote_dir/$tfile $remote_dir/foo1/luna
13160         ln $remote_dir/$tfile $remote_dir/foo2/thor
13161
13162         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13163                      tr -d ']')
13164         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13165                 $LFS fid2path $DIR $FID
13166                 error "bad link ea"
13167         fi
13168         # middle
13169         rm $remote_dir/foo2/zachary
13170         # last
13171         rm $remote_dir/foo2/thor
13172         # first
13173         rm $remote_dir/$tfile
13174         # rename
13175         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13176         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13177         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13178                 $LFS fid2path $DIR $FID
13179                 error "bad link rename"
13180         fi
13181         rm $remote_dir/foo2/maggie
13182
13183         # overflow the EA
13184         local longname=filename_avg_len_is_thirty_two_
13185         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13186                 error "failed to hardlink many files"
13187         links=$($LFS fid2path $DIR $FID | wc -l)
13188         echo -n "${links}/1000 links in link EA"
13189         [[ ${links} -gt 60 ]] ||
13190                 error "expected at least 60 links in link EA"
13191         unlinkmany $remote_dir/foo2/$longname 1000 ||
13192         error "failed to unlink many hardlinks"
13193 }
13194 run_test 161b "link ea sanity under remote directory"
13195
13196 test_161c() {
13197         remote_mds_nodsh && skip "remote MDS with nodsh"
13198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13199         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13200                 skip "Need MDS version at least 2.1.5"
13201
13202         # define CLF_RENAME_LAST 0x0001
13203         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13204         changelog_register || error "changelog_register failed"
13205
13206         rm -rf $DIR/$tdir
13207         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13208         touch $DIR/$tdir/foo_161c
13209         touch $DIR/$tdir/bar_161c
13210         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13211         changelog_dump | grep RENME | tail -n 5
13212         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13213         changelog_clear 0 || error "changelog_clear failed"
13214         if [ x$flags != "x0x1" ]; then
13215                 error "flag $flags is not 0x1"
13216         fi
13217
13218         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13219         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13220         touch $DIR/$tdir/foo_161c
13221         touch $DIR/$tdir/bar_161c
13222         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13223         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13224         changelog_dump | grep RENME | tail -n 5
13225         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13226         changelog_clear 0 || error "changelog_clear failed"
13227         if [ x$flags != "x0x0" ]; then
13228                 error "flag $flags is not 0x0"
13229         fi
13230         echo "rename overwrite a target having nlink > 1," \
13231                 "changelog record has flags of $flags"
13232
13233         # rename doesn't overwrite a target (changelog flag 0x0)
13234         touch $DIR/$tdir/foo_161c
13235         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13236         changelog_dump | grep RENME | tail -n 5
13237         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13238         changelog_clear 0 || error "changelog_clear failed"
13239         if [ x$flags != "x0x0" ]; then
13240                 error "flag $flags is not 0x0"
13241         fi
13242         echo "rename doesn't overwrite a target," \
13243                 "changelog record has flags of $flags"
13244
13245         # define CLF_UNLINK_LAST 0x0001
13246         # unlink a file having nlink = 1 (changelog flag 0x1)
13247         rm -f $DIR/$tdir/foo2_161c
13248         changelog_dump | grep UNLNK | tail -n 5
13249         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13250         changelog_clear 0 || error "changelog_clear failed"
13251         if [ x$flags != "x0x1" ]; then
13252                 error "flag $flags is not 0x1"
13253         fi
13254         echo "unlink a file having nlink = 1," \
13255                 "changelog record has flags of $flags"
13256
13257         # unlink a file having nlink > 1 (changelog flag 0x0)
13258         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13259         rm -f $DIR/$tdir/foobar_161c
13260         changelog_dump | grep UNLNK | tail -n 5
13261         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13262         changelog_clear 0 || error "changelog_clear failed"
13263         if [ x$flags != "x0x0" ]; then
13264                 error "flag $flags is not 0x0"
13265         fi
13266         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13267 }
13268 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13269
13270 test_161d() {
13271         remote_mds_nodsh && skip "remote MDS with nodsh"
13272         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13273
13274         local pid
13275         local fid
13276
13277         changelog_register || error "changelog_register failed"
13278
13279         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13280         # interfer with $MOUNT/.lustre/fid/ access
13281         mkdir $DIR/$tdir
13282         [[ $? -eq 0 ]] || error "mkdir failed"
13283
13284         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13285         $LCTL set_param fail_loc=0x8000140c
13286         # 5s pause
13287         $LCTL set_param fail_val=5
13288
13289         # create file
13290         echo foofoo > $DIR/$tdir/$tfile &
13291         pid=$!
13292
13293         # wait for create to be delayed
13294         sleep 2
13295
13296         ps -p $pid
13297         [[ $? -eq 0 ]] || error "create should be blocked"
13298
13299         local tempfile=$(mktemp)
13300         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13301         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13302         # some delay may occur during ChangeLog publishing and file read just
13303         # above, that could allow file write to happen finally
13304         [[ -s $tempfile ]] && echo "file should be empty"
13305
13306         $LCTL set_param fail_loc=0
13307
13308         wait $pid
13309         [[ $? -eq 0 ]] || error "create failed"
13310 }
13311 run_test 161d "create with concurrent .lustre/fid access"
13312
13313 check_path() {
13314         local expected="$1"
13315         shift
13316         local fid="$2"
13317
13318         local path
13319         path=$($LFS fid2path "$@")
13320         local rc=$?
13321
13322         if [ $rc -ne 0 ]; then
13323                 error "path looked up of '$expected' failed: rc=$rc"
13324         elif [ "$path" != "$expected" ]; then
13325                 error "path looked up '$path' instead of '$expected'"
13326         else
13327                 echo "FID '$fid' resolves to path '$path' as expected"
13328         fi
13329 }
13330
13331 test_162a() { # was test_162
13332         test_mkdir -p -c1 $DIR/$tdir/d2
13333         touch $DIR/$tdir/d2/$tfile
13334         touch $DIR/$tdir/d2/x1
13335         touch $DIR/$tdir/d2/x2
13336         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13337         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13338         # regular file
13339         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13340         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13341
13342         # softlink
13343         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13344         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13345         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13346
13347         # softlink to wrong file
13348         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13349         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13350         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13351
13352         # hardlink
13353         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13354         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13355         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13356         # fid2path dir/fsname should both work
13357         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13358         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13359
13360         # hardlink count: check that there are 2 links
13361         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13362         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13363
13364         # hardlink indexing: remove the first link
13365         rm $DIR/$tdir/d2/p/q/r/hlink
13366         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13367 }
13368 run_test 162a "path lookup sanity"
13369
13370 test_162b() {
13371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13372         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13373
13374         mkdir $DIR/$tdir
13375         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13376                                 error "create striped dir failed"
13377
13378         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13379                                         tail -n 1 | awk '{print $2}')
13380         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13381
13382         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13383         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13384
13385         # regular file
13386         for ((i=0;i<5;i++)); do
13387                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13388                         error "get fid for f$i failed"
13389                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13390
13391                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13392                         error "get fid for d$i failed"
13393                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13394         done
13395
13396         return 0
13397 }
13398 run_test 162b "striped directory path lookup sanity"
13399
13400 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13401 test_162c() {
13402         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13403                 skip "Need MDS version at least 2.7.51"
13404
13405         local lpath=$tdir.local
13406         local rpath=$tdir.remote
13407
13408         test_mkdir $DIR/$lpath
13409         test_mkdir $DIR/$rpath
13410
13411         for ((i = 0; i <= 101; i++)); do
13412                 lpath="$lpath/$i"
13413                 mkdir $DIR/$lpath
13414                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13415                         error "get fid for local directory $DIR/$lpath failed"
13416                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13417
13418                 rpath="$rpath/$i"
13419                 test_mkdir $DIR/$rpath
13420                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13421                         error "get fid for remote directory $DIR/$rpath failed"
13422                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13423         done
13424
13425         return 0
13426 }
13427 run_test 162c "fid2path works with paths 100 or more directories deep"
13428
13429 test_169() {
13430         # do directio so as not to populate the page cache
13431         log "creating a 10 Mb file"
13432         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13433         log "starting reads"
13434         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13435         log "truncating the file"
13436         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13437         log "killing dd"
13438         kill %+ || true # reads might have finished
13439         echo "wait until dd is finished"
13440         wait
13441         log "removing the temporary file"
13442         rm -rf $DIR/$tfile || error "tmp file removal failed"
13443 }
13444 run_test 169 "parallel read and truncate should not deadlock"
13445
13446 test_170() {
13447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13448
13449         $LCTL clear     # bug 18514
13450         $LCTL debug_daemon start $TMP/${tfile}_log_good
13451         touch $DIR/$tfile
13452         $LCTL debug_daemon stop
13453         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13454                 error "sed failed to read log_good"
13455
13456         $LCTL debug_daemon start $TMP/${tfile}_log_good
13457         rm -rf $DIR/$tfile
13458         $LCTL debug_daemon stop
13459
13460         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13461                error "lctl df log_bad failed"
13462
13463         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13464         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13465
13466         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13467         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13468
13469         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13470                 error "bad_line good_line1 good_line2 are empty"
13471
13472         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13473         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13474         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13475
13476         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13477         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13478         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13479
13480         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13481                 error "bad_line_new good_line_new are empty"
13482
13483         local expected_good=$((good_line1 + good_line2*2))
13484
13485         rm -f $TMP/${tfile}*
13486         # LU-231, short malformed line may not be counted into bad lines
13487         if [ $bad_line -ne $bad_line_new ] &&
13488                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13489                 error "expected $bad_line bad lines, but got $bad_line_new"
13490                 return 1
13491         fi
13492
13493         if [ $expected_good -ne $good_line_new ]; then
13494                 error "expected $expected_good good lines, but got $good_line_new"
13495                 return 2
13496         fi
13497         true
13498 }
13499 run_test 170 "test lctl df to handle corrupted log ====================="
13500
13501 test_171() { # bug20592
13502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13503
13504         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13505         $LCTL set_param fail_loc=0x50e
13506         $LCTL set_param fail_val=3000
13507         multiop_bg_pause $DIR/$tfile O_s || true
13508         local MULTIPID=$!
13509         kill -USR1 $MULTIPID
13510         # cause log dump
13511         sleep 3
13512         wait $MULTIPID
13513         if dmesg | grep "recursive fault"; then
13514                 error "caught a recursive fault"
13515         fi
13516         $LCTL set_param fail_loc=0
13517         true
13518 }
13519 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13520
13521 # it would be good to share it with obdfilter-survey/iokit-libecho code
13522 setup_obdecho_osc () {
13523         local rc=0
13524         local ost_nid=$1
13525         local obdfilter_name=$2
13526         echo "Creating new osc for $obdfilter_name on $ost_nid"
13527         # make sure we can find loopback nid
13528         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13529
13530         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13531                            ${obdfilter_name}_osc_UUID || rc=2; }
13532         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13533                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13534         return $rc
13535 }
13536
13537 cleanup_obdecho_osc () {
13538         local obdfilter_name=$1
13539         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13540         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13541         return 0
13542 }
13543
13544 obdecho_test() {
13545         local OBD=$1
13546         local node=$2
13547         local pages=${3:-64}
13548         local rc=0
13549         local id
13550
13551         local count=10
13552         local obd_size=$(get_obd_size $node $OBD)
13553         local page_size=$(get_page_size $node)
13554         if [[ -n "$obd_size" ]]; then
13555                 local new_count=$((obd_size / (pages * page_size / 1024)))
13556                 [[ $new_count -ge $count ]] || count=$new_count
13557         fi
13558
13559         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13560         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13561                            rc=2; }
13562         if [ $rc -eq 0 ]; then
13563             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13564             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13565         fi
13566         echo "New object id is $id"
13567         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13568                            rc=4; }
13569         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13570                            "test_brw $count w v $pages $id" || rc=4; }
13571         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13572                            rc=4; }
13573         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13574                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13575         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13576                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13577         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13578         return $rc
13579 }
13580
13581 test_180a() {
13582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13583
13584         if ! module_loaded obdecho; then
13585                 load_module obdecho/obdecho &&
13586                         stack_trap "rmmod obdecho" EXIT ||
13587                         error "unable to load obdecho on client"
13588         fi
13589
13590         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13591         local host=$($LCTL get_param -n osc.$osc.import |
13592                      awk '/current_connection:/ { print $2 }' )
13593         local target=$($LCTL get_param -n osc.$osc.import |
13594                        awk '/target:/ { print $2 }' )
13595         target=${target%_UUID}
13596
13597         if [ -n "$target" ]; then
13598                 setup_obdecho_osc $host $target &&
13599                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13600                         { error "obdecho setup failed with $?"; return; }
13601
13602                 obdecho_test ${target}_osc client ||
13603                         error "obdecho_test failed on ${target}_osc"
13604         else
13605                 $LCTL get_param osc.$osc.import
13606                 error "there is no osc.$osc.import target"
13607         fi
13608 }
13609 run_test 180a "test obdecho on osc"
13610
13611 test_180b() {
13612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13613         remote_ost_nodsh && skip "remote OST with nodsh"
13614
13615         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13616                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13617                 error "failed to load module obdecho"
13618
13619         local target=$(do_facet ost1 $LCTL dl |
13620                        awk '/obdfilter/ { print $4; exit; }')
13621
13622         if [ -n "$target" ]; then
13623                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13624         else
13625                 do_facet ost1 $LCTL dl
13626                 error "there is no obdfilter target on ost1"
13627         fi
13628 }
13629 run_test 180b "test obdecho directly on obdfilter"
13630
13631 test_180c() { # LU-2598
13632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13633         remote_ost_nodsh && skip "remote OST with nodsh"
13634         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13635                 skip "Need MDS version at least 2.4.0"
13636
13637         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13638                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13639                 error "failed to load module obdecho"
13640
13641         local target=$(do_facet ost1 $LCTL dl |
13642                        awk '/obdfilter/ { print $4; exit; }')
13643
13644         if [ -n "$target" ]; then
13645                 local pages=16384 # 64MB bulk I/O RPC size
13646
13647                 obdecho_test "$target" ost1 "$pages" ||
13648                         error "obdecho_test with pages=$pages failed with $?"
13649         else
13650                 do_facet ost1 $LCTL dl
13651                 error "there is no obdfilter target on ost1"
13652         fi
13653 }
13654 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13655
13656 test_181() { # bug 22177
13657         test_mkdir $DIR/$tdir
13658         # create enough files to index the directory
13659         createmany -o $DIR/$tdir/foobar 4000
13660         # print attributes for debug purpose
13661         lsattr -d .
13662         # open dir
13663         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13664         MULTIPID=$!
13665         # remove the files & current working dir
13666         unlinkmany $DIR/$tdir/foobar 4000
13667         rmdir $DIR/$tdir
13668         kill -USR1 $MULTIPID
13669         wait $MULTIPID
13670         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13671         return 0
13672 }
13673 run_test 181 "Test open-unlinked dir ========================"
13674
13675 test_182() {
13676         local fcount=1000
13677         local tcount=10
13678
13679         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13680
13681         $LCTL set_param mdc.*.rpc_stats=clear
13682
13683         for (( i = 0; i < $tcount; i++ )) ; do
13684                 mkdir $DIR/$tdir/$i
13685         done
13686
13687         for (( i = 0; i < $tcount; i++ )) ; do
13688                 createmany -o $DIR/$tdir/$i/f- $fcount &
13689         done
13690         wait
13691
13692         for (( i = 0; i < $tcount; i++ )) ; do
13693                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13694         done
13695         wait
13696
13697         $LCTL get_param mdc.*.rpc_stats
13698
13699         rm -rf $DIR/$tdir
13700 }
13701 run_test 182 "Test parallel modify metadata operations ================"
13702
13703 test_183() { # LU-2275
13704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13705         remote_mds_nodsh && skip "remote MDS with nodsh"
13706         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13707                 skip "Need MDS version at least 2.3.56"
13708
13709         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13710         echo aaa > $DIR/$tdir/$tfile
13711
13712 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13713         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13714
13715         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13716         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13717
13718         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13719
13720         # Flush negative dentry cache
13721         touch $DIR/$tdir/$tfile
13722
13723         # We are not checking for any leaked references here, they'll
13724         # become evident next time we do cleanup with module unload.
13725         rm -rf $DIR/$tdir
13726 }
13727 run_test 183 "No crash or request leak in case of strange dispositions ========"
13728
13729 # test suite 184 is for LU-2016, LU-2017
13730 test_184a() {
13731         check_swap_layouts_support
13732
13733         dir0=$DIR/$tdir/$testnum
13734         test_mkdir -p -c1 $dir0
13735         ref1=/etc/passwd
13736         ref2=/etc/group
13737         file1=$dir0/f1
13738         file2=$dir0/f2
13739         $LFS setstripe -c1 $file1
13740         cp $ref1 $file1
13741         $LFS setstripe -c2 $file2
13742         cp $ref2 $file2
13743         gen1=$($LFS getstripe -g $file1)
13744         gen2=$($LFS getstripe -g $file2)
13745
13746         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13747         gen=$($LFS getstripe -g $file1)
13748         [[ $gen1 != $gen ]] ||
13749                 "Layout generation on $file1 does not change"
13750         gen=$($LFS getstripe -g $file2)
13751         [[ $gen2 != $gen ]] ||
13752                 "Layout generation on $file2 does not change"
13753
13754         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13755         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13756
13757         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13758 }
13759 run_test 184a "Basic layout swap"
13760
13761 test_184b() {
13762         check_swap_layouts_support
13763
13764         dir0=$DIR/$tdir/$testnum
13765         mkdir -p $dir0 || error "creating dir $dir0"
13766         file1=$dir0/f1
13767         file2=$dir0/f2
13768         file3=$dir0/f3
13769         dir1=$dir0/d1
13770         dir2=$dir0/d2
13771         mkdir $dir1 $dir2
13772         $LFS setstripe -c1 $file1
13773         $LFS setstripe -c2 $file2
13774         $LFS setstripe -c1 $file3
13775         chown $RUNAS_ID $file3
13776         gen1=$($LFS getstripe -g $file1)
13777         gen2=$($LFS getstripe -g $file2)
13778
13779         $LFS swap_layouts $dir1 $dir2 &&
13780                 error "swap of directories layouts should fail"
13781         $LFS swap_layouts $dir1 $file1 &&
13782                 error "swap of directory and file layouts should fail"
13783         $RUNAS $LFS swap_layouts $file1 $file2 &&
13784                 error "swap of file we cannot write should fail"
13785         $LFS swap_layouts $file1 $file3 &&
13786                 error "swap of file with different owner should fail"
13787         /bin/true # to clear error code
13788 }
13789 run_test 184b "Forbidden layout swap (will generate errors)"
13790
13791 test_184c() {
13792         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13793         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13794         check_swap_layouts_support
13795
13796         local dir0=$DIR/$tdir/$testnum
13797         mkdir -p $dir0 || error "creating dir $dir0"
13798
13799         local ref1=$dir0/ref1
13800         local ref2=$dir0/ref2
13801         local file1=$dir0/file1
13802         local file2=$dir0/file2
13803         # create a file large enough for the concurrent test
13804         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13805         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13806         echo "ref file size: ref1($(stat -c %s $ref1))," \
13807              "ref2($(stat -c %s $ref2))"
13808
13809         cp $ref2 $file2
13810         dd if=$ref1 of=$file1 bs=16k &
13811         local DD_PID=$!
13812
13813         # Make sure dd starts to copy file
13814         while [ ! -f $file1 ]; do sleep 0.1; done
13815
13816         $LFS swap_layouts $file1 $file2
13817         local rc=$?
13818         wait $DD_PID
13819         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13820         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13821
13822         # how many bytes copied before swapping layout
13823         local copied=$(stat -c %s $file2)
13824         local remaining=$(stat -c %s $ref1)
13825         remaining=$((remaining - copied))
13826         echo "Copied $copied bytes before swapping layout..."
13827
13828         cmp -n $copied $file1 $ref2 | grep differ &&
13829                 error "Content mismatch [0, $copied) of ref2 and file1"
13830         cmp -n $copied $file2 $ref1 ||
13831                 error "Content mismatch [0, $copied) of ref1 and file2"
13832         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13833                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13834
13835         # clean up
13836         rm -f $ref1 $ref2 $file1 $file2
13837 }
13838 run_test 184c "Concurrent write and layout swap"
13839
13840 test_184d() {
13841         check_swap_layouts_support
13842         [ -z "$(which getfattr 2>/dev/null)" ] &&
13843                 skip_env "no getfattr command"
13844
13845         local file1=$DIR/$tdir/$tfile-1
13846         local file2=$DIR/$tdir/$tfile-2
13847         local file3=$DIR/$tdir/$tfile-3
13848         local lovea1
13849         local lovea2
13850
13851         mkdir -p $DIR/$tdir
13852         touch $file1 || error "create $file1 failed"
13853         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13854                 error "create $file2 failed"
13855         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13856                 error "create $file3 failed"
13857         lovea1=$(get_layout_param $file1)
13858
13859         $LFS swap_layouts $file2 $file3 ||
13860                 error "swap $file2 $file3 layouts failed"
13861         $LFS swap_layouts $file1 $file2 ||
13862                 error "swap $file1 $file2 layouts failed"
13863
13864         lovea2=$(get_layout_param $file2)
13865         echo "$lovea1"
13866         echo "$lovea2"
13867         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13868
13869         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13870         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13871 }
13872 run_test 184d "allow stripeless layouts swap"
13873
13874 test_184e() {
13875         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13876                 skip "Need MDS version at least 2.6.94"
13877         check_swap_layouts_support
13878         [ -z "$(which getfattr 2>/dev/null)" ] &&
13879                 skip_env "no getfattr command"
13880
13881         local file1=$DIR/$tdir/$tfile-1
13882         local file2=$DIR/$tdir/$tfile-2
13883         local file3=$DIR/$tdir/$tfile-3
13884         local lovea
13885
13886         mkdir -p $DIR/$tdir
13887         touch $file1 || error "create $file1 failed"
13888         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13889                 error "create $file2 failed"
13890         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13891                 error "create $file3 failed"
13892
13893         $LFS swap_layouts $file1 $file2 ||
13894                 error "swap $file1 $file2 layouts failed"
13895
13896         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13897         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13898
13899         echo 123 > $file1 || error "Should be able to write into $file1"
13900
13901         $LFS swap_layouts $file1 $file3 ||
13902                 error "swap $file1 $file3 layouts failed"
13903
13904         echo 123 > $file1 || error "Should be able to write into $file1"
13905
13906         rm -rf $file1 $file2 $file3
13907 }
13908 run_test 184e "Recreate layout after stripeless layout swaps"
13909
13910 test_184f() {
13911         # Create a file with name longer than sizeof(struct stat) ==
13912         # 144 to see if we can get chars from the file name to appear
13913         # in the returned striping. Note that 'f' == 0x66.
13914         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13915
13916         mkdir -p $DIR/$tdir
13917         mcreate $DIR/$tdir/$file
13918         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13919                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13920         fi
13921 }
13922 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13923
13924 test_185() { # LU-2441
13925         # LU-3553 - no volatile file support in old servers
13926         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13927                 skip "Need MDS version at least 2.3.60"
13928
13929         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13930         touch $DIR/$tdir/spoo
13931         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13932         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13933                 error "cannot create/write a volatile file"
13934         [ "$FILESET" == "" ] &&
13935         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13936                 error "FID is still valid after close"
13937
13938         multiop_bg_pause $DIR/$tdir vVw4096_c
13939         local multi_pid=$!
13940
13941         local OLD_IFS=$IFS
13942         IFS=":"
13943         local fidv=($fid)
13944         IFS=$OLD_IFS
13945         # assume that the next FID for this client is sequential, since stdout
13946         # is unfortunately eaten by multiop_bg_pause
13947         local n=$((${fidv[1]} + 1))
13948         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13949         if [ "$FILESET" == "" ]; then
13950                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13951                         error "FID is missing before close"
13952         fi
13953         kill -USR1 $multi_pid
13954         # 1 second delay, so if mtime change we will see it
13955         sleep 1
13956         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13957         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13958 }
13959 run_test 185 "Volatile file support"
13960
13961 test_187a() {
13962         remote_mds_nodsh && skip "remote MDS with nodsh"
13963         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13964                 skip "Need MDS version at least 2.3.0"
13965
13966         local dir0=$DIR/$tdir/$testnum
13967         mkdir -p $dir0 || error "creating dir $dir0"
13968
13969         local file=$dir0/file1
13970         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13971         local dv1=$($LFS data_version $file)
13972         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13973         local dv2=$($LFS data_version $file)
13974         [[ $dv1 != $dv2 ]] ||
13975                 error "data version did not change on write $dv1 == $dv2"
13976
13977         # clean up
13978         rm -f $file1
13979 }
13980 run_test 187a "Test data version change"
13981
13982 test_187b() {
13983         remote_mds_nodsh && skip "remote MDS with nodsh"
13984         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13985                 skip "Need MDS version at least 2.3.0"
13986
13987         local dir0=$DIR/$tdir/$testnum
13988         mkdir -p $dir0 || error "creating dir $dir0"
13989
13990         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13991         [[ ${DV[0]} != ${DV[1]} ]] ||
13992                 error "data version did not change on write"\
13993                       " ${DV[0]} == ${DV[1]}"
13994
13995         # clean up
13996         rm -f $file1
13997 }
13998 run_test 187b "Test data version change on volatile file"
13999
14000 test_200() {
14001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14002         remote_mgs_nodsh && skip "remote MGS with nodsh"
14003         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14004
14005         local POOL=${POOL:-cea1}
14006         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14007         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14008         # Pool OST targets
14009         local first_ost=0
14010         local last_ost=$(($OSTCOUNT - 1))
14011         local ost_step=2
14012         local ost_list=$(seq $first_ost $ost_step $last_ost)
14013         local ost_range="$first_ost $last_ost $ost_step"
14014         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14015         local file_dir=$POOL_ROOT/file_tst
14016         local subdir=$test_path/subdir
14017         local rc=0
14018
14019         if ! combined_mgs_mds ; then
14020                 mount_mgs_client
14021         fi
14022
14023         while : ; do
14024                 # former test_200a test_200b
14025                 pool_add $POOL                          || { rc=$? ; break; }
14026                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14027                 # former test_200c test_200d
14028                 mkdir -p $test_path
14029                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14030                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14031                 mkdir -p $subdir
14032                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14033                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14034                                                         || { rc=$? ; break; }
14035                 # former test_200e test_200f
14036                 local files=$((OSTCOUNT*3))
14037                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14038                                                         || { rc=$? ; break; }
14039                 pool_create_files $POOL $file_dir $files "$ost_list" \
14040                                                         || { rc=$? ; break; }
14041                 # former test_200g test_200h
14042                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14043                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14044
14045                 # former test_201a test_201b test_201c
14046                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14047
14048                 local f=$test_path/$tfile
14049                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14050                 pool_remove $POOL $f                    || { rc=$? ; break; }
14051                 break
14052         done
14053
14054         destroy_test_pools
14055
14056         if ! combined_mgs_mds ; then
14057                 umount_mgs_client
14058         fi
14059         return $rc
14060 }
14061 run_test 200 "OST pools"
14062
14063 # usage: default_attr <count | size | offset>
14064 default_attr() {
14065         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14066 }
14067
14068 # usage: check_default_stripe_attr
14069 check_default_stripe_attr() {
14070         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14071         case $1 in
14072         --stripe-count|-c)
14073                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14074         --stripe-size|-S)
14075                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14076         --stripe-index|-i)
14077                 EXPECTED=-1;;
14078         *)
14079                 error "unknown getstripe attr '$1'"
14080         esac
14081
14082         [ $ACTUAL == $EXPECTED ] ||
14083                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14084 }
14085
14086 test_204a() {
14087         test_mkdir $DIR/$tdir
14088         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14089
14090         check_default_stripe_attr --stripe-count
14091         check_default_stripe_attr --stripe-size
14092         check_default_stripe_attr --stripe-index
14093 }
14094 run_test 204a "Print default stripe attributes"
14095
14096 test_204b() {
14097         test_mkdir $DIR/$tdir
14098         $LFS setstripe --stripe-count 1 $DIR/$tdir
14099
14100         check_default_stripe_attr --stripe-size
14101         check_default_stripe_attr --stripe-index
14102 }
14103 run_test 204b "Print default stripe size and offset"
14104
14105 test_204c() {
14106         test_mkdir $DIR/$tdir
14107         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14108
14109         check_default_stripe_attr --stripe-count
14110         check_default_stripe_attr --stripe-index
14111 }
14112 run_test 204c "Print default stripe count and offset"
14113
14114 test_204d() {
14115         test_mkdir $DIR/$tdir
14116         $LFS setstripe --stripe-index 0 $DIR/$tdir
14117
14118         check_default_stripe_attr --stripe-count
14119         check_default_stripe_attr --stripe-size
14120 }
14121 run_test 204d "Print default stripe count and size"
14122
14123 test_204e() {
14124         test_mkdir $DIR/$tdir
14125         $LFS setstripe -d $DIR/$tdir
14126
14127         check_default_stripe_attr --stripe-count --raw
14128         check_default_stripe_attr --stripe-size --raw
14129         check_default_stripe_attr --stripe-index --raw
14130 }
14131 run_test 204e "Print raw stripe attributes"
14132
14133 test_204f() {
14134         test_mkdir $DIR/$tdir
14135         $LFS setstripe --stripe-count 1 $DIR/$tdir
14136
14137         check_default_stripe_attr --stripe-size --raw
14138         check_default_stripe_attr --stripe-index --raw
14139 }
14140 run_test 204f "Print raw stripe size and offset"
14141
14142 test_204g() {
14143         test_mkdir $DIR/$tdir
14144         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14145
14146         check_default_stripe_attr --stripe-count --raw
14147         check_default_stripe_attr --stripe-index --raw
14148 }
14149 run_test 204g "Print raw stripe count and offset"
14150
14151 test_204h() {
14152         test_mkdir $DIR/$tdir
14153         $LFS setstripe --stripe-index 0 $DIR/$tdir
14154
14155         check_default_stripe_attr --stripe-count --raw
14156         check_default_stripe_attr --stripe-size --raw
14157 }
14158 run_test 204h "Print raw stripe count and size"
14159
14160 # Figure out which job scheduler is being used, if any,
14161 # or use a fake one
14162 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14163         JOBENV=SLURM_JOB_ID
14164 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14165         JOBENV=LSB_JOBID
14166 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14167         JOBENV=PBS_JOBID
14168 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14169         JOBENV=LOADL_STEP_ID
14170 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14171         JOBENV=JOB_ID
14172 else
14173         $LCTL list_param jobid_name > /dev/null 2>&1
14174         if [ $? -eq 0 ]; then
14175                 JOBENV=nodelocal
14176         else
14177                 JOBENV=FAKE_JOBID
14178         fi
14179 fi
14180 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14181
14182 verify_jobstats() {
14183         local cmd=($1)
14184         shift
14185         local facets="$@"
14186
14187 # we don't really need to clear the stats for this test to work, since each
14188 # command has a unique jobid, but it makes debugging easier if needed.
14189 #       for facet in $facets; do
14190 #               local dev=$(convert_facet2label $facet)
14191 #               # clear old jobstats
14192 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14193 #       done
14194
14195         # use a new JobID for each test, or we might see an old one
14196         [ "$JOBENV" = "FAKE_JOBID" ] &&
14197                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14198
14199         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14200
14201         [ "$JOBENV" = "nodelocal" ] && {
14202                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14203                 $LCTL set_param jobid_name=$FAKE_JOBID
14204                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14205         }
14206
14207         log "Test: ${cmd[*]}"
14208         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14209
14210         if [ $JOBENV = "FAKE_JOBID" ]; then
14211                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14212         else
14213                 ${cmd[*]}
14214         fi
14215
14216         # all files are created on OST0000
14217         for facet in $facets; do
14218                 local stats="*.$(convert_facet2label $facet).job_stats"
14219
14220                 # strip out libtool wrappers for in-tree executables
14221                 if [ $(do_facet $facet lctl get_param $stats |
14222                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14223                         do_facet $facet lctl get_param $stats
14224                         error "No jobstats for $JOBVAL found on $facet::$stats"
14225                 fi
14226         done
14227 }
14228
14229 jobstats_set() {
14230         local new_jobenv=$1
14231
14232         set_persistent_param_and_check client "jobid_var" \
14233                 "$FSNAME.sys.jobid_var" $new_jobenv
14234 }
14235
14236 test_205() { # Job stats
14237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14238         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14239                 skip "Need MDS version with at least 2.7.1"
14240         remote_mgs_nodsh && skip "remote MGS with nodsh"
14241         remote_mds_nodsh && skip "remote MDS with nodsh"
14242         remote_ost_nodsh && skip "remote OST with nodsh"
14243         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14244                 skip "Server doesn't support jobstats"
14245         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14246
14247         local old_jobenv=$($LCTL get_param -n jobid_var)
14248         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14249
14250         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14251                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14252         else
14253                 stack_trap "do_facet mgs $PERM_CMD \
14254                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14255         fi
14256         changelog_register
14257
14258         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14259                                 mdt.*.job_cleanup_interval | head -n 1)
14260         local new_interval=5
14261         do_facet $SINGLEMDS \
14262                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14263         stack_trap "do_facet $SINGLEMDS \
14264                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14265         local start=$SECONDS
14266
14267         local cmd
14268         # mkdir
14269         cmd="mkdir $DIR/$tdir"
14270         verify_jobstats "$cmd" "$SINGLEMDS"
14271         # rmdir
14272         cmd="rmdir $DIR/$tdir"
14273         verify_jobstats "$cmd" "$SINGLEMDS"
14274         # mkdir on secondary MDT
14275         if [ $MDSCOUNT -gt 1 ]; then
14276                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14277                 verify_jobstats "$cmd" "mds2"
14278         fi
14279         # mknod
14280         cmd="mknod $DIR/$tfile c 1 3"
14281         verify_jobstats "$cmd" "$SINGLEMDS"
14282         # unlink
14283         cmd="rm -f $DIR/$tfile"
14284         verify_jobstats "$cmd" "$SINGLEMDS"
14285         # create all files on OST0000 so verify_jobstats can find OST stats
14286         # open & close
14287         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14288         verify_jobstats "$cmd" "$SINGLEMDS"
14289         # setattr
14290         cmd="touch $DIR/$tfile"
14291         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14292         # write
14293         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14294         verify_jobstats "$cmd" "ost1"
14295         # read
14296         cancel_lru_locks osc
14297         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14298         verify_jobstats "$cmd" "ost1"
14299         # truncate
14300         cmd="$TRUNCATE $DIR/$tfile 0"
14301         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14302         # rename
14303         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14304         verify_jobstats "$cmd" "$SINGLEMDS"
14305         # jobstats expiry - sleep until old stats should be expired
14306         local left=$((new_interval + 5 - (SECONDS - start)))
14307         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14308                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14309                         "0" $left
14310         cmd="mkdir $DIR/$tdir.expire"
14311         verify_jobstats "$cmd" "$SINGLEMDS"
14312         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14313             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14314
14315         # Ensure that jobid are present in changelog (if supported by MDS)
14316         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14317                 changelog_dump | tail -10
14318                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14319                 [ $jobids -eq 9 ] ||
14320                         error "Wrong changelog jobid count $jobids != 9"
14321
14322                 # LU-5862
14323                 JOBENV="disable"
14324                 jobstats_set $JOBENV
14325                 touch $DIR/$tfile
14326                 changelog_dump | grep $tfile
14327                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14328                 [ $jobids -eq 0 ] ||
14329                         error "Unexpected jobids when jobid_var=$JOBENV"
14330         fi
14331
14332         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14333         JOBENV="JOBCOMPLEX"
14334         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14335
14336         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14337 }
14338 run_test 205 "Verify job stats"
14339
14340 # LU-1480, LU-1773 and LU-1657
14341 test_206() {
14342         mkdir -p $DIR/$tdir
14343         $LFS setstripe -c -1 $DIR/$tdir
14344 #define OBD_FAIL_LOV_INIT 0x1403
14345         $LCTL set_param fail_loc=0xa0001403
14346         $LCTL set_param fail_val=1
14347         touch $DIR/$tdir/$tfile || true
14348 }
14349 run_test 206 "fail lov_init_raid0() doesn't lbug"
14350
14351 test_207a() {
14352         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14353         local fsz=`stat -c %s $DIR/$tfile`
14354         cancel_lru_locks mdc
14355
14356         # do not return layout in getattr intent
14357 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14358         $LCTL set_param fail_loc=0x170
14359         local sz=`stat -c %s $DIR/$tfile`
14360
14361         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14362
14363         rm -rf $DIR/$tfile
14364 }
14365 run_test 207a "can refresh layout at glimpse"
14366
14367 test_207b() {
14368         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14369         local cksum=`md5sum $DIR/$tfile`
14370         local fsz=`stat -c %s $DIR/$tfile`
14371         cancel_lru_locks mdc
14372         cancel_lru_locks osc
14373
14374         # do not return layout in getattr intent
14375 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14376         $LCTL set_param fail_loc=0x171
14377
14378         # it will refresh layout after the file is opened but before read issues
14379         echo checksum is "$cksum"
14380         echo "$cksum" |md5sum -c --quiet || error "file differs"
14381
14382         rm -rf $DIR/$tfile
14383 }
14384 run_test 207b "can refresh layout at open"
14385
14386 test_208() {
14387         # FIXME: in this test suite, only RD lease is used. This is okay
14388         # for now as only exclusive open is supported. After generic lease
14389         # is done, this test suite should be revised. - Jinshan
14390
14391         remote_mds_nodsh && skip "remote MDS with nodsh"
14392         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14393                 skip "Need MDS version at least 2.4.52"
14394
14395         echo "==== test 1: verify get lease work"
14396         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14397
14398         echo "==== test 2: verify lease can be broken by upcoming open"
14399         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14400         local PID=$!
14401         sleep 1
14402
14403         $MULTIOP $DIR/$tfile oO_RDONLY:c
14404         kill -USR1 $PID && wait $PID || error "break lease error"
14405
14406         echo "==== test 3: verify lease can't be granted if an open already exists"
14407         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14408         local PID=$!
14409         sleep 1
14410
14411         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14412         kill -USR1 $PID && wait $PID || error "open file error"
14413
14414         echo "==== test 4: lease can sustain over recovery"
14415         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14416         PID=$!
14417         sleep 1
14418
14419         fail mds1
14420
14421         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14422
14423         echo "==== test 5: lease broken can't be regained by replay"
14424         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14425         PID=$!
14426         sleep 1
14427
14428         # open file to break lease and then recovery
14429         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14430         fail mds1
14431
14432         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14433
14434         rm -f $DIR/$tfile
14435 }
14436 run_test 208 "Exclusive open"
14437
14438 test_209() {
14439         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14440                 skip_env "must have disp_stripe"
14441
14442         touch $DIR/$tfile
14443         sync; sleep 5; sync;
14444
14445         echo 3 > /proc/sys/vm/drop_caches
14446         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14447
14448         # open/close 500 times
14449         for i in $(seq 500); do
14450                 cat $DIR/$tfile
14451         done
14452
14453         echo 3 > /proc/sys/vm/drop_caches
14454         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14455
14456         echo "before: $req_before, after: $req_after"
14457         [ $((req_after - req_before)) -ge 300 ] &&
14458                 error "open/close requests are not freed"
14459         return 0
14460 }
14461 run_test 209 "read-only open/close requests should be freed promptly"
14462
14463 test_212() {
14464         size=`date +%s`
14465         size=$((size % 8192 + 1))
14466         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14467         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14468         rm -f $DIR/f212 $DIR/f212.xyz
14469 }
14470 run_test 212 "Sendfile test ============================================"
14471
14472 test_213() {
14473         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14474         cancel_lru_locks osc
14475         lctl set_param fail_loc=0x8000040f
14476         # generate a read lock
14477         cat $DIR/$tfile > /dev/null
14478         # write to the file, it will try to cancel the above read lock.
14479         cat /etc/hosts >> $DIR/$tfile
14480 }
14481 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14482
14483 test_214() { # for bug 20133
14484         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14485         for (( i=0; i < 340; i++ )) ; do
14486                 touch $DIR/$tdir/d214c/a$i
14487         done
14488
14489         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14490         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14491         ls $DIR/d214c || error "ls $DIR/d214c failed"
14492         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14493         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14494 }
14495 run_test 214 "hash-indexed directory test - bug 20133"
14496
14497 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14498 create_lnet_proc_files() {
14499         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14500 }
14501
14502 # counterpart of create_lnet_proc_files
14503 remove_lnet_proc_files() {
14504         rm -f $TMP/lnet_$1.sys
14505 }
14506
14507 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14508 # 3rd arg as regexp for body
14509 check_lnet_proc_stats() {
14510         local l=$(cat "$TMP/lnet_$1" |wc -l)
14511         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14512
14513         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14514 }
14515
14516 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14517 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14518 # optional and can be regexp for 2nd line (lnet.routes case)
14519 check_lnet_proc_entry() {
14520         local blp=2          # blp stands for 'position of 1st line of body'
14521         [ -z "$5" ] || blp=3 # lnet.routes case
14522
14523         local l=$(cat "$TMP/lnet_$1" |wc -l)
14524         # subtracting one from $blp because the body can be empty
14525         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14526
14527         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14528                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14529
14530         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14531                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14532
14533         # bail out if any unexpected line happened
14534         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14535         [ "$?" != 0 ] || error "$2 misformatted"
14536 }
14537
14538 test_215() { # for bugs 18102, 21079, 21517
14539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14540
14541         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14542         local P='[1-9][0-9]*'           # positive numeric
14543         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14544         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14545         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14546         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14547
14548         local L1 # regexp for 1st line
14549         local L2 # regexp for 2nd line (optional)
14550         local BR # regexp for the rest (body)
14551
14552         # lnet.stats should look as 11 space-separated non-negative numerics
14553         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14554         create_lnet_proc_files "stats"
14555         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14556         remove_lnet_proc_files "stats"
14557
14558         # lnet.routes should look like this:
14559         # Routing disabled/enabled
14560         # net hops priority state router
14561         # where net is a string like tcp0, hops > 0, priority >= 0,
14562         # state is up/down,
14563         # router is a string like 192.168.1.1@tcp2
14564         L1="^Routing (disabled|enabled)$"
14565         L2="^net +hops +priority +state +router$"
14566         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14567         create_lnet_proc_files "routes"
14568         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14569         remove_lnet_proc_files "routes"
14570
14571         # lnet.routers should look like this:
14572         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14573         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14574         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14575         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14576         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14577         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14578         create_lnet_proc_files "routers"
14579         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14580         remove_lnet_proc_files "routers"
14581
14582         # lnet.peers should look like this:
14583         # nid refs state last max rtr min tx min queue
14584         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14585         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14586         # numeric (0 or >0 or <0), queue >= 0.
14587         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14588         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14589         create_lnet_proc_files "peers"
14590         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14591         remove_lnet_proc_files "peers"
14592
14593         # lnet.buffers  should look like this:
14594         # pages count credits min
14595         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14596         L1="^pages +count +credits +min$"
14597         BR="^ +$N +$N +$I +$I$"
14598         create_lnet_proc_files "buffers"
14599         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14600         remove_lnet_proc_files "buffers"
14601
14602         # lnet.nis should look like this:
14603         # nid status alive refs peer rtr max tx min
14604         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14605         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14606         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14607         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14608         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14609         create_lnet_proc_files "nis"
14610         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14611         remove_lnet_proc_files "nis"
14612
14613         # can we successfully write to lnet.stats?
14614         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14615 }
14616 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14617
14618 test_216() { # bug 20317
14619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14620         remote_ost_nodsh && skip "remote OST with nodsh"
14621
14622         local node
14623         local facets=$(get_facets OST)
14624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14625
14626         save_lustre_params client "osc.*.contention_seconds" > $p
14627         save_lustre_params $facets \
14628                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14629         save_lustre_params $facets \
14630                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14631         save_lustre_params $facets \
14632                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14633         clear_stats osc.*.osc_stats
14634
14635         # agressive lockless i/o settings
14636         do_nodes $(comma_list $(osts_nodes)) \
14637                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14638                         ldlm.namespaces.filter-*.contended_locks=0 \
14639                         ldlm.namespaces.filter-*.contention_seconds=60"
14640         lctl set_param -n osc.*.contention_seconds=60
14641
14642         $DIRECTIO write $DIR/$tfile 0 10 4096
14643         $CHECKSTAT -s 40960 $DIR/$tfile
14644
14645         # disable lockless i/o
14646         do_nodes $(comma_list $(osts_nodes)) \
14647                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14648                         ldlm.namespaces.filter-*.contended_locks=32 \
14649                         ldlm.namespaces.filter-*.contention_seconds=0"
14650         lctl set_param -n osc.*.contention_seconds=0
14651         clear_stats osc.*.osc_stats
14652
14653         dd if=/dev/zero of=$DIR/$tfile count=0
14654         $CHECKSTAT -s 0 $DIR/$tfile
14655
14656         restore_lustre_params <$p
14657         rm -f $p
14658         rm $DIR/$tfile
14659 }
14660 run_test 216 "check lockless direct write updates file size and kms correctly"
14661
14662 test_217() { # bug 22430
14663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14664
14665         local node
14666         local nid
14667
14668         for node in $(nodes_list); do
14669                 nid=$(host_nids_address $node $NETTYPE)
14670                 if [[ $nid = *-* ]] ; then
14671                         echo "lctl ping $(h2nettype $nid)"
14672                         lctl ping $(h2nettype $nid)
14673                 else
14674                         echo "skipping $node (no hyphen detected)"
14675                 fi
14676         done
14677 }
14678 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14679
14680 test_218() {
14681        # do directio so as not to populate the page cache
14682        log "creating a 10 Mb file"
14683        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14684        log "starting reads"
14685        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14686        log "truncating the file"
14687        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14688        log "killing dd"
14689        kill %+ || true # reads might have finished
14690        echo "wait until dd is finished"
14691        wait
14692        log "removing the temporary file"
14693        rm -rf $DIR/$tfile || error "tmp file removal failed"
14694 }
14695 run_test 218 "parallel read and truncate should not deadlock"
14696
14697 test_219() {
14698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14699
14700         # write one partial page
14701         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14702         # set no grant so vvp_io_commit_write will do sync write
14703         $LCTL set_param fail_loc=0x411
14704         # write a full page at the end of file
14705         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14706
14707         $LCTL set_param fail_loc=0
14708         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14709         $LCTL set_param fail_loc=0x411
14710         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14711
14712         # LU-4201
14713         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14714         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14715 }
14716 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14717
14718 test_220() { #LU-325
14719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14720         remote_ost_nodsh && skip "remote OST with nodsh"
14721         remote_mds_nodsh && skip "remote MDS with nodsh"
14722         remote_mgs_nodsh && skip "remote MGS with nodsh"
14723
14724         local OSTIDX=0
14725
14726         # create on MDT0000 so the last_id and next_id are correct
14727         mkdir $DIR/$tdir
14728         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14729         OST=${OST%_UUID}
14730
14731         # on the mdt's osc
14732         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14733         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14734                         osc.$mdtosc_proc1.prealloc_last_id)
14735         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14736                         osc.$mdtosc_proc1.prealloc_next_id)
14737
14738         $LFS df -i
14739
14740         if ! combined_mgs_mds ; then
14741                 mount_mgs_client
14742         fi
14743
14744         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14745         #define OBD_FAIL_OST_ENOINO              0x229
14746         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14747         create_pool $FSNAME.$TESTNAME || return 1
14748         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14749
14750         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14751
14752         MDSOBJS=$((last_id - next_id))
14753         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14754
14755         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14756         echo "OST still has $count kbytes free"
14757
14758         echo "create $MDSOBJS files @next_id..."
14759         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14760
14761         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14762                         osc.$mdtosc_proc1.prealloc_last_id)
14763         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14764                         osc.$mdtosc_proc1.prealloc_next_id)
14765
14766         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14767         $LFS df -i
14768
14769         echo "cleanup..."
14770
14771         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14772         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14773
14774         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14775                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14776         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14777                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14778         echo "unlink $MDSOBJS files @$next_id..."
14779         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14780
14781         if ! combined_mgs_mds ; then
14782                 umount_mgs_client
14783         fi
14784 }
14785 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14786
14787 test_221() {
14788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14789
14790         dd if=`which date` of=$MOUNT/date oflag=sync
14791         chmod +x $MOUNT/date
14792
14793         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14794         $LCTL set_param fail_loc=0x80001401
14795
14796         $MOUNT/date > /dev/null
14797         rm -f $MOUNT/date
14798 }
14799 run_test 221 "make sure fault and truncate race to not cause OOM"
14800
14801 test_222a () {
14802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14803
14804         rm -rf $DIR/$tdir
14805         test_mkdir $DIR/$tdir
14806         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14807         createmany -o $DIR/$tdir/$tfile 10
14808         cancel_lru_locks mdc
14809         cancel_lru_locks osc
14810         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14811         $LCTL set_param fail_loc=0x31a
14812         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14813         $LCTL set_param fail_loc=0
14814         rm -r $DIR/$tdir
14815 }
14816 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14817
14818 test_222b () {
14819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14820
14821         rm -rf $DIR/$tdir
14822         test_mkdir $DIR/$tdir
14823         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14824         createmany -o $DIR/$tdir/$tfile 10
14825         cancel_lru_locks mdc
14826         cancel_lru_locks osc
14827         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14828         $LCTL set_param fail_loc=0x31a
14829         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14830         $LCTL set_param fail_loc=0
14831 }
14832 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14833
14834 test_223 () {
14835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14836
14837         rm -rf $DIR/$tdir
14838         test_mkdir $DIR/$tdir
14839         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14840         createmany -o $DIR/$tdir/$tfile 10
14841         cancel_lru_locks mdc
14842         cancel_lru_locks osc
14843         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14844         $LCTL set_param fail_loc=0x31b
14845         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14846         $LCTL set_param fail_loc=0
14847         rm -r $DIR/$tdir
14848 }
14849 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14850
14851 test_224a() { # LU-1039, MRP-303
14852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14853
14854         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14855         $LCTL set_param fail_loc=0x508
14856         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14857         $LCTL set_param fail_loc=0
14858         df $DIR
14859 }
14860 run_test 224a "Don't panic on bulk IO failure"
14861
14862 test_224b() { # LU-1039, MRP-303
14863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14864
14865         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14866         cancel_lru_locks osc
14867         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14868         $LCTL set_param fail_loc=0x515
14869         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14870         $LCTL set_param fail_loc=0
14871         df $DIR
14872 }
14873 run_test 224b "Don't panic on bulk IO failure"
14874
14875 test_224c() { # LU-6441
14876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14877         remote_mds_nodsh && skip "remote MDS with nodsh"
14878
14879         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14880         save_writethrough $p
14881         set_cache writethrough on
14882
14883         local pages_per_rpc=$($LCTL get_param \
14884                                 osc.*.max_pages_per_rpc)
14885         local at_max=$($LCTL get_param -n at_max)
14886         local timeout=$($LCTL get_param -n timeout)
14887         local test_at="at_max"
14888         local param_at="$FSNAME.sys.at_max"
14889         local test_timeout="timeout"
14890         local param_timeout="$FSNAME.sys.timeout"
14891
14892         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14893
14894         set_persistent_param_and_check client "$test_at" "$param_at" 0
14895         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14896
14897         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14898         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14899         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14900         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14901         sync
14902         do_facet ost1 "$LCTL set_param fail_loc=0"
14903
14904         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14905         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14906                 $timeout
14907
14908         $LCTL set_param -n $pages_per_rpc
14909         restore_lustre_params < $p
14910         rm -f $p
14911 }
14912 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14913
14914 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14915 test_225a () {
14916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14917         if [ -z ${MDSSURVEY} ]; then
14918                 skip_env "mds-survey not found"
14919         fi
14920         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14921                 skip "Need MDS version at least 2.2.51"
14922
14923         local mds=$(facet_host $SINGLEMDS)
14924         local target=$(do_nodes $mds 'lctl dl' |
14925                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14926
14927         local cmd1="file_count=1000 thrhi=4"
14928         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14929         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14930         local cmd="$cmd1 $cmd2 $cmd3"
14931
14932         rm -f ${TMP}/mds_survey*
14933         echo + $cmd
14934         eval $cmd || error "mds-survey with zero-stripe failed"
14935         cat ${TMP}/mds_survey*
14936         rm -f ${TMP}/mds_survey*
14937 }
14938 run_test 225a "Metadata survey sanity with zero-stripe"
14939
14940 test_225b () {
14941         if [ -z ${MDSSURVEY} ]; then
14942                 skip_env "mds-survey not found"
14943         fi
14944         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14945                 skip "Need MDS version at least 2.2.51"
14946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14947         remote_mds_nodsh && skip "remote MDS with nodsh"
14948         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14949                 skip_env "Need to mount OST to test"
14950         fi
14951
14952         local mds=$(facet_host $SINGLEMDS)
14953         local target=$(do_nodes $mds 'lctl dl' |
14954                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14955
14956         local cmd1="file_count=1000 thrhi=4"
14957         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14958         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14959         local cmd="$cmd1 $cmd2 $cmd3"
14960
14961         rm -f ${TMP}/mds_survey*
14962         echo + $cmd
14963         eval $cmd || error "mds-survey with stripe_count failed"
14964         cat ${TMP}/mds_survey*
14965         rm -f ${TMP}/mds_survey*
14966 }
14967 run_test 225b "Metadata survey sanity with stripe_count = 1"
14968
14969 mcreate_path2fid () {
14970         local mode=$1
14971         local major=$2
14972         local minor=$3
14973         local name=$4
14974         local desc=$5
14975         local path=$DIR/$tdir/$name
14976         local fid
14977         local rc
14978         local fid_path
14979
14980         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14981                 error "cannot create $desc"
14982
14983         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14984         rc=$?
14985         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14986
14987         fid_path=$($LFS fid2path $MOUNT $fid)
14988         rc=$?
14989         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14990
14991         [ "$path" == "$fid_path" ] ||
14992                 error "fid2path returned $fid_path, expected $path"
14993
14994         echo "pass with $path and $fid"
14995 }
14996
14997 test_226a () {
14998         rm -rf $DIR/$tdir
14999         mkdir -p $DIR/$tdir
15000
15001         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15002         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15003         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15004         mcreate_path2fid 0040666 0 0 dir "directory"
15005         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15006         mcreate_path2fid 0100666 0 0 file "regular file"
15007         mcreate_path2fid 0120666 0 0 link "symbolic link"
15008         mcreate_path2fid 0140666 0 0 sock "socket"
15009 }
15010 run_test 226a "call path2fid and fid2path on files of all type"
15011
15012 test_226b () {
15013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15014
15015         local MDTIDX=1
15016
15017         rm -rf $DIR/$tdir
15018         mkdir -p $DIR/$tdir
15019         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15020                 error "create remote directory failed"
15021         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15022         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15023                                 "character special file (null)"
15024         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15025                                 "character special file (no device)"
15026         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15027         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15028                                 "block special file (loop)"
15029         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15030         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15031         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15032 }
15033 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15034
15035 # LU-1299 Executing or running ldd on a truncated executable does not
15036 # cause an out-of-memory condition.
15037 test_227() {
15038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15039         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15040
15041         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15042         chmod +x $MOUNT/date
15043
15044         $MOUNT/date > /dev/null
15045         ldd $MOUNT/date > /dev/null
15046         rm -f $MOUNT/date
15047 }
15048 run_test 227 "running truncated executable does not cause OOM"
15049
15050 # LU-1512 try to reuse idle OI blocks
15051 test_228a() {
15052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15053         remote_mds_nodsh && skip "remote MDS with nodsh"
15054         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15055
15056         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15057         local myDIR=$DIR/$tdir
15058
15059         mkdir -p $myDIR
15060         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15061         $LCTL set_param fail_loc=0x80001002
15062         createmany -o $myDIR/t- 10000
15063         $LCTL set_param fail_loc=0
15064         # The guard is current the largest FID holder
15065         touch $myDIR/guard
15066         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15067                     tr -d '[')
15068         local IDX=$(($SEQ % 64))
15069
15070         do_facet $SINGLEMDS sync
15071         # Make sure journal flushed.
15072         sleep 6
15073         local blk1=$(do_facet $SINGLEMDS \
15074                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15075                      grep Blockcount | awk '{print $4}')
15076
15077         # Remove old files, some OI blocks will become idle.
15078         unlinkmany $myDIR/t- 10000
15079         # Create new files, idle OI blocks should be reused.
15080         createmany -o $myDIR/t- 2000
15081         do_facet $SINGLEMDS sync
15082         # Make sure journal flushed.
15083         sleep 6
15084         local blk2=$(do_facet $SINGLEMDS \
15085                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15086                      grep Blockcount | awk '{print $4}')
15087
15088         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15089 }
15090 run_test 228a "try to reuse idle OI blocks"
15091
15092 test_228b() {
15093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15094         remote_mds_nodsh && skip "remote MDS with nodsh"
15095         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15096
15097         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15098         local myDIR=$DIR/$tdir
15099
15100         mkdir -p $myDIR
15101         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15102         $LCTL set_param fail_loc=0x80001002
15103         createmany -o $myDIR/t- 10000
15104         $LCTL set_param fail_loc=0
15105         # The guard is current the largest FID holder
15106         touch $myDIR/guard
15107         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15108                     tr -d '[')
15109         local IDX=$(($SEQ % 64))
15110
15111         do_facet $SINGLEMDS sync
15112         # Make sure journal flushed.
15113         sleep 6
15114         local blk1=$(do_facet $SINGLEMDS \
15115                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15116                      grep Blockcount | awk '{print $4}')
15117
15118         # Remove old files, some OI blocks will become idle.
15119         unlinkmany $myDIR/t- 10000
15120
15121         # stop the MDT
15122         stop $SINGLEMDS || error "Fail to stop MDT."
15123         # remount the MDT
15124         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15125
15126         df $MOUNT || error "Fail to df."
15127         # Create new files, idle OI blocks should be reused.
15128         createmany -o $myDIR/t- 2000
15129         do_facet $SINGLEMDS sync
15130         # Make sure journal flushed.
15131         sleep 6
15132         local blk2=$(do_facet $SINGLEMDS \
15133                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15134                      grep Blockcount | awk '{print $4}')
15135
15136         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15137 }
15138 run_test 228b "idle OI blocks can be reused after MDT restart"
15139
15140 #LU-1881
15141 test_228c() {
15142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15143         remote_mds_nodsh && skip "remote MDS with nodsh"
15144         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15145
15146         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15147         local myDIR=$DIR/$tdir
15148
15149         mkdir -p $myDIR
15150         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15151         $LCTL set_param fail_loc=0x80001002
15152         # 20000 files can guarantee there are index nodes in the OI file
15153         createmany -o $myDIR/t- 20000
15154         $LCTL set_param fail_loc=0
15155         # The guard is current the largest FID holder
15156         touch $myDIR/guard
15157         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15158                     tr -d '[')
15159         local IDX=$(($SEQ % 64))
15160
15161         do_facet $SINGLEMDS sync
15162         # Make sure journal flushed.
15163         sleep 6
15164         local blk1=$(do_facet $SINGLEMDS \
15165                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15166                      grep Blockcount | awk '{print $4}')
15167
15168         # Remove old files, some OI blocks will become idle.
15169         unlinkmany $myDIR/t- 20000
15170         rm -f $myDIR/guard
15171         # The OI file should become empty now
15172
15173         # Create new files, idle OI blocks should be reused.
15174         createmany -o $myDIR/t- 2000
15175         do_facet $SINGLEMDS sync
15176         # Make sure journal flushed.
15177         sleep 6
15178         local blk2=$(do_facet $SINGLEMDS \
15179                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15180                      grep Blockcount | awk '{print $4}')
15181
15182         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15183 }
15184 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15185
15186 test_229() { # LU-2482, LU-3448
15187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15188         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15189         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15190                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15191
15192         rm -f $DIR/$tfile
15193
15194         # Create a file with a released layout and stripe count 2.
15195         $MULTIOP $DIR/$tfile H2c ||
15196                 error "failed to create file with released layout"
15197
15198         $LFS getstripe -v $DIR/$tfile
15199
15200         local pattern=$($LFS getstripe -L $DIR/$tfile)
15201         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15202
15203         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15204                 error "getstripe"
15205         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15206         stat $DIR/$tfile || error "failed to stat released file"
15207
15208         chown $RUNAS_ID $DIR/$tfile ||
15209                 error "chown $RUNAS_ID $DIR/$tfile failed"
15210
15211         chgrp $RUNAS_ID $DIR/$tfile ||
15212                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15213
15214         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15215         rm $DIR/$tfile || error "failed to remove released file"
15216 }
15217 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15218
15219 test_230a() {
15220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15222         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15223                 skip "Need MDS version at least 2.11.52"
15224
15225         local MDTIDX=1
15226
15227         test_mkdir $DIR/$tdir
15228         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15229         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15230         [ $mdt_idx -ne 0 ] &&
15231                 error "create local directory on wrong MDT $mdt_idx"
15232
15233         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15234                         error "create remote directory failed"
15235         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15236         [ $mdt_idx -ne $MDTIDX ] &&
15237                 error "create remote directory on wrong MDT $mdt_idx"
15238
15239         createmany -o $DIR/$tdir/test_230/t- 10 ||
15240                 error "create files on remote directory failed"
15241         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15242         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15243         rm -r $DIR/$tdir || error "unlink remote directory failed"
15244 }
15245 run_test 230a "Create remote directory and files under the remote directory"
15246
15247 test_230b() {
15248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15250         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15251                 skip "Need MDS version at least 2.11.52"
15252
15253         local MDTIDX=1
15254         local mdt_index
15255         local i
15256         local file
15257         local pid
15258         local stripe_count
15259         local migrate_dir=$DIR/$tdir/migrate_dir
15260         local other_dir=$DIR/$tdir/other_dir
15261
15262         test_mkdir $DIR/$tdir
15263         test_mkdir -i0 -c1 $migrate_dir
15264         test_mkdir -i0 -c1 $other_dir
15265         for ((i=0; i<10; i++)); do
15266                 mkdir -p $migrate_dir/dir_${i}
15267                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15268                         error "create files under remote dir failed $i"
15269         done
15270
15271         cp /etc/passwd $migrate_dir/$tfile
15272         cp /etc/passwd $other_dir/$tfile
15273         chattr +SAD $migrate_dir
15274         chattr +SAD $migrate_dir/$tfile
15275
15276         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15277         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15278         local old_dir_mode=$(stat -c%f $migrate_dir)
15279         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15280
15281         mkdir -p $migrate_dir/dir_default_stripe2
15282         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15283         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15284
15285         mkdir -p $other_dir
15286         ln $migrate_dir/$tfile $other_dir/luna
15287         ln $migrate_dir/$tfile $migrate_dir/sofia
15288         ln $other_dir/$tfile $migrate_dir/david
15289         ln -s $migrate_dir/$tfile $other_dir/zachary
15290         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15291         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15292
15293         $LFS migrate -m $MDTIDX $migrate_dir ||
15294                 error "fails on migrating remote dir to MDT1"
15295
15296         echo "migratate to MDT1, then checking.."
15297         for ((i = 0; i < 10; i++)); do
15298                 for file in $(find $migrate_dir/dir_${i}); do
15299                         mdt_index=$($LFS getstripe -m $file)
15300                         [ $mdt_index == $MDTIDX ] ||
15301                                 error "$file is not on MDT${MDTIDX}"
15302                 done
15303         done
15304
15305         # the multiple link file should still in MDT0
15306         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15307         [ $mdt_index == 0 ] ||
15308                 error "$file is not on MDT${MDTIDX}"
15309
15310         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15311         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15312                 error " expect $old_dir_flag get $new_dir_flag"
15313
15314         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15315         [ "$old_file_flag" = "$new_file_flag" ] ||
15316                 error " expect $old_file_flag get $new_file_flag"
15317
15318         local new_dir_mode=$(stat -c%f $migrate_dir)
15319         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15320                 error "expect mode $old_dir_mode get $new_dir_mode"
15321
15322         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15323         [ "$old_file_mode" = "$new_file_mode" ] ||
15324                 error "expect mode $old_file_mode get $new_file_mode"
15325
15326         diff /etc/passwd $migrate_dir/$tfile ||
15327                 error "$tfile different after migration"
15328
15329         diff /etc/passwd $other_dir/luna ||
15330                 error "luna different after migration"
15331
15332         diff /etc/passwd $migrate_dir/sofia ||
15333                 error "sofia different after migration"
15334
15335         diff /etc/passwd $migrate_dir/david ||
15336                 error "david different after migration"
15337
15338         diff /etc/passwd $other_dir/zachary ||
15339                 error "zachary different after migration"
15340
15341         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15342                 error "${tfile}_ln different after migration"
15343
15344         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15345                 error "${tfile}_ln_other different after migration"
15346
15347         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15348         [ $stripe_count = 2 ] ||
15349                 error "dir strpe_count $d != 2 after migration."
15350
15351         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15352         [ $stripe_count = 2 ] ||
15353                 error "file strpe_count $d != 2 after migration."
15354
15355         #migrate back to MDT0
15356         MDTIDX=0
15357
15358         $LFS migrate -m $MDTIDX $migrate_dir ||
15359                 error "fails on migrating remote dir to MDT0"
15360
15361         echo "migrate back to MDT0, checking.."
15362         for file in $(find $migrate_dir); do
15363                 mdt_index=$($LFS getstripe -m $file)
15364                 [ $mdt_index == $MDTIDX ] ||
15365                         error "$file is not on MDT${MDTIDX}"
15366         done
15367
15368         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15369         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15370                 error " expect $old_dir_flag get $new_dir_flag"
15371
15372         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15373         [ "$old_file_flag" = "$new_file_flag" ] ||
15374                 error " expect $old_file_flag get $new_file_flag"
15375
15376         local new_dir_mode=$(stat -c%f $migrate_dir)
15377         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15378                 error "expect mode $old_dir_mode get $new_dir_mode"
15379
15380         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15381         [ "$old_file_mode" = "$new_file_mode" ] ||
15382                 error "expect mode $old_file_mode get $new_file_mode"
15383
15384         diff /etc/passwd ${migrate_dir}/$tfile ||
15385                 error "$tfile different after migration"
15386
15387         diff /etc/passwd ${other_dir}/luna ||
15388                 error "luna different after migration"
15389
15390         diff /etc/passwd ${migrate_dir}/sofia ||
15391                 error "sofia different after migration"
15392
15393         diff /etc/passwd ${other_dir}/zachary ||
15394                 error "zachary different after migration"
15395
15396         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15397                 error "${tfile}_ln different after migration"
15398
15399         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15400                 error "${tfile}_ln_other different after migration"
15401
15402         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15403         [ $stripe_count = 2 ] ||
15404                 error "dir strpe_count $d != 2 after migration."
15405
15406         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15407         [ $stripe_count = 2 ] ||
15408                 error "file strpe_count $d != 2 after migration."
15409
15410         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15411 }
15412 run_test 230b "migrate directory"
15413
15414 test_230c() {
15415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15417         remote_mds_nodsh && skip "remote MDS with nodsh"
15418         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15419                 skip "Need MDS version at least 2.11.52"
15420
15421         local MDTIDX=1
15422         local total=3
15423         local mdt_index
15424         local file
15425         local migrate_dir=$DIR/$tdir/migrate_dir
15426
15427         #If migrating directory fails in the middle, all entries of
15428         #the directory is still accessiable.
15429         test_mkdir $DIR/$tdir
15430         test_mkdir -i0 -c1 $migrate_dir
15431         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15432         stat $migrate_dir
15433         createmany -o $migrate_dir/f $total ||
15434                 error "create files under ${migrate_dir} failed"
15435
15436         # fail after migrating top dir, and this will fail only once, so the
15437         # first sub file migration will fail (currently f3), others succeed.
15438         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15439         do_facet mds1 lctl set_param fail_loc=0x1801
15440         local t=$(ls $migrate_dir | wc -l)
15441         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15442                 error "migrate should fail"
15443         local u=$(ls $migrate_dir | wc -l)
15444         [ "$u" == "$t" ] || error "$u != $t during migration"
15445
15446         # add new dir/file should succeed
15447         mkdir $migrate_dir/dir ||
15448                 error "mkdir failed under migrating directory"
15449         touch $migrate_dir/file ||
15450                 error "create file failed under migrating directory"
15451
15452         # add file with existing name should fail
15453         for file in $migrate_dir/f*; do
15454                 stat $file > /dev/null || error "stat $file failed"
15455                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15456                         error "open(O_CREAT|O_EXCL) $file should fail"
15457                 $MULTIOP $file m && error "create $file should fail"
15458                 touch $DIR/$tdir/remote_dir/$tfile ||
15459                         error "touch $tfile failed"
15460                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15461                         error "link $file should fail"
15462                 mdt_index=$($LFS getstripe -m $file)
15463                 if [ $mdt_index == 0 ]; then
15464                         # file failed to migrate is not allowed to rename to
15465                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15466                                 error "rename to $file should fail"
15467                 else
15468                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15469                                 error "rename to $file failed"
15470                 fi
15471                 echo hello >> $file || error "write $file failed"
15472         done
15473
15474         # resume migration with different options should fail
15475         $LFS migrate -m 0 $migrate_dir &&
15476                 error "migrate -m 0 $migrate_dir should fail"
15477
15478         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15479                 error "migrate -c 2 $migrate_dir should fail"
15480
15481         # resume migration should succeed
15482         $LFS migrate -m $MDTIDX $migrate_dir ||
15483                 error "migrate $migrate_dir failed"
15484
15485         echo "Finish migration, then checking.."
15486         for file in $(find $migrate_dir); do
15487                 mdt_index=$($LFS getstripe -m $file)
15488                 [ $mdt_index == $MDTIDX ] ||
15489                         error "$file is not on MDT${MDTIDX}"
15490         done
15491
15492         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15493 }
15494 run_test 230c "check directory accessiblity if migration failed"
15495
15496 test_230d() {
15497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15499         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15500                 skip "Need MDS version at least 2.11.52"
15501         # LU-11235
15502         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15503
15504         local migrate_dir=$DIR/$tdir/migrate_dir
15505         local old_index
15506         local new_index
15507         local old_count
15508         local new_count
15509         local new_hash
15510         local mdt_index
15511         local i
15512         local j
15513
15514         old_index=$((RANDOM % MDSCOUNT))
15515         old_count=$((MDSCOUNT - old_index))
15516         new_index=$((RANDOM % MDSCOUNT))
15517         new_count=$((MDSCOUNT - new_index))
15518         new_hash="all_char"
15519
15520         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15521         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15522
15523         test_mkdir $DIR/$tdir
15524         test_mkdir -i $old_index -c $old_count $migrate_dir
15525
15526         for ((i=0; i<100; i++)); do
15527                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15528                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15529                         error "create files under remote dir failed $i"
15530         done
15531
15532         echo -n "Migrate from MDT$old_index "
15533         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15534         echo -n "to MDT$new_index"
15535         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15536         echo
15537
15538         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15539         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15540                 error "migrate remote dir error"
15541
15542         echo "Finish migration, then checking.."
15543         for file in $(find $migrate_dir); do
15544                 mdt_index=$($LFS getstripe -m $file)
15545                 if [ $mdt_index -lt $new_index ] ||
15546                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15547                         error "$file is on MDT$mdt_index"
15548                 fi
15549         done
15550
15551         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15552 }
15553 run_test 230d "check migrate big directory"
15554
15555 test_230e() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15558         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15559                 skip "Need MDS version at least 2.11.52"
15560
15561         local i
15562         local j
15563         local a_fid
15564         local b_fid
15565
15566         mkdir -p $DIR/$tdir
15567         mkdir $DIR/$tdir/migrate_dir
15568         mkdir $DIR/$tdir/other_dir
15569         touch $DIR/$tdir/migrate_dir/a
15570         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15571         ls $DIR/$tdir/other_dir
15572
15573         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15574                 error "migrate dir fails"
15575
15576         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15577         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15578
15579         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15580         [ $mdt_index == 0 ] || error "a is not on MDT0"
15581
15582         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15583                 error "migrate dir fails"
15584
15585         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15586         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15587
15588         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15589         [ $mdt_index == 1 ] || error "a is not on MDT1"
15590
15591         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15592         [ $mdt_index == 1 ] || error "b is not on MDT1"
15593
15594         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15595         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15596
15597         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15598
15599         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15600 }
15601 run_test 230e "migrate mulitple local link files"
15602
15603 test_230f() {
15604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15606         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15607                 skip "Need MDS version at least 2.11.52"
15608
15609         local a_fid
15610         local ln_fid
15611
15612         mkdir -p $DIR/$tdir
15613         mkdir $DIR/$tdir/migrate_dir
15614         $LFS mkdir -i1 $DIR/$tdir/other_dir
15615         touch $DIR/$tdir/migrate_dir/a
15616         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15617         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15618         ls $DIR/$tdir/other_dir
15619
15620         # a should be migrated to MDT1, since no other links on MDT0
15621         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15622                 error "#1 migrate dir fails"
15623         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15624         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15625         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15626         [ $mdt_index == 1 ] || error "a is not on MDT1"
15627
15628         # a should stay on MDT1, because it is a mulitple link file
15629         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15630                 error "#2 migrate dir fails"
15631         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15632         [ $mdt_index == 1 ] || error "a is not on MDT1"
15633
15634         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15635                 error "#3 migrate dir fails"
15636
15637         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15638         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15639         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15640
15641         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15642         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15643
15644         # a should be migrated to MDT0, since no other links on MDT1
15645         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15646                 error "#4 migrate dir fails"
15647         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15648         [ $mdt_index == 0 ] || error "a is not on MDT0"
15649
15650         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15651 }
15652 run_test 230f "migrate mulitple remote link files"
15653
15654 test_230g() {
15655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15657         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15658                 skip "Need MDS version at least 2.11.52"
15659
15660         mkdir -p $DIR/$tdir/migrate_dir
15661
15662         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15663                 error "migrating dir to non-exist MDT succeeds"
15664         true
15665 }
15666 run_test 230g "migrate dir to non-exist MDT"
15667
15668 test_230h() {
15669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15671         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15672                 skip "Need MDS version at least 2.11.52"
15673
15674         local mdt_index
15675
15676         mkdir -p $DIR/$tdir/migrate_dir
15677
15678         $LFS migrate -m1 $DIR &&
15679                 error "migrating mountpoint1 should fail"
15680
15681         $LFS migrate -m1 $DIR/$tdir/.. &&
15682                 error "migrating mountpoint2 should fail"
15683
15684         # same as mv
15685         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15686                 error "migrating $tdir/migrate_dir/.. should fail"
15687
15688         true
15689 }
15690 run_test 230h "migrate .. and root"
15691
15692 test_230i() {
15693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15695         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15696                 skip "Need MDS version at least 2.11.52"
15697
15698         mkdir -p $DIR/$tdir/migrate_dir
15699
15700         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15701                 error "migration fails with a tailing slash"
15702
15703         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15704                 error "migration fails with two tailing slashes"
15705 }
15706 run_test 230i "lfs migrate -m tolerates trailing slashes"
15707
15708 test_230j() {
15709         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15710         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15711                 skip "Need MDS version at least 2.11.52"
15712
15713         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15714         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15715                 error "create $tfile failed"
15716         cat /etc/passwd > $DIR/$tdir/$tfile
15717
15718         $LFS migrate -m 1 $DIR/$tdir
15719
15720         cmp /etc/passwd $DIR/$tdir/$tfile ||
15721                 error "DoM file mismatch after migration"
15722 }
15723 run_test 230j "DoM file data not changed after dir migration"
15724
15725 test_230k() {
15726         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15727         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15728                 skip "Need MDS version at least 2.11.56"
15729
15730         local total=20
15731         local files_on_starting_mdt=0
15732
15733         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15734         $LFS getdirstripe $DIR/$tdir
15735         for i in $(seq $total); do
15736                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15737                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15738                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15739         done
15740
15741         echo "$files_on_starting_mdt files on MDT0"
15742
15743         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15744         $LFS getdirstripe $DIR/$tdir
15745
15746         files_on_starting_mdt=0
15747         for i in $(seq $total); do
15748                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15749                         error "file $tfile.$i mismatch after migration"
15750                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15751                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15752         done
15753
15754         echo "$files_on_starting_mdt files on MDT1 after migration"
15755         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15756
15757         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15758         $LFS getdirstripe $DIR/$tdir
15759
15760         files_on_starting_mdt=0
15761         for i in $(seq $total); do
15762                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15763                         error "file $tfile.$i mismatch after 2nd migration"
15764                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15765                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15766         done
15767
15768         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15769         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15770
15771         true
15772 }
15773 run_test 230k "file data not changed after dir migration"
15774
15775 test_230l() {
15776         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15777         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15778                 skip "Need MDS version at least 2.11.56"
15779
15780         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15781         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15782                 error "create files under remote dir failed $i"
15783         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15784 }
15785 run_test 230l "readdir between MDTs won't crash"
15786
15787 test_231a()
15788 {
15789         # For simplicity this test assumes that max_pages_per_rpc
15790         # is the same across all OSCs
15791         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15792         local bulk_size=$((max_pages * PAGE_SIZE))
15793         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15794                                        head -n 1)
15795
15796         mkdir -p $DIR/$tdir
15797         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15798                 error "failed to set stripe with -S ${brw_size}M option"
15799
15800         # clear the OSC stats
15801         $LCTL set_param osc.*.stats=0 &>/dev/null
15802         stop_writeback
15803
15804         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15805         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15806                 oflag=direct &>/dev/null || error "dd failed"
15807
15808         sync; sleep 1; sync # just to be safe
15809         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15810         if [ x$nrpcs != "x1" ]; then
15811                 $LCTL get_param osc.*.stats
15812                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15813         fi
15814
15815         start_writeback
15816         # Drop the OSC cache, otherwise we will read from it
15817         cancel_lru_locks osc
15818
15819         # clear the OSC stats
15820         $LCTL set_param osc.*.stats=0 &>/dev/null
15821
15822         # Client reads $bulk_size.
15823         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15824                 iflag=direct &>/dev/null || error "dd failed"
15825
15826         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15827         if [ x$nrpcs != "x1" ]; then
15828                 $LCTL get_param osc.*.stats
15829                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15830         fi
15831 }
15832 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15833
15834 test_231b() {
15835         mkdir -p $DIR/$tdir
15836         local i
15837         for i in {0..1023}; do
15838                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15839                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15840                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15841         done
15842         sync
15843 }
15844 run_test 231b "must not assert on fully utilized OST request buffer"
15845
15846 test_232a() {
15847         mkdir -p $DIR/$tdir
15848         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15849
15850         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15851         do_facet ost1 $LCTL set_param fail_loc=0x31c
15852
15853         # ignore dd failure
15854         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15855
15856         do_facet ost1 $LCTL set_param fail_loc=0
15857         umount_client $MOUNT || error "umount failed"
15858         mount_client $MOUNT || error "mount failed"
15859         stop ost1 || error "cannot stop ost1"
15860         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15861 }
15862 run_test 232a "failed lock should not block umount"
15863
15864 test_232b() {
15865         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15866                 skip "Need MDS version at least 2.10.58"
15867
15868         mkdir -p $DIR/$tdir
15869         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15870         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15871         sync
15872         cancel_lru_locks osc
15873
15874         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15875         do_facet ost1 $LCTL set_param fail_loc=0x31c
15876
15877         # ignore failure
15878         $LFS data_version $DIR/$tdir/$tfile || true
15879
15880         do_facet ost1 $LCTL set_param fail_loc=0
15881         umount_client $MOUNT || error "umount failed"
15882         mount_client $MOUNT || error "mount failed"
15883         stop ost1 || error "cannot stop ost1"
15884         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15885 }
15886 run_test 232b "failed data version lock should not block umount"
15887
15888 test_233a() {
15889         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15890                 skip "Need MDS version at least 2.3.64"
15891         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15892
15893         local fid=$($LFS path2fid $MOUNT)
15894
15895         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15896                 error "cannot access $MOUNT using its FID '$fid'"
15897 }
15898 run_test 233a "checking that OBF of the FS root succeeds"
15899
15900 test_233b() {
15901         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15902                 skip "Need MDS version at least 2.5.90"
15903         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15904
15905         local fid=$($LFS path2fid $MOUNT/.lustre)
15906
15907         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15908                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15909
15910         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15911         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15912                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15913 }
15914 run_test 233b "checking that OBF of the FS .lustre succeeds"
15915
15916 test_234() {
15917         local p="$TMP/sanityN-$TESTNAME.parameters"
15918         save_lustre_params client "llite.*.xattr_cache" > $p
15919         lctl set_param llite.*.xattr_cache 1 ||
15920                 skip_env "xattr cache is not supported"
15921
15922         mkdir -p $DIR/$tdir || error "mkdir failed"
15923         touch $DIR/$tdir/$tfile || error "touch failed"
15924         # OBD_FAIL_LLITE_XATTR_ENOMEM
15925         $LCTL set_param fail_loc=0x1405
15926         getfattr -n user.attr $DIR/$tdir/$tfile &&
15927                 error "getfattr should have failed with ENOMEM"
15928         $LCTL set_param fail_loc=0x0
15929         rm -rf $DIR/$tdir
15930
15931         restore_lustre_params < $p
15932         rm -f $p
15933 }
15934 run_test 234 "xattr cache should not crash on ENOMEM"
15935
15936 test_235() {
15937         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15938                 skip "Need MDS version at least 2.4.52"
15939
15940         flock_deadlock $DIR/$tfile
15941         local RC=$?
15942         case $RC in
15943                 0)
15944                 ;;
15945                 124) error "process hangs on a deadlock"
15946                 ;;
15947                 *) error "error executing flock_deadlock $DIR/$tfile"
15948                 ;;
15949         esac
15950 }
15951 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15952
15953 #LU-2935
15954 test_236() {
15955         check_swap_layouts_support
15956
15957         local ref1=/etc/passwd
15958         local ref2=/etc/group
15959         local file1=$DIR/$tdir/f1
15960         local file2=$DIR/$tdir/f2
15961
15962         test_mkdir -c1 $DIR/$tdir
15963         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15964         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15965         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15966         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15967         local fd=$(free_fd)
15968         local cmd="exec $fd<>$file2"
15969         eval $cmd
15970         rm $file2
15971         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15972                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15973         cmd="exec $fd>&-"
15974         eval $cmd
15975         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15976
15977         #cleanup
15978         rm -rf $DIR/$tdir
15979 }
15980 run_test 236 "Layout swap on open unlinked file"
15981
15982 # LU-4659 linkea consistency
15983 test_238() {
15984         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15985                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15986                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15987                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15988
15989         touch $DIR/$tfile
15990         ln $DIR/$tfile $DIR/$tfile.lnk
15991         touch $DIR/$tfile.new
15992         mv $DIR/$tfile.new $DIR/$tfile
15993         local fid1=$($LFS path2fid $DIR/$tfile)
15994         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15995         local path1=$($LFS fid2path $FSNAME "$fid1")
15996         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15997         local path2=$($LFS fid2path $FSNAME "$fid2")
15998         [ $tfile.lnk == $path2 ] ||
15999                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16000         rm -f $DIR/$tfile*
16001 }
16002 run_test 238 "Verify linkea consistency"
16003
16004 test_239A() { # was test_239
16005         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16006                 skip "Need MDS version at least 2.5.60"
16007
16008         local list=$(comma_list $(mdts_nodes))
16009
16010         mkdir -p $DIR/$tdir
16011         createmany -o $DIR/$tdir/f- 5000
16012         unlinkmany $DIR/$tdir/f- 5000
16013         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16014                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16015         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16016                         osp.*MDT*.sync_in_flight" | calc_sum)
16017         [ "$changes" -eq 0 ] || error "$changes not synced"
16018 }
16019 run_test 239A "osp_sync test"
16020
16021 test_239a() { #LU-5297
16022         remote_mds_nodsh && skip "remote MDS with nodsh"
16023
16024         touch $DIR/$tfile
16025         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16026         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16027         chgrp $RUNAS_GID $DIR/$tfile
16028         wait_delete_completed
16029 }
16030 run_test 239a "process invalid osp sync record correctly"
16031
16032 test_239b() { #LU-5297
16033         remote_mds_nodsh && skip "remote MDS with nodsh"
16034
16035         touch $DIR/$tfile1
16036         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16037         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16038         chgrp $RUNAS_GID $DIR/$tfile1
16039         wait_delete_completed
16040         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16041         touch $DIR/$tfile2
16042         chgrp $RUNAS_GID $DIR/$tfile2
16043         wait_delete_completed
16044 }
16045 run_test 239b "process osp sync record with ENOMEM error correctly"
16046
16047 test_240() {
16048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16049         remote_mds_nodsh && skip "remote MDS with nodsh"
16050
16051         mkdir -p $DIR/$tdir
16052
16053         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16054                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16055         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16056                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16057
16058         umount_client $MOUNT || error "umount failed"
16059         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16060         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16061         mount_client $MOUNT || error "failed to mount client"
16062
16063         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16064         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16065 }
16066 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16067
16068 test_241_bio() {
16069         local count=$1
16070         local bsize=$2
16071
16072         for LOOP in $(seq $count); do
16073                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16074                 cancel_lru_locks $OSC || true
16075         done
16076 }
16077
16078 test_241_dio() {
16079         local count=$1
16080         local bsize=$2
16081
16082         for LOOP in $(seq $1); do
16083                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16084                         2>/dev/null
16085         done
16086 }
16087
16088 test_241a() { # was test_241
16089         local bsize=$PAGE_SIZE
16090
16091         (( bsize < 40960 )) && bsize=40960
16092         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16093         ls -la $DIR/$tfile
16094         cancel_lru_locks $OSC
16095         test_241_bio 1000 $bsize &
16096         PID=$!
16097         test_241_dio 1000 $bsize
16098         wait $PID
16099 }
16100 run_test 241a "bio vs dio"
16101
16102 test_241b() {
16103         local bsize=$PAGE_SIZE
16104
16105         (( bsize < 40960 )) && bsize=40960
16106         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16107         ls -la $DIR/$tfile
16108         test_241_dio 1000 $bsize &
16109         PID=$!
16110         test_241_dio 1000 $bsize
16111         wait $PID
16112 }
16113 run_test 241b "dio vs dio"
16114
16115 test_242() {
16116         remote_mds_nodsh && skip "remote MDS with nodsh"
16117
16118         mkdir -p $DIR/$tdir
16119         touch $DIR/$tdir/$tfile
16120
16121         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16122         do_facet mds1 lctl set_param fail_loc=0x105
16123         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16124
16125         do_facet mds1 lctl set_param fail_loc=0
16126         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16127 }
16128 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16129
16130 test_243()
16131 {
16132         test_mkdir $DIR/$tdir
16133         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16134 }
16135 run_test 243 "various group lock tests"
16136
16137 test_244()
16138 {
16139         test_mkdir $DIR/$tdir
16140         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16141         sendfile_grouplock $DIR/$tdir/$tfile || \
16142                 error "sendfile+grouplock failed"
16143         rm -rf $DIR/$tdir
16144 }
16145 run_test 244 "sendfile with group lock tests"
16146
16147 test_245() {
16148         local flagname="multi_mod_rpcs"
16149         local connect_data_name="max_mod_rpcs"
16150         local out
16151
16152         # check if multiple modify RPCs flag is set
16153         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16154                 grep "connect_flags:")
16155         echo "$out"
16156
16157         echo "$out" | grep -qw $flagname
16158         if [ $? -ne 0 ]; then
16159                 echo "connect flag $flagname is not set"
16160                 return
16161         fi
16162
16163         # check if multiple modify RPCs data is set
16164         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16165         echo "$out"
16166
16167         echo "$out" | grep -qw $connect_data_name ||
16168                 error "import should have connect data $connect_data_name"
16169 }
16170 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16171
16172 test_246() { # LU-7371
16173         remote_ost_nodsh && skip "remote OST with nodsh"
16174         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16175                 skip "Need OST version >= 2.7.62"
16176
16177         do_facet ost1 $LCTL set_param fail_val=4095
16178 #define OBD_FAIL_OST_READ_SIZE          0x234
16179         do_facet ost1 $LCTL set_param fail_loc=0x234
16180         $LFS setstripe $DIR/$tfile -i 0 -c 1
16181         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16182         cancel_lru_locks $FSNAME-OST0000
16183         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16184 }
16185 run_test 246 "Read file of size 4095 should return right length"
16186
16187 cleanup_247() {
16188         local submount=$1
16189
16190         trap 0
16191         umount_client $submount
16192         rmdir $submount
16193 }
16194
16195 test_247a() {
16196         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16197                 grep -q subtree ||
16198                 skip_env "Fileset feature is not supported"
16199
16200         local submount=${MOUNT}_$tdir
16201
16202         mkdir $MOUNT/$tdir
16203         mkdir -p $submount || error "mkdir $submount failed"
16204         FILESET="$FILESET/$tdir" mount_client $submount ||
16205                 error "mount $submount failed"
16206         trap "cleanup_247 $submount" EXIT
16207         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16208         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16209                 error "read $MOUNT/$tdir/$tfile failed"
16210         cleanup_247 $submount
16211 }
16212 run_test 247a "mount subdir as fileset"
16213
16214 test_247b() {
16215         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16216                 skip_env "Fileset feature is not supported"
16217
16218         local submount=${MOUNT}_$tdir
16219
16220         rm -rf $MOUNT/$tdir
16221         mkdir -p $submount || error "mkdir $submount failed"
16222         SKIP_FILESET=1
16223         FILESET="$FILESET/$tdir" mount_client $submount &&
16224                 error "mount $submount should fail"
16225         rmdir $submount
16226 }
16227 run_test 247b "mount subdir that dose not exist"
16228
16229 test_247c() {
16230         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16231                 skip_env "Fileset feature is not supported"
16232
16233         local submount=${MOUNT}_$tdir
16234
16235         mkdir -p $MOUNT/$tdir/dir1
16236         mkdir -p $submount || error "mkdir $submount failed"
16237         trap "cleanup_247 $submount" EXIT
16238         FILESET="$FILESET/$tdir" mount_client $submount ||
16239                 error "mount $submount failed"
16240         local fid=$($LFS path2fid $MOUNT/)
16241         $LFS fid2path $submount $fid && error "fid2path should fail"
16242         cleanup_247 $submount
16243 }
16244 run_test 247c "running fid2path outside root"
16245
16246 test_247d() {
16247         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16248                 skip "Fileset feature is not supported"
16249
16250         local submount=${MOUNT}_$tdir
16251
16252         mkdir -p $MOUNT/$tdir/dir1
16253         mkdir -p $submount || error "mkdir $submount failed"
16254         FILESET="$FILESET/$tdir" mount_client $submount ||
16255                 error "mount $submount failed"
16256         trap "cleanup_247 $submount" EXIT
16257         local fid=$($LFS path2fid $submount/dir1)
16258         $LFS fid2path $submount $fid || error "fid2path should succeed"
16259         cleanup_247 $submount
16260 }
16261 run_test 247d "running fid2path inside root"
16262
16263 # LU-8037
16264 test_247e() {
16265         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16266                 grep -q subtree ||
16267                 skip "Fileset feature is not supported"
16268
16269         local submount=${MOUNT}_$tdir
16270
16271         mkdir $MOUNT/$tdir
16272         mkdir -p $submount || error "mkdir $submount failed"
16273         FILESET="$FILESET/.." mount_client $submount &&
16274                 error "mount $submount should fail"
16275         rmdir $submount
16276 }
16277 run_test 247e "mount .. as fileset"
16278
16279 test_248() {
16280         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16281         [ -z "$fast_read_sav" ] && skip "no fast read support"
16282
16283         # create a large file for fast read verification
16284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16285
16286         # make sure the file is created correctly
16287         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16288                 { rm -f $DIR/$tfile; skip "file creation error"; }
16289
16290         echo "Test 1: verify that fast read is 4 times faster on cache read"
16291
16292         # small read with fast read enabled
16293         $LCTL set_param -n llite.*.fast_read=1
16294         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16295                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16296                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16297         # small read with fast read disabled
16298         $LCTL set_param -n llite.*.fast_read=0
16299         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16300                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16301                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16302
16303         # verify that fast read is 4 times faster for cache read
16304         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16305                 error_not_in_vm "fast read was not 4 times faster: " \
16306                            "$t_fast vs $t_slow"
16307
16308         echo "Test 2: verify the performance between big and small read"
16309         $LCTL set_param -n llite.*.fast_read=1
16310
16311         # 1k non-cache read
16312         cancel_lru_locks osc
16313         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16314                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16315                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16316
16317         # 1M non-cache read
16318         cancel_lru_locks osc
16319         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16320                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16321                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16322
16323         # verify that big IO is not 4 times faster than small IO
16324         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16325                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16326
16327         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16328         rm -f $DIR/$tfile
16329 }
16330 run_test 248 "fast read verification"
16331
16332 test_249() { # LU-7890
16333         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16334                 skip "Need at least version 2.8.54"
16335
16336         rm -f $DIR/$tfile
16337         $LFS setstripe -c 1 $DIR/$tfile
16338         # Offset 2T == 4k * 512M
16339         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16340                 error "dd to 2T offset failed"
16341 }
16342 run_test 249 "Write above 2T file size"
16343
16344 test_250() {
16345         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16346          && skip "no 16TB file size limit on ZFS"
16347
16348         $LFS setstripe -c 1 $DIR/$tfile
16349         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16350         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16351         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16352         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16353                 conv=notrunc,fsync && error "append succeeded"
16354         return 0
16355 }
16356 run_test 250 "Write above 16T limit"
16357
16358 test_251() {
16359         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16360
16361         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16362         #Skip once - writing the first stripe will succeed
16363         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16364         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16365                 error "short write happened"
16366
16367         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16368         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16369                 error "short read happened"
16370
16371         rm -f $DIR/$tfile
16372 }
16373 run_test 251 "Handling short read and write correctly"
16374
16375 test_252() {
16376         remote_mds_nodsh && skip "remote MDS with nodsh"
16377         remote_ost_nodsh && skip "remote OST with nodsh"
16378         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16379                 skip_env "ldiskfs only test"
16380         fi
16381
16382         local tgt
16383         local dev
16384         local out
16385         local uuid
16386         local num
16387         local gen
16388
16389         # check lr_reader on OST0000
16390         tgt=ost1
16391         dev=$(facet_device $tgt)
16392         out=$(do_facet $tgt $LR_READER $dev)
16393         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16394         echo "$out"
16395         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16396         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16397                 error "Invalid uuid returned by $LR_READER on target $tgt"
16398         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16399
16400         # check lr_reader -c on MDT0000
16401         tgt=mds1
16402         dev=$(facet_device $tgt)
16403         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16404                 skip "$LR_READER does not support additional options"
16405         fi
16406         out=$(do_facet $tgt $LR_READER -c $dev)
16407         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16408         echo "$out"
16409         num=$(echo "$out" | grep -c "mdtlov")
16410         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16411                 error "Invalid number of mdtlov clients returned by $LR_READER"
16412         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16413
16414         # check lr_reader -cr on MDT0000
16415         out=$(do_facet $tgt $LR_READER -cr $dev)
16416         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16417         echo "$out"
16418         echo "$out" | grep -q "^reply_data:$" ||
16419                 error "$LR_READER should have returned 'reply_data' section"
16420         num=$(echo "$out" | grep -c "client_generation")
16421         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16422 }
16423 run_test 252 "check lr_reader tool"
16424
16425 test_253_fill_ost() {
16426         local size_mb #how many MB should we write to pass watermark
16427         local lwm=$3  #low watermark
16428         local free_10mb #10% of free space
16429
16430         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16431         size_mb=$((free_kb / 1024 - lwm))
16432         free_10mb=$((free_kb / 10240))
16433         #If 10% of free space cross low watermark use it
16434         if (( free_10mb > size_mb )); then
16435                 size_mb=$free_10mb
16436         else
16437                 #At least we need to store 1.1 of difference between
16438                 #free space and low watermark
16439                 size_mb=$((size_mb + size_mb / 10))
16440         fi
16441         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16442                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16443                          oflag=append conv=notrunc
16444         fi
16445
16446         sleep_maxage
16447
16448         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16449         echo "OST still has $((free_kb / 1024)) mbytes free"
16450 }
16451
16452 test_253() {
16453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16454         remote_mds_nodsh && skip "remote MDS with nodsh"
16455         remote_mgs_nodsh && skip "remote MGS with nodsh"
16456
16457         local ostidx=0
16458         local rc=0
16459
16460         local ost_name=$($LFS osts |
16461                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16462         # on the mdt's osc
16463         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16464         do_facet $SINGLEMDS $LCTL get_param -n \
16465                 osp.$mdtosc_proc1.reserved_mb_high ||
16466                 skip  "remote MDS does not support reserved_mb_high"
16467
16468         rm -rf $DIR/$tdir
16469         wait_mds_ost_sync
16470         wait_delete_completed
16471         mkdir $DIR/$tdir
16472
16473         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16474                         osp.$mdtosc_proc1.reserved_mb_high)
16475         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16476                         osp.$mdtosc_proc1.reserved_mb_low)
16477         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16478
16479         if ! combined_mgs_mds ; then
16480                 mount_mgs_client
16481         fi
16482         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16483         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16484                 error "Adding $ost_name to pool failed"
16485
16486         # Wait for client to see a OST at pool
16487         wait_update $HOSTNAME "$LCTL get_param -n
16488                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16489                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16490                 error "Client can not see the pool"
16491         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16492                 error "Setstripe failed"
16493
16494         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16495         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16496         echo "OST still has $((blocks/1024)) mbytes free"
16497
16498         local new_lwm=$((blocks/1024-10))
16499         do_facet $SINGLEMDS $LCTL set_param \
16500                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16501         do_facet $SINGLEMDS $LCTL set_param \
16502                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16503
16504         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16505
16506         #First enospc could execute orphan deletion so repeat.
16507         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16508
16509         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16510                         osp.$mdtosc_proc1.prealloc_status)
16511         echo "prealloc_status $oa_status"
16512
16513         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16514                 error "File creation should fail"
16515         #object allocation was stopped, but we still able to append files
16516         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16517                 error "Append failed"
16518         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16519
16520         wait_delete_completed
16521
16522         sleep_maxage
16523
16524         for i in $(seq 10 12); do
16525                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16526                         error "File creation failed after rm";
16527         done
16528
16529         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16530                         osp.$mdtosc_proc1.prealloc_status)
16531         echo "prealloc_status $oa_status"
16532
16533         if (( oa_status != 0 )); then
16534                 error "Object allocation still disable after rm"
16535         fi
16536         do_facet $SINGLEMDS $LCTL set_param \
16537                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16538         do_facet $SINGLEMDS $LCTL set_param \
16539                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16540
16541
16542         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16543                 error "Remove $ost_name from pool failed"
16544         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16545                 error "Pool destroy fialed"
16546
16547         if ! combined_mgs_mds ; then
16548                 umount_mgs_client
16549         fi
16550 }
16551 run_test 253 "Check object allocation limit"
16552
16553 test_254() {
16554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16555         remote_mds_nodsh && skip "remote MDS with nodsh"
16556         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16557                 skip "MDS does not support changelog_size"
16558
16559         local cl_user
16560         local MDT0=$(facet_svc $SINGLEMDS)
16561
16562         changelog_register || error "changelog_register failed"
16563
16564         changelog_clear 0 || error "changelog_clear failed"
16565
16566         local size1=$(do_facet $SINGLEMDS \
16567                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16568         echo "Changelog size $size1"
16569
16570         rm -rf $DIR/$tdir
16571         $LFS mkdir -i 0 $DIR/$tdir
16572         # change something
16573         mkdir -p $DIR/$tdir/pics/2008/zachy
16574         touch $DIR/$tdir/pics/2008/zachy/timestamp
16575         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16576         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16577         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16578         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16579         rm $DIR/$tdir/pics/desktop.jpg
16580
16581         local size2=$(do_facet $SINGLEMDS \
16582                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16583         echo "Changelog size after work $size2"
16584
16585         (( $size2 > $size1 )) ||
16586                 error "new Changelog size=$size2 less than old size=$size1"
16587 }
16588 run_test 254 "Check changelog size"
16589
16590 ladvise_no_type()
16591 {
16592         local type=$1
16593         local file=$2
16594
16595         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16596                 awk -F: '{print $2}' | grep $type > /dev/null
16597         if [ $? -ne 0 ]; then
16598                 return 0
16599         fi
16600         return 1
16601 }
16602
16603 ladvise_no_ioctl()
16604 {
16605         local file=$1
16606
16607         lfs ladvise -a willread $file > /dev/null 2>&1
16608         if [ $? -eq 0 ]; then
16609                 return 1
16610         fi
16611
16612         lfs ladvise -a willread $file 2>&1 |
16613                 grep "Inappropriate ioctl for device" > /dev/null
16614         if [ $? -eq 0 ]; then
16615                 return 0
16616         fi
16617         return 1
16618 }
16619
16620 percent() {
16621         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16622 }
16623
16624 # run a random read IO workload
16625 # usage: random_read_iops <filename> <filesize> <iosize>
16626 random_read_iops() {
16627         local file=$1
16628         local fsize=$2
16629         local iosize=${3:-4096}
16630
16631         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16632                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16633 }
16634
16635 drop_file_oss_cache() {
16636         local file="$1"
16637         local nodes="$2"
16638
16639         $LFS ladvise -a dontneed $file 2>/dev/null ||
16640                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16641 }
16642
16643 ladvise_willread_performance()
16644 {
16645         local repeat=10
16646         local average_origin=0
16647         local average_cache=0
16648         local average_ladvise=0
16649
16650         for ((i = 1; i <= $repeat; i++)); do
16651                 echo "Iter $i/$repeat: reading without willread hint"
16652                 cancel_lru_locks osc
16653                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16654                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16655                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16656                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16657
16658                 cancel_lru_locks osc
16659                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16660                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16661                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16662
16663                 cancel_lru_locks osc
16664                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16665                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16666                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16667                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16668                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16669         done
16670         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16671         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16672         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16673
16674         speedup_cache=$(percent $average_cache $average_origin)
16675         speedup_ladvise=$(percent $average_ladvise $average_origin)
16676
16677         echo "Average uncached read: $average_origin"
16678         echo "Average speedup with OSS cached read: " \
16679                 "$average_cache = +$speedup_cache%"
16680         echo "Average speedup with ladvise willread: " \
16681                 "$average_ladvise = +$speedup_ladvise%"
16682
16683         local lowest_speedup=20
16684         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16685                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16686                         "got $average_cache%. Skipping ladvise willread check."
16687                 return 0
16688         fi
16689
16690         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16691         # it is still good to run until then to exercise 'ladvise willread'
16692         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16693                 [ "$ost1_FSTYPE" = "zfs" ] &&
16694                 echo "osd-zfs does not support dontneed or drop_caches" &&
16695                 return 0
16696
16697         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16698         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16699                 error_not_in_vm "Speedup with willread is less than " \
16700                         "$lowest_speedup%, got $average_ladvise%"
16701 }
16702
16703 test_255a() {
16704         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16705                 skip "lustre < 2.8.54 does not support ladvise "
16706         remote_ost_nodsh && skip "remote OST with nodsh"
16707
16708         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16709
16710         ladvise_no_type willread $DIR/$tfile &&
16711                 skip "willread ladvise is not supported"
16712
16713         ladvise_no_ioctl $DIR/$tfile &&
16714                 skip "ladvise ioctl is not supported"
16715
16716         local size_mb=100
16717         local size=$((size_mb * 1048576))
16718         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16719                 error "dd to $DIR/$tfile failed"
16720
16721         lfs ladvise -a willread $DIR/$tfile ||
16722                 error "Ladvise failed with no range argument"
16723
16724         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16725                 error "Ladvise failed with no -l or -e argument"
16726
16727         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16728                 error "Ladvise failed with only -e argument"
16729
16730         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16731                 error "Ladvise failed with only -l argument"
16732
16733         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16734                 error "End offset should not be smaller than start offset"
16735
16736         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16737                 error "End offset should not be equal to start offset"
16738
16739         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16740                 error "Ladvise failed with overflowing -s argument"
16741
16742         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16743                 error "Ladvise failed with overflowing -e argument"
16744
16745         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16746                 error "Ladvise failed with overflowing -l argument"
16747
16748         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16749                 error "Ladvise succeeded with conflicting -l and -e arguments"
16750
16751         echo "Synchronous ladvise should wait"
16752         local delay=4
16753 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16754         do_nodes $(comma_list $(osts_nodes)) \
16755                 $LCTL set_param fail_val=$delay fail_loc=0x237
16756
16757         local start_ts=$SECONDS
16758         lfs ladvise -a willread $DIR/$tfile ||
16759                 error "Ladvise failed with no range argument"
16760         local end_ts=$SECONDS
16761         local inteval_ts=$((end_ts - start_ts))
16762
16763         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16764                 error "Synchronous advice didn't wait reply"
16765         fi
16766
16767         echo "Asynchronous ladvise shouldn't wait"
16768         local start_ts=$SECONDS
16769         lfs ladvise -a willread -b $DIR/$tfile ||
16770                 error "Ladvise failed with no range argument"
16771         local end_ts=$SECONDS
16772         local inteval_ts=$((end_ts - start_ts))
16773
16774         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16775                 error "Asynchronous advice blocked"
16776         fi
16777
16778         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16779         ladvise_willread_performance
16780 }
16781 run_test 255a "check 'lfs ladvise -a willread'"
16782
16783 facet_meminfo() {
16784         local facet=$1
16785         local info=$2
16786
16787         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16788 }
16789
16790 test_255b() {
16791         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16792                 skip "lustre < 2.8.54 does not support ladvise "
16793         remote_ost_nodsh && skip "remote OST with nodsh"
16794
16795         lfs setstripe -c 1 -i 0 $DIR/$tfile
16796
16797         ladvise_no_type dontneed $DIR/$tfile &&
16798                 skip "dontneed ladvise is not supported"
16799
16800         ladvise_no_ioctl $DIR/$tfile &&
16801                 skip "ladvise ioctl is not supported"
16802
16803         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16804                 [ "$ost1_FSTYPE" = "zfs" ] &&
16805                 skip "zfs-osd does not support 'ladvise dontneed'"
16806
16807         local size_mb=100
16808         local size=$((size_mb * 1048576))
16809         # In order to prevent disturbance of other processes, only check 3/4
16810         # of the memory usage
16811         local kibibytes=$((size_mb * 1024 * 3 / 4))
16812
16813         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16814                 error "dd to $DIR/$tfile failed"
16815
16816         #force write to complete before dropping OST cache & checking memory
16817         sync
16818
16819         local total=$(facet_meminfo ost1 MemTotal)
16820         echo "Total memory: $total KiB"
16821
16822         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16823         local before_read=$(facet_meminfo ost1 Cached)
16824         echo "Cache used before read: $before_read KiB"
16825
16826         lfs ladvise -a willread $DIR/$tfile ||
16827                 error "Ladvise willread failed"
16828         local after_read=$(facet_meminfo ost1 Cached)
16829         echo "Cache used after read: $after_read KiB"
16830
16831         lfs ladvise -a dontneed $DIR/$tfile ||
16832                 error "Ladvise dontneed again failed"
16833         local no_read=$(facet_meminfo ost1 Cached)
16834         echo "Cache used after dontneed ladvise: $no_read KiB"
16835
16836         if [ $total -lt $((before_read + kibibytes)) ]; then
16837                 echo "Memory is too small, abort checking"
16838                 return 0
16839         fi
16840
16841         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16842                 error "Ladvise willread should use more memory" \
16843                         "than $kibibytes KiB"
16844         fi
16845
16846         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16847                 error "Ladvise dontneed should release more memory" \
16848                         "than $kibibytes KiB"
16849         fi
16850 }
16851 run_test 255b "check 'lfs ladvise -a dontneed'"
16852
16853 test_255c() {
16854         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16855                 skip "lustre < 2.10.53 does not support lockahead"
16856
16857         local count
16858         local new_count
16859         local difference
16860         local i
16861         local rc
16862
16863         test_mkdir -p $DIR/$tdir
16864         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16865
16866         #test 10 returns only success/failure
16867         i=10
16868         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16869         rc=$?
16870         if [ $rc -eq 255 ]; then
16871                 error "Ladvise test${i} failed, ${rc}"
16872         fi
16873
16874         #test 11 counts lock enqueue requests, all others count new locks
16875         i=11
16876         count=$(do_facet ost1 \
16877                 $LCTL get_param -n ost.OSS.ost.stats)
16878         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16879
16880         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16881         rc=$?
16882         if [ $rc -eq 255 ]; then
16883                 error "Ladvise test${i} failed, ${rc}"
16884         fi
16885
16886         new_count=$(do_facet ost1 \
16887                 $LCTL get_param -n ost.OSS.ost.stats)
16888         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16889                    awk '{ print $2 }')
16890
16891         difference="$((new_count - count))"
16892         if [ $difference -ne $rc ]; then
16893                 error "Ladvise test${i}, bad enqueue count, returned " \
16894                       "${rc}, actual ${difference}"
16895         fi
16896
16897         for i in $(seq 12 21); do
16898                 # If we do not do this, we run the risk of having too many
16899                 # locks and starting lock cancellation while we are checking
16900                 # lock counts.
16901                 cancel_lru_locks osc
16902
16903                 count=$($LCTL get_param -n \
16904                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16905
16906                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16907                 rc=$?
16908                 if [ $rc -eq 255 ]; then
16909                         error "Ladvise test ${i} failed, ${rc}"
16910                 fi
16911
16912                 new_count=$($LCTL get_param -n \
16913                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16914                 difference="$((new_count - count))"
16915
16916                 # Test 15 output is divided by 100 to map down to valid return
16917                 if [ $i -eq 15 ]; then
16918                         rc="$((rc * 100))"
16919                 fi
16920
16921                 if [ $difference -ne $rc ]; then
16922                         error "Ladvise test ${i}, bad lock count, returned " \
16923                               "${rc}, actual ${difference}"
16924                 fi
16925         done
16926
16927         #test 22 returns only success/failure
16928         i=22
16929         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16930         rc=$?
16931         if [ $rc -eq 255 ]; then
16932                 error "Ladvise test${i} failed, ${rc}"
16933         fi
16934 }
16935 run_test 255c "suite of ladvise lockahead tests"
16936
16937 test_256() {
16938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16939         remote_mds_nodsh && skip "remote MDS with nodsh"
16940         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16941         changelog_users $SINGLEMDS | grep "^cl" &&
16942                 skip "active changelog user"
16943
16944         local cl_user
16945         local cat_sl
16946         local mdt_dev
16947
16948         mdt_dev=$(mdsdevname 1)
16949         echo $mdt_dev
16950
16951         changelog_register || error "changelog_register failed"
16952
16953         rm -rf $DIR/$tdir
16954         mkdir -p $DIR/$tdir
16955
16956         changelog_clear 0 || error "changelog_clear failed"
16957
16958         # change something
16959         touch $DIR/$tdir/{1..10}
16960
16961         # stop the MDT
16962         stop $SINGLEMDS || error "Fail to stop MDT"
16963
16964         # remount the MDT
16965
16966         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16967
16968         #after mount new plainllog is used
16969         touch $DIR/$tdir/{11..19}
16970         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16971         cat_sl=$(do_facet $SINGLEMDS "sync; \
16972                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16973                  llog_reader $tmpfile | grep -c type=1064553b")
16974         do_facet $SINGLEMDS llog_reader $tmpfile
16975
16976         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16977
16978         changelog_clear 0 || error "changelog_clear failed"
16979
16980         cat_sl=$(do_facet $SINGLEMDS "sync; \
16981                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16982                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16983
16984         if (( cat_sl == 2 )); then
16985                 error "Empty plain llog was not deleted from changelog catalog"
16986         elif (( cat_sl != 1 )); then
16987                 error "Active plain llog shouldn't be deleted from catalog"
16988         fi
16989 }
16990 run_test 256 "Check llog delete for empty and not full state"
16991
16992 test_257() {
16993         remote_mds_nodsh && skip "remote MDS with nodsh"
16994         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16995                 skip "Need MDS version at least 2.8.55"
16996
16997         test_mkdir $DIR/$tdir
16998
16999         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17000                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17001         stat $DIR/$tdir
17002
17003 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17004         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17005         local facet=mds$((mdtidx + 1))
17006         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17007         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17008
17009         stop $facet || error "stop MDS failed"
17010         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17011                 error "start MDS fail"
17012         wait_recovery_complete $facet
17013 }
17014 run_test 257 "xattr locks are not lost"
17015
17016 # Verify we take the i_mutex when security requires it
17017 test_258a() {
17018 #define OBD_FAIL_IMUTEX_SEC 0x141c
17019         $LCTL set_param fail_loc=0x141c
17020         touch $DIR/$tfile
17021         chmod u+s $DIR/$tfile
17022         chmod a+rwx $DIR/$tfile
17023         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17024         RC=$?
17025         if [ $RC -ne 0 ]; then
17026                 error "error, failed to take i_mutex, rc=$?"
17027         fi
17028         rm -f $DIR/$tfile
17029 }
17030 run_test 258a
17031
17032 # Verify we do NOT take the i_mutex in the normal case
17033 test_258b() {
17034 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17035         $LCTL set_param fail_loc=0x141d
17036         touch $DIR/$tfile
17037         chmod a+rwx $DIR
17038         chmod a+rw $DIR/$tfile
17039         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17040         RC=$?
17041         if [ $RC -ne 0 ]; then
17042                 error "error, took i_mutex unnecessarily, rc=$?"
17043         fi
17044         rm -f $DIR/$tfile
17045
17046 }
17047 run_test 258b "verify i_mutex security behavior"
17048
17049 test_259() {
17050         local file=$DIR/$tfile
17051         local before
17052         local after
17053
17054         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17055
17056         stack_trap "rm -f $file" EXIT
17057
17058         wait_delete_completed
17059         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17060         echo "before: $before"
17061
17062         $LFS setstripe -i 0 -c 1 $file
17063         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17064         sync_all_data
17065         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17066         echo "after write: $after"
17067
17068 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17069         do_facet ost1 $LCTL set_param fail_loc=0x2301
17070         $TRUNCATE $file 0
17071         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17072         echo "after truncate: $after"
17073
17074         stop ost1
17075         do_facet ost1 $LCTL set_param fail_loc=0
17076         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17077         sleep 2
17078         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17079         echo "after restart: $after"
17080         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17081                 error "missing truncate?"
17082
17083         return 0
17084 }
17085 run_test 259 "crash at delayed truncate"
17086
17087 test_260() {
17088 #define OBD_FAIL_MDC_CLOSE               0x806
17089         $LCTL set_param fail_loc=0x80000806
17090         touch $DIR/$tfile
17091
17092 }
17093 run_test 260 "Check mdc_close fail"
17094
17095 ### Data-on-MDT sanity tests ###
17096 test_270a() {
17097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17098                 skip "Need MDS version at least 2.10.55 for DoM"
17099
17100         # create DoM file
17101         local dom=$DIR/$tdir/dom_file
17102         local tmp=$DIR/$tdir/tmp_file
17103
17104         mkdir -p $DIR/$tdir
17105
17106         # basic checks for DoM component creation
17107         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17108                 error "Can set MDT layout to non-first entry"
17109
17110         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17111                 error "Can define multiple entries as MDT layout"
17112
17113         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17114
17115         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17116         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17117         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17118
17119         local mdtidx=$($LFS getstripe -m $dom)
17120         local mdtname=MDT$(printf %04x $mdtidx)
17121         local facet=mds$((mdtidx + 1))
17122         local space_check=1
17123
17124         # Skip free space checks with ZFS
17125         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17126
17127         # write
17128         sync
17129         local size_tmp=$((65536 * 3))
17130         local mdtfree1=$(do_facet $facet \
17131                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17132
17133         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17134         # check also direct IO along write
17135         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17136         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17137         sync
17138         cmp $tmp $dom || error "file data is different"
17139         [ $(stat -c%s $dom) == $size_tmp ] ||
17140                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17141         if [ $space_check == 1 ]; then
17142                 local mdtfree2=$(do_facet $facet \
17143                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17144
17145                 # increase in usage from by $size_tmp
17146                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17147                         error "MDT free space wrong after write: " \
17148                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17149         fi
17150
17151         # truncate
17152         local size_dom=10000
17153
17154         $TRUNCATE $dom $size_dom
17155         [ $(stat -c%s $dom) == $size_dom ] ||
17156                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17157         if [ $space_check == 1 ]; then
17158                 mdtfree1=$(do_facet $facet \
17159                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17160                 # decrease in usage from $size_tmp to new $size_dom
17161                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17162                   $(((size_tmp - size_dom) / 1024)) ] ||
17163                         error "MDT free space is wrong after truncate: " \
17164                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17165         fi
17166
17167         # append
17168         cat $tmp >> $dom
17169         sync
17170         size_dom=$((size_dom + size_tmp))
17171         [ $(stat -c%s $dom) == $size_dom ] ||
17172                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17173         if [ $space_check == 1 ]; then
17174                 mdtfree2=$(do_facet $facet \
17175                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17176                 # increase in usage by $size_tmp from previous
17177                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17178                         error "MDT free space is wrong after append: " \
17179                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17180         fi
17181
17182         # delete
17183         rm $dom
17184         if [ $space_check == 1 ]; then
17185                 mdtfree1=$(do_facet $facet \
17186                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17187                 # decrease in usage by $size_dom from previous
17188                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17189                         error "MDT free space is wrong after removal: " \
17190                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17191         fi
17192
17193         # combined striping
17194         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17195                 error "Can't create DoM + OST striping"
17196
17197         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17198         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17199         # check also direct IO along write
17200         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17201         sync
17202         cmp $tmp $dom || error "file data is different"
17203         [ $(stat -c%s $dom) == $size_tmp ] ||
17204                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17205         rm $dom $tmp
17206
17207         return 0
17208 }
17209 run_test 270a "DoM: basic functionality tests"
17210
17211 test_270b() {
17212         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17213                 skip "Need MDS version at least 2.10.55"
17214
17215         local dom=$DIR/$tdir/dom_file
17216         local max_size=1048576
17217
17218         mkdir -p $DIR/$tdir
17219         $LFS setstripe -E $max_size -L mdt $dom
17220
17221         # truncate over the limit
17222         $TRUNCATE $dom $(($max_size + 1)) &&
17223                 error "successful truncate over the maximum size"
17224         # write over the limit
17225         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17226                 error "successful write over the maximum size"
17227         # append over the limit
17228         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17229         echo "12345" >> $dom && error "successful append over the maximum size"
17230         rm $dom
17231
17232         return 0
17233 }
17234 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17235
17236 test_270c() {
17237         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17238                 skip "Need MDS version at least 2.10.55"
17239
17240         mkdir -p $DIR/$tdir
17241         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17242
17243         # check files inherit DoM EA
17244         touch $DIR/$tdir/first
17245         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17246                 error "bad pattern"
17247         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17248                 error "bad stripe count"
17249         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17250                 error "bad stripe size"
17251
17252         # check directory inherits DoM EA and uses it as default
17253         mkdir $DIR/$tdir/subdir
17254         touch $DIR/$tdir/subdir/second
17255         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17256                 error "bad pattern in sub-directory"
17257         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17258                 error "bad stripe count in sub-directory"
17259         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17260                 error "bad stripe size in sub-directory"
17261         return 0
17262 }
17263 run_test 270c "DoM: DoM EA inheritance tests"
17264
17265 test_270d() {
17266         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17267                 skip "Need MDS version at least 2.10.55"
17268
17269         mkdir -p $DIR/$tdir
17270         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17271
17272         # inherit default DoM striping
17273         mkdir $DIR/$tdir/subdir
17274         touch $DIR/$tdir/subdir/f1
17275
17276         # change default directory striping
17277         $LFS setstripe -c 1 $DIR/$tdir/subdir
17278         touch $DIR/$tdir/subdir/f2
17279         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17280                 error "wrong default striping in file 2"
17281         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17282                 error "bad pattern in file 2"
17283         return 0
17284 }
17285 run_test 270d "DoM: change striping from DoM to RAID0"
17286
17287 test_270e() {
17288         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17289                 skip "Need MDS version at least 2.10.55"
17290
17291         mkdir -p $DIR/$tdir/dom
17292         mkdir -p $DIR/$tdir/norm
17293         DOMFILES=20
17294         NORMFILES=10
17295         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17296         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17297
17298         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17299         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17300
17301         # find DoM files by layout
17302         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17303         [ $NUM -eq  $DOMFILES ] ||
17304                 error "lfs find -L: found $NUM, expected $DOMFILES"
17305         echo "Test 1: lfs find 20 DOM files by layout: OK"
17306
17307         # there should be 1 dir with default DOM striping
17308         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17309         [ $NUM -eq  1 ] ||
17310                 error "lfs find -L: found $NUM, expected 1 dir"
17311         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17312
17313         # find DoM files by stripe size
17314         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17315         [ $NUM -eq  $DOMFILES ] ||
17316                 error "lfs find -S: found $NUM, expected $DOMFILES"
17317         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17318
17319         # find files by stripe offset except DoM files
17320         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17321         [ $NUM -eq  $NORMFILES ] ||
17322                 error "lfs find -i: found $NUM, expected $NORMFILES"
17323         echo "Test 5: lfs find no DOM files by stripe index: OK"
17324         return 0
17325 }
17326 run_test 270e "DoM: lfs find with DoM files test"
17327
17328 test_270f() {
17329         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17330                 skip "Need MDS version at least 2.10.55"
17331
17332         local mdtname=${FSNAME}-MDT0000-mdtlov
17333         local dom=$DIR/$tdir/dom_file
17334         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17335                                                 lod.$mdtname.dom_stripesize)
17336         local dom_limit=131072
17337
17338         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17339         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17340                                                 lod.$mdtname.dom_stripesize)
17341         [ ${dom_limit} -eq ${dom_current} ] ||
17342                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17343
17344         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17345         $LFS setstripe -d $DIR/$tdir
17346         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17347                 error "Can't set directory default striping"
17348
17349         # exceed maximum stripe size
17350         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17351                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17352         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17353                 error "Able to create DoM component size more than LOD limit"
17354
17355         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17356         dom_current=$(do_facet mds1 $LCTL get_param -n \
17357                                                 lod.$mdtname.dom_stripesize)
17358         [ 0 -eq ${dom_current} ] ||
17359                 error "Can't set zero DoM stripe limit"
17360         rm $dom
17361
17362         # attempt to create DoM file on server with disabled DoM should
17363         # remove DoM entry from layout and be succeed
17364         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17365                 error "Can't create DoM file (DoM is disabled)"
17366         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17367                 error "File has DoM component while DoM is disabled"
17368         rm $dom
17369
17370         # attempt to create DoM file with only DoM stripe should return error
17371         $LFS setstripe -E $dom_limit -L mdt $dom &&
17372                 error "Able to create DoM-only file while DoM is disabled"
17373
17374         # too low values to be aligned with smallest stripe size 64K
17375         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17376         dom_current=$(do_facet mds1 $LCTL get_param -n \
17377                                                 lod.$mdtname.dom_stripesize)
17378         [ 30000 -eq ${dom_current} ] &&
17379                 error "Can set too small DoM stripe limit"
17380
17381         # 64K is a minimal stripe size in Lustre, expect limit of that size
17382         [ 65536 -eq ${dom_current} ] ||
17383                 error "Limit is not set to 64K but ${dom_current}"
17384
17385         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17386         dom_current=$(do_facet mds1 $LCTL get_param -n \
17387                                                 lod.$mdtname.dom_stripesize)
17388         echo $dom_current
17389         [ 2147483648 -eq ${dom_current} ] &&
17390                 error "Can set too large DoM stripe limit"
17391
17392         do_facet mds1 $LCTL set_param -n \
17393                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17394         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17395                 error "Can't create DoM component size after limit change"
17396         do_facet mds1 $LCTL set_param -n \
17397                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17398         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17399                 error "Can't create DoM file after limit decrease"
17400         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17401                 error "Can create big DoM component after limit decrease"
17402         touch ${dom}_def ||
17403                 error "Can't create file with old default layout"
17404
17405         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17406         return 0
17407 }
17408 run_test 270f "DoM: maximum DoM stripe size checks"
17409
17410 test_271a() {
17411         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17412                 skip "Need MDS version at least 2.10.55"
17413
17414         local dom=$DIR/$tdir/dom
17415
17416         mkdir -p $DIR/$tdir
17417
17418         $LFS setstripe -E 1024K -L mdt $dom
17419
17420         lctl set_param -n mdc.*.stats=clear
17421         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17422         cat $dom > /dev/null
17423         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17424         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17425         ls $dom
17426         rm -f $dom
17427 }
17428 run_test 271a "DoM: data is cached for read after write"
17429
17430 test_271b() {
17431         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17432                 skip "Need MDS version at least 2.10.55"
17433
17434         local dom=$DIR/$tdir/dom
17435
17436         mkdir -p $DIR/$tdir
17437
17438         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17439
17440         lctl set_param -n mdc.*.stats=clear
17441         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17442         cancel_lru_locks mdc
17443         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17444         # second stat to check size is cached on client
17445         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17446         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17447         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17448         rm -f $dom
17449 }
17450 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17451
17452 test_271ba() {
17453         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17454                 skip "Need MDS version at least 2.10.55"
17455
17456         local dom=$DIR/$tdir/dom
17457
17458         mkdir -p $DIR/$tdir
17459
17460         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17461
17462         lctl set_param -n mdc.*.stats=clear
17463         lctl set_param -n osc.*.stats=clear
17464         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17465         cancel_lru_locks mdc
17466         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17467         # second stat to check size is cached on client
17468         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17469         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17470         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17471         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17472         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17473         rm -f $dom
17474 }
17475 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17476
17477
17478 get_mdc_stats() {
17479         local mdtidx=$1
17480         local param=$2
17481         local mdt=MDT$(printf %04x $mdtidx)
17482
17483         if [ -z $param ]; then
17484                 lctl get_param -n mdc.*$mdt*.stats
17485         else
17486                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17487         fi
17488 }
17489
17490 test_271c() {
17491         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17492                 skip "Need MDS version at least 2.10.55"
17493
17494         local dom=$DIR/$tdir/dom
17495
17496         mkdir -p $DIR/$tdir
17497
17498         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17499
17500         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17501         local facet=mds$((mdtidx + 1))
17502
17503         cancel_lru_locks mdc
17504         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17505         createmany -o $dom 1000
17506         lctl set_param -n mdc.*.stats=clear
17507         smalliomany -w $dom 1000 200
17508         get_mdc_stats $mdtidx
17509         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17510         # Each file has 1 open, 1 IO enqueues, total 2000
17511         # but now we have also +1 getxattr for security.capability, total 3000
17512         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17513         unlinkmany $dom 1000
17514
17515         cancel_lru_locks mdc
17516         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17517         createmany -o $dom 1000
17518         lctl set_param -n mdc.*.stats=clear
17519         smalliomany -w $dom 1000 200
17520         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17521         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17522         # for OPEN and IO lock.
17523         [ $((enq - enq_2)) -ge 1000 ] ||
17524                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17525         unlinkmany $dom 1000
17526         return 0
17527 }
17528 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17529
17530 cleanup_271def_tests() {
17531         trap 0
17532         rm -f $1
17533 }
17534
17535 test_271d() {
17536         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17537                 skip "Need MDS version at least 2.10.57"
17538
17539         local dom=$DIR/$tdir/dom
17540         local tmp=$TMP/$tfile
17541         trap "cleanup_271def_tests $tmp" EXIT
17542
17543         mkdir -p $DIR/$tdir
17544
17545         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17546
17547         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17548
17549         cancel_lru_locks mdc
17550         dd if=/dev/urandom of=$tmp bs=1000 count=1
17551         dd if=$tmp of=$dom bs=1000 count=1
17552         cancel_lru_locks mdc
17553
17554         cat /etc/hosts >> $tmp
17555         lctl set_param -n mdc.*.stats=clear
17556
17557         # append data to the same file it should update local page
17558         echo "Append to the same page"
17559         cat /etc/hosts >> $dom
17560         local num=$(get_mdc_stats $mdtidx ost_read)
17561         local ra=$(get_mdc_stats $mdtidx req_active)
17562         local rw=$(get_mdc_stats $mdtidx req_waittime)
17563
17564         [ -z $num ] || error "$num READ RPC occured"
17565         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17566         echo "... DONE"
17567
17568         # compare content
17569         cmp $tmp $dom || error "file miscompare"
17570
17571         cancel_lru_locks mdc
17572         lctl set_param -n mdc.*.stats=clear
17573
17574         echo "Open and read file"
17575         cat $dom > /dev/null
17576         local num=$(get_mdc_stats $mdtidx ost_read)
17577         local ra=$(get_mdc_stats $mdtidx req_active)
17578         local rw=$(get_mdc_stats $mdtidx req_waittime)
17579
17580         [ -z $num ] || error "$num READ RPC occured"
17581         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17582         echo "... DONE"
17583
17584         # compare content
17585         cmp $tmp $dom || error "file miscompare"
17586
17587         return 0
17588 }
17589 run_test 271d "DoM: read on open (1K file in reply buffer)"
17590
17591 test_271f() {
17592         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17593                 skip "Need MDS version at least 2.10.57"
17594
17595         local dom=$DIR/$tdir/dom
17596         local tmp=$TMP/$tfile
17597         trap "cleanup_271def_tests $tmp" EXIT
17598
17599         mkdir -p $DIR/$tdir
17600
17601         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17602
17603         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17604
17605         cancel_lru_locks mdc
17606         dd if=/dev/urandom of=$tmp bs=200000 count=1
17607         dd if=$tmp of=$dom bs=200000 count=1
17608         cancel_lru_locks mdc
17609         cat /etc/hosts >> $tmp
17610         lctl set_param -n mdc.*.stats=clear
17611
17612         echo "Append to the same page"
17613         cat /etc/hosts >> $dom
17614         local num=$(get_mdc_stats $mdtidx ost_read)
17615         local ra=$(get_mdc_stats $mdtidx req_active)
17616         local rw=$(get_mdc_stats $mdtidx req_waittime)
17617
17618         [ -z $num ] || error "$num READ RPC occured"
17619         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17620         echo "... DONE"
17621
17622         # compare content
17623         cmp $tmp $dom || error "file miscompare"
17624
17625         cancel_lru_locks mdc
17626         lctl set_param -n mdc.*.stats=clear
17627
17628         echo "Open and read file"
17629         cat $dom > /dev/null
17630         local num=$(get_mdc_stats $mdtidx ost_read)
17631         local ra=$(get_mdc_stats $mdtidx req_active)
17632         local rw=$(get_mdc_stats $mdtidx req_waittime)
17633
17634         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17635         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17636         echo "... DONE"
17637
17638         # compare content
17639         cmp $tmp $dom || error "file miscompare"
17640
17641         return 0
17642 }
17643 run_test 271f "DoM: read on open (200K file and read tail)"
17644
17645 test_272a() {
17646         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17647                 skip "Need MDS version at least 2.11.50"
17648
17649         local dom=$DIR/$tdir/dom
17650         mkdir -p $DIR/$tdir
17651
17652         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17653         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17654                 error "failed to write data into $dom"
17655         local old_md5=$(md5sum $dom)
17656
17657         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17658                 error "failed to migrate to the same DoM component"
17659
17660         local new_md5=$(md5sum $dom)
17661
17662         [ "$old_md5" == "$new_md5" ] ||
17663                 error "md5sum differ: $old_md5, $new_md5"
17664
17665         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17666                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17667 }
17668 run_test 272a "DoM migration: new layout with the same DOM component"
17669
17670 test_272b() {
17671         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17672                 skip "Need MDS version at least 2.11.50"
17673
17674         local dom=$DIR/$tdir/dom
17675         mkdir -p $DIR/$tdir
17676         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17677
17678         local mdtidx=$($LFS getstripe -m $dom)
17679         local mdtname=MDT$(printf %04x $mdtidx)
17680         local facet=mds$((mdtidx + 1))
17681
17682         local mdtfree1=$(do_facet $facet \
17683                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17684         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17685                 error "failed to write data into $dom"
17686         local old_md5=$(md5sum $dom)
17687         cancel_lru_locks mdc
17688         local mdtfree1=$(do_facet $facet \
17689                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17690
17691         $LFS migrate -c2 $dom ||
17692                 error "failed to migrate to the new composite layout"
17693         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17694                 error "MDT stripe was not removed"
17695
17696         cancel_lru_locks mdc
17697         local new_md5=$(md5sum $dom)
17698         [ "$old_md5" != "$new_md5" ] &&
17699                 error "$old_md5 != $new_md5"
17700
17701         # Skip free space checks with ZFS
17702         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17703                 local mdtfree2=$(do_facet $facet \
17704                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17705                 [ $mdtfree2 -gt $mdtfree1 ] ||
17706                         error "MDT space is not freed after migration"
17707         fi
17708         return 0
17709 }
17710 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17711
17712 test_272c() {
17713         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17714                 skip "Need MDS version at least 2.11.50"
17715
17716         local dom=$DIR/$tdir/$tfile
17717         mkdir -p $DIR/$tdir
17718         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17719
17720         local mdtidx=$($LFS getstripe -m $dom)
17721         local mdtname=MDT$(printf %04x $mdtidx)
17722         local facet=mds$((mdtidx + 1))
17723
17724         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17725                 error "failed to write data into $dom"
17726         local old_md5=$(md5sum $dom)
17727         cancel_lru_locks mdc
17728         local mdtfree1=$(do_facet $facet \
17729                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17730
17731         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17732                 error "failed to migrate to the new composite layout"
17733         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17734                 error "MDT stripe was not removed"
17735
17736         cancel_lru_locks mdc
17737         local new_md5=$(md5sum $dom)
17738         [ "$old_md5" != "$new_md5" ] &&
17739                 error "$old_md5 != $new_md5"
17740
17741         # Skip free space checks with ZFS
17742         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17743                 local mdtfree2=$(do_facet $facet \
17744                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17745                 [ $mdtfree2 -gt $mdtfree1 ] ||
17746                         error "MDS space is not freed after migration"
17747         fi
17748         return 0
17749 }
17750 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17751
17752 test_273a() {
17753         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17754                 skip "Need MDS version at least 2.11.50"
17755
17756         # Layout swap cannot be done if either file has DOM component,
17757         # this will never be supported, migration should be used instead
17758
17759         local dom=$DIR/$tdir/$tfile
17760         mkdir -p $DIR/$tdir
17761
17762         $LFS setstripe -c2 ${dom}_plain
17763         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17764         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17765                 error "can swap layout with DoM component"
17766         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17767                 error "can swap layout with DoM component"
17768
17769         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17770         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17771                 error "can swap layout with DoM component"
17772         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17773                 error "can swap layout with DoM component"
17774         return 0
17775 }
17776 run_test 273a "DoM: layout swapping should fail with DOM"
17777
17778 test_275() {
17779         remote_ost_nodsh && skip "remote OST with nodsh"
17780         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17781                 skip "Need OST version >= 2.10.57"
17782
17783         local file=$DIR/$tfile
17784         local oss
17785
17786         oss=$(comma_list $(osts_nodes))
17787
17788         dd if=/dev/urandom of=$file bs=1M count=2 ||
17789                 error "failed to create a file"
17790         cancel_lru_locks osc
17791
17792         #lock 1
17793         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17794                 error "failed to read a file"
17795
17796 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17797         $LCTL set_param fail_loc=0x8000031f
17798
17799         cancel_lru_locks osc &
17800         sleep 1
17801
17802 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17803         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17804         #IO takes another lock, but matches the PENDING one
17805         #and places it to the IO RPC
17806         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17807                 error "failed to read a file with PENDING lock"
17808 }
17809 run_test 275 "Read on a canceled duplicate lock"
17810
17811 test_276() {
17812         remote_ost_nodsh && skip "remote OST with nodsh"
17813         local pid
17814
17815         do_facet ost1 "(while true; do \
17816                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17817                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17818         pid=$!
17819
17820         for LOOP in $(seq 20); do
17821                 stop ost1
17822                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17823         done
17824         kill -9 $pid
17825         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17826                 rm $TMP/sanity_276_pid"
17827 }
17828 run_test 276 "Race between mount and obd_statfs"
17829
17830 cleanup_test_300() {
17831         trap 0
17832         umask $SAVE_UMASK
17833 }
17834 test_striped_dir() {
17835         local mdt_index=$1
17836         local stripe_count
17837         local stripe_index
17838
17839         mkdir -p $DIR/$tdir
17840
17841         SAVE_UMASK=$(umask)
17842         trap cleanup_test_300 RETURN EXIT
17843
17844         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17845                                                 $DIR/$tdir/striped_dir ||
17846                 error "set striped dir error"
17847
17848         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17849         [ "$mode" = "755" ] || error "expect 755 got $mode"
17850
17851         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17852                 error "getdirstripe failed"
17853         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17854         if [ "$stripe_count" != "2" ]; then
17855                 error "1:stripe_count is $stripe_count, expect 2"
17856         fi
17857         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17858         if [ "$stripe_count" != "2" ]; then
17859                 error "2:stripe_count is $stripe_count, expect 2"
17860         fi
17861
17862         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17863         if [ "$stripe_index" != "$mdt_index" ]; then
17864                 error "stripe_index is $stripe_index, expect $mdt_index"
17865         fi
17866
17867         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17868                 error "nlink error after create striped dir"
17869
17870         mkdir $DIR/$tdir/striped_dir/a
17871         mkdir $DIR/$tdir/striped_dir/b
17872
17873         stat $DIR/$tdir/striped_dir/a ||
17874                 error "create dir under striped dir failed"
17875         stat $DIR/$tdir/striped_dir/b ||
17876                 error "create dir under striped dir failed"
17877
17878         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17879                 error "nlink error after mkdir"
17880
17881         rmdir $DIR/$tdir/striped_dir/a
17882         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17883                 error "nlink error after rmdir"
17884
17885         rmdir $DIR/$tdir/striped_dir/b
17886         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17887                 error "nlink error after rmdir"
17888
17889         chattr +i $DIR/$tdir/striped_dir
17890         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17891                 error "immutable flags not working under striped dir!"
17892         chattr -i $DIR/$tdir/striped_dir
17893
17894         rmdir $DIR/$tdir/striped_dir ||
17895                 error "rmdir striped dir error"
17896
17897         cleanup_test_300
17898
17899         true
17900 }
17901
17902 test_300a() {
17903         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17904                 skip "skipped for lustre < 2.7.0"
17905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17907
17908         test_striped_dir 0 || error "failed on striped dir on MDT0"
17909         test_striped_dir 1 || error "failed on striped dir on MDT0"
17910 }
17911 run_test 300a "basic striped dir sanity test"
17912
17913 test_300b() {
17914         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17915                 skip "skipped for lustre < 2.7.0"
17916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17918
17919         local i
17920         local mtime1
17921         local mtime2
17922         local mtime3
17923
17924         test_mkdir $DIR/$tdir || error "mkdir fail"
17925         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17926                 error "set striped dir error"
17927         for i in {0..9}; do
17928                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17929                 sleep 1
17930                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17931                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17932                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17933                 sleep 1
17934                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17935                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17936                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17937         done
17938         true
17939 }
17940 run_test 300b "check ctime/mtime for striped dir"
17941
17942 test_300c() {
17943         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17944                 skip "skipped for lustre < 2.7.0"
17945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17947
17948         local file_count
17949
17950         mkdir -p $DIR/$tdir
17951         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17952                 error "set striped dir error"
17953
17954         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17955                 error "chown striped dir failed"
17956
17957         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17958                 error "create 5k files failed"
17959
17960         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17961
17962         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17963
17964         rm -rf $DIR/$tdir
17965 }
17966 run_test 300c "chown && check ls under striped directory"
17967
17968 test_300d() {
17969         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17970                 skip "skipped for lustre < 2.7.0"
17971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17973
17974         local stripe_count
17975         local file
17976
17977         mkdir -p $DIR/$tdir
17978         $LFS setstripe -c 2 $DIR/$tdir
17979
17980         #local striped directory
17981         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17982                 error "set striped dir error"
17983         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17984                 error "create 10 files failed"
17985
17986         #remote striped directory
17987         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17988                 error "set striped dir error"
17989         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17990                 error "create 10 files failed"
17991
17992         for file in $(find $DIR/$tdir); do
17993                 stripe_count=$($LFS getstripe -c $file)
17994                 [ $stripe_count -eq 2 ] ||
17995                         error "wrong stripe $stripe_count for $file"
17996         done
17997
17998         rm -rf $DIR/$tdir
17999 }
18000 run_test 300d "check default stripe under striped directory"
18001
18002 test_300e() {
18003         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18004                 skip "Need MDS version at least 2.7.55"
18005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18007
18008         local stripe_count
18009         local file
18010
18011         mkdir -p $DIR/$tdir
18012
18013         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18014                 error "set striped dir error"
18015
18016         touch $DIR/$tdir/striped_dir/a
18017         touch $DIR/$tdir/striped_dir/b
18018         touch $DIR/$tdir/striped_dir/c
18019
18020         mkdir $DIR/$tdir/striped_dir/dir_a
18021         mkdir $DIR/$tdir/striped_dir/dir_b
18022         mkdir $DIR/$tdir/striped_dir/dir_c
18023
18024         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18025                 error "set striped adir under striped dir error"
18026
18027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18028                 error "set striped bdir under striped dir error"
18029
18030         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18031                 error "set striped cdir under striped dir error"
18032
18033         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18034                 error "rename dir under striped dir fails"
18035
18036         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18037                 error "rename dir under different stripes fails"
18038
18039         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18040                 error "rename file under striped dir should succeed"
18041
18042         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18043                 error "rename dir under striped dir should succeed"
18044
18045         rm -rf $DIR/$tdir
18046 }
18047 run_test 300e "check rename under striped directory"
18048
18049 test_300f() {
18050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18052         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18053                 skip "Need MDS version at least 2.7.55"
18054
18055         local stripe_count
18056         local file
18057
18058         rm -rf $DIR/$tdir
18059         mkdir -p $DIR/$tdir
18060
18061         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18062                 error "set striped dir error"
18063
18064         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18065                 error "set striped dir error"
18066
18067         touch $DIR/$tdir/striped_dir/a
18068         mkdir $DIR/$tdir/striped_dir/dir_a
18069         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18070                 error "create striped dir under striped dir fails"
18071
18072         touch $DIR/$tdir/striped_dir1/b
18073         mkdir $DIR/$tdir/striped_dir1/dir_b
18074         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18075                 error "create striped dir under striped dir fails"
18076
18077         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18078                 error "rename dir under different striped dir should fail"
18079
18080         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18081                 error "rename striped dir under diff striped dir should fail"
18082
18083         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18084                 error "rename file under diff striped dirs fails"
18085
18086         rm -rf $DIR/$tdir
18087 }
18088 run_test 300f "check rename cross striped directory"
18089
18090 test_300_check_default_striped_dir()
18091 {
18092         local dirname=$1
18093         local default_count=$2
18094         local default_index=$3
18095         local stripe_count
18096         local stripe_index
18097         local dir_stripe_index
18098         local dir
18099
18100         echo "checking $dirname $default_count $default_index"
18101         $LFS setdirstripe -D -c $default_count -i $default_index \
18102                                 -t all_char $DIR/$tdir/$dirname ||
18103                 error "set default stripe on striped dir error"
18104         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18105         [ $stripe_count -eq $default_count ] ||
18106                 error "expect $default_count get $stripe_count for $dirname"
18107
18108         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18109         [ $stripe_index -eq $default_index ] ||
18110                 error "expect $default_index get $stripe_index for $dirname"
18111
18112         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18113                                                 error "create dirs failed"
18114
18115         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18116         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18117         for dir in $(find $DIR/$tdir/$dirname/*); do
18118                 stripe_count=$($LFS getdirstripe -c $dir)
18119                 [ $stripe_count -eq $default_count ] ||
18120                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18121                 error "stripe count $default_count != $stripe_count for $dir"
18122
18123                 stripe_index=$($LFS getdirstripe -i $dir)
18124                 [ $default_index -eq -1 ] ||
18125                         [ $stripe_index -eq $default_index ] ||
18126                         error "$stripe_index != $default_index for $dir"
18127
18128                 #check default stripe
18129                 stripe_count=$($LFS getdirstripe -D -c $dir)
18130                 [ $stripe_count -eq $default_count ] ||
18131                 error "default count $default_count != $stripe_count for $dir"
18132
18133                 stripe_index=$($LFS getdirstripe -D -i $dir)
18134                 [ $stripe_index -eq $default_index ] ||
18135                 error "default index $default_index != $stripe_index for $dir"
18136         done
18137         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18138 }
18139
18140 test_300g() {
18141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18142         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18143                 skip "Need MDS version at least 2.7.55"
18144
18145         local dir
18146         local stripe_count
18147         local stripe_index
18148
18149         mkdir $DIR/$tdir
18150         mkdir $DIR/$tdir/normal_dir
18151
18152         #Checking when client cache stripe index
18153         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18154         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18155                 error "create striped_dir failed"
18156
18157         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18158                 error "create dir0 fails"
18159         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18160         [ $stripe_index -eq 0 ] ||
18161                 error "dir0 expect index 0 got $stripe_index"
18162
18163         mkdir $DIR/$tdir/striped_dir/dir1 ||
18164                 error "create dir1 fails"
18165         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18166         [ $stripe_index -eq 1 ] ||
18167                 error "dir1 expect index 1 got $stripe_index"
18168
18169         #check default stripe count/stripe index
18170         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18171         test_300_check_default_striped_dir normal_dir 1 0
18172         test_300_check_default_striped_dir normal_dir 2 1
18173         test_300_check_default_striped_dir normal_dir 2 -1
18174
18175         #delete default stripe information
18176         echo "delete default stripeEA"
18177         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18178                 error "set default stripe on striped dir error"
18179
18180         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18181         for dir in $(find $DIR/$tdir/normal_dir/*); do
18182                 stripe_count=$($LFS getdirstripe -c $dir)
18183                 [ $stripe_count -eq 0 ] ||
18184                         error "expect 1 get $stripe_count for $dir"
18185                 stripe_index=$($LFS getdirstripe -i $dir)
18186                 [ $stripe_index -eq 0 ] ||
18187                         error "expect 0 get $stripe_index for $dir"
18188         done
18189 }
18190 run_test 300g "check default striped directory for normal directory"
18191
18192 test_300h() {
18193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18194         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18195                 skip "Need MDS version at least 2.7.55"
18196
18197         local dir
18198         local stripe_count
18199
18200         mkdir $DIR/$tdir
18201         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18202                 error "set striped dir error"
18203
18204         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18205         test_300_check_default_striped_dir striped_dir 1 0
18206         test_300_check_default_striped_dir striped_dir 2 1
18207         test_300_check_default_striped_dir striped_dir 2 -1
18208
18209         #delete default stripe information
18210         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18211                 error "set default stripe on striped dir error"
18212
18213         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18214         for dir in $(find $DIR/$tdir/striped_dir/*); do
18215                 stripe_count=$($LFS getdirstripe -c $dir)
18216                 [ $stripe_count -eq 0 ] ||
18217                         error "expect 1 get $stripe_count for $dir"
18218         done
18219 }
18220 run_test 300h "check default striped directory for striped directory"
18221
18222 test_300i() {
18223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18225         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18226                 skip "Need MDS version at least 2.7.55"
18227
18228         local stripe_count
18229         local file
18230
18231         mkdir $DIR/$tdir
18232
18233         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18234                 error "set striped dir error"
18235
18236         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18237                 error "create files under striped dir failed"
18238
18239         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18240                 error "set striped hashdir error"
18241
18242         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18243                 error "create dir0 under hash dir failed"
18244         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18245                 error "create dir1 under hash dir failed"
18246
18247         # unfortunately, we need to umount to clear dir layout cache for now
18248         # once we fully implement dir layout, we can drop this
18249         umount_client $MOUNT || error "umount failed"
18250         mount_client $MOUNT || error "mount failed"
18251
18252         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18253         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18254         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18255
18256         #set the stripe to be unknown hash type
18257         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18258         $LCTL set_param fail_loc=0x1901
18259         for ((i = 0; i < 10; i++)); do
18260                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18261                         error "stat f-$i failed"
18262                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18263         done
18264
18265         touch $DIR/$tdir/striped_dir/f0 &&
18266                 error "create under striped dir with unknown hash should fail"
18267
18268         $LCTL set_param fail_loc=0
18269
18270         umount_client $MOUNT || error "umount failed"
18271         mount_client $MOUNT || error "mount failed"
18272
18273         return 0
18274 }
18275 run_test 300i "client handle unknown hash type striped directory"
18276
18277 test_300j() {
18278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18280         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18281                 skip "Need MDS version at least 2.7.55"
18282
18283         local stripe_count
18284         local file
18285
18286         mkdir $DIR/$tdir
18287
18288         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18289         $LCTL set_param fail_loc=0x1702
18290         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18291                 error "set striped dir error"
18292
18293         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18294                 error "create files under striped dir failed"
18295
18296         $LCTL set_param fail_loc=0
18297
18298         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18299
18300         return 0
18301 }
18302 run_test 300j "test large update record"
18303
18304 test_300k() {
18305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18308                 skip "Need MDS version at least 2.7.55"
18309
18310         # this test needs a huge transaction
18311         local kb
18312         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18313         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18314
18315         local stripe_count
18316         local file
18317
18318         mkdir $DIR/$tdir
18319
18320         #define OBD_FAIL_LARGE_STRIPE   0x1703
18321         $LCTL set_param fail_loc=0x1703
18322         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18323                 error "set striped dir error"
18324         $LCTL set_param fail_loc=0
18325
18326         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18327                 error "getstripeddir fails"
18328         rm -rf $DIR/$tdir/striped_dir ||
18329                 error "unlink striped dir fails"
18330
18331         return 0
18332 }
18333 run_test 300k "test large striped directory"
18334
18335 test_300l() {
18336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18338         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18339                 skip "Need MDS version at least 2.7.55"
18340
18341         local stripe_index
18342
18343         test_mkdir -p $DIR/$tdir/striped_dir
18344         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18345                         error "chown $RUNAS_ID failed"
18346         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18347                 error "set default striped dir failed"
18348
18349         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18350         $LCTL set_param fail_loc=0x80000158
18351         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18352
18353         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18354         [ $stripe_index -eq 1 ] ||
18355                 error "expect 1 get $stripe_index for $dir"
18356 }
18357 run_test 300l "non-root user to create dir under striped dir with stale layout"
18358
18359 test_300m() {
18360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18361         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18362         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18363                 skip "Need MDS version at least 2.7.55"
18364
18365         mkdir -p $DIR/$tdir/striped_dir
18366         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18367                 error "set default stripes dir error"
18368
18369         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18370
18371         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18372         [ $stripe_count -eq 0 ] ||
18373                         error "expect 0 get $stripe_count for a"
18374
18375         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18376                 error "set default stripes dir error"
18377
18378         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18379
18380         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18381         [ $stripe_count -eq 0 ] ||
18382                         error "expect 0 get $stripe_count for b"
18383
18384         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18385                 error "set default stripes dir error"
18386
18387         mkdir $DIR/$tdir/striped_dir/c &&
18388                 error "default stripe_index is invalid, mkdir c should fails"
18389
18390         rm -rf $DIR/$tdir || error "rmdir fails"
18391 }
18392 run_test 300m "setstriped directory on single MDT FS"
18393
18394 cleanup_300n() {
18395         local list=$(comma_list $(mdts_nodes))
18396
18397         trap 0
18398         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18399 }
18400
18401 test_300n() {
18402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18404         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18405                 skip "Need MDS version at least 2.7.55"
18406         remote_mds_nodsh && skip "remote MDS with nodsh"
18407
18408         local stripe_index
18409         local list=$(comma_list $(mdts_nodes))
18410
18411         trap cleanup_300n RETURN EXIT
18412         mkdir -p $DIR/$tdir
18413         chmod 777 $DIR/$tdir
18414         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18415                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18416                 error "create striped dir succeeds with gid=0"
18417
18418         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18419         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18420                 error "create striped dir fails with gid=-1"
18421
18422         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18423         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18424                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18425                 error "set default striped dir succeeds with gid=0"
18426
18427
18428         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18429         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18430                 error "set default striped dir fails with gid=-1"
18431
18432
18433         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18434         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18435                                         error "create test_dir fails"
18436         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18437                                         error "create test_dir1 fails"
18438         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18439                                         error "create test_dir2 fails"
18440         cleanup_300n
18441 }
18442 run_test 300n "non-root user to create dir under striped dir with default EA"
18443
18444 test_300o() {
18445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18446         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18447         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18448                 skip "Need MDS version at least 2.7.55"
18449
18450         local numfree1
18451         local numfree2
18452
18453         mkdir -p $DIR/$tdir
18454
18455         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18456         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18457         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18458                 skip "not enough free inodes $numfree1 $numfree2"
18459         fi
18460
18461         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18462         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18463         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18464                 skip "not enough free space $numfree1 $numfree2"
18465         fi
18466
18467         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18468                 error "setdirstripe fails"
18469
18470         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18471                 error "create dirs fails"
18472
18473         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18474         ls $DIR/$tdir/striped_dir > /dev/null ||
18475                 error "ls striped dir fails"
18476         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18477                 error "unlink big striped dir fails"
18478 }
18479 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18480
18481 test_300p() {
18482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18484         remote_mds_nodsh && skip "remote MDS with nodsh"
18485
18486         mkdir -p $DIR/$tdir
18487
18488         #define OBD_FAIL_OUT_ENOSPC     0x1704
18489         do_facet mds2 lctl set_param fail_loc=0x80001704
18490         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18491                  && error "create striped directory should fail"
18492
18493         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18494
18495         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18496         true
18497 }
18498 run_test 300p "create striped directory without space"
18499
18500 test_300q() {
18501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18503
18504         local fd=$(free_fd)
18505         local cmd="exec $fd<$tdir"
18506         cd $DIR
18507         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18508         eval $cmd
18509         cmd="exec $fd<&-"
18510         trap "eval $cmd" EXIT
18511         cd $tdir || error "cd $tdir fails"
18512         rmdir  ../$tdir || error "rmdir $tdir fails"
18513         mkdir local_dir && error "create dir succeeds"
18514         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18515         eval $cmd
18516         return 0
18517 }
18518 run_test 300q "create remote directory under orphan directory"
18519
18520 test_300r() {
18521         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18522                 skip "Need MDS version at least 2.7.55" && return
18523         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18524
18525         mkdir $DIR/$tdir
18526
18527         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18528                 error "set striped dir error"
18529
18530         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18531                 error "getstripeddir fails"
18532
18533         local stripe_count
18534         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18535                       awk '/lmv_stripe_count:/ { print $2 }')
18536
18537         [ $MDSCOUNT -ne $stripe_count ] &&
18538                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18539
18540         rm -rf $DIR/$tdir/striped_dir ||
18541                 error "unlink striped dir fails"
18542 }
18543 run_test 300r "test -1 striped directory"
18544
18545 prepare_remote_file() {
18546         mkdir $DIR/$tdir/src_dir ||
18547                 error "create remote source failed"
18548
18549         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18550                  error "cp to remote source failed"
18551         touch $DIR/$tdir/src_dir/a
18552
18553         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18554                 error "create remote target dir failed"
18555
18556         touch $DIR/$tdir/tgt_dir/b
18557
18558         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18559                 error "rename dir cross MDT failed!"
18560
18561         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18562                 error "src_child still exists after rename"
18563
18564         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18565                 error "missing file(a) after rename"
18566
18567         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18568                 error "diff after rename"
18569 }
18570
18571 test_310a() {
18572         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18574
18575         local remote_file=$DIR/$tdir/tgt_dir/b
18576
18577         mkdir -p $DIR/$tdir
18578
18579         prepare_remote_file || error "prepare remote file failed"
18580
18581         #open-unlink file
18582         $OPENUNLINK $remote_file $remote_file ||
18583                 error "openunlink $remote_file failed"
18584         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18585 }
18586 run_test 310a "open unlink remote file"
18587
18588 test_310b() {
18589         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18591
18592         local remote_file=$DIR/$tdir/tgt_dir/b
18593
18594         mkdir -p $DIR/$tdir
18595
18596         prepare_remote_file || error "prepare remote file failed"
18597
18598         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18599         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18600         $CHECKSTAT -t file $remote_file || error "check file failed"
18601 }
18602 run_test 310b "unlink remote file with multiple links while open"
18603
18604 test_310c() {
18605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18606         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18607
18608         local remote_file=$DIR/$tdir/tgt_dir/b
18609
18610         mkdir -p $DIR/$tdir
18611
18612         prepare_remote_file || error "prepare remote file failed"
18613
18614         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18615         multiop_bg_pause $remote_file O_uc ||
18616                         error "mulitop failed for remote file"
18617         MULTIPID=$!
18618         $MULTIOP $DIR/$tfile Ouc
18619         kill -USR1 $MULTIPID
18620         wait $MULTIPID
18621 }
18622 run_test 310c "open-unlink remote file with multiple links"
18623
18624 #LU-4825
18625 test_311() {
18626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18627         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18628         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18629                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18630         remote_mds_nodsh && skip "remote MDS with nodsh"
18631
18632         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18633         local mdts=$(comma_list $(mdts_nodes))
18634
18635         mkdir -p $DIR/$tdir
18636         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18637         createmany -o $DIR/$tdir/$tfile. 1000
18638
18639         # statfs data is not real time, let's just calculate it
18640         old_iused=$((old_iused + 1000))
18641
18642         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18643                         osp.*OST0000*MDT0000.create_count")
18644         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18645                                 osp.*OST0000*MDT0000.max_create_count")
18646         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18647
18648         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18649         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18650         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18651
18652         unlinkmany $DIR/$tdir/$tfile. 1000
18653
18654         do_nodes $mdts "$LCTL set_param -n \
18655                         osp.*OST0000*.max_create_count=$max_count"
18656         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18657                 do_nodes $mdts "$LCTL set_param -n \
18658                                 osp.*OST0000*.create_count=$count"
18659         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18660                         grep "=0" && error "create_count is zero"
18661
18662         local new_iused
18663         for i in $(seq 120); do
18664                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18665                 # system may be too busy to destroy all objs in time, use
18666                 # a somewhat small value to not fail autotest
18667                 [ $((old_iused - new_iused)) -gt 400 ] && break
18668                 sleep 1
18669         done
18670
18671         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18672         [ $((old_iused - new_iused)) -gt 400 ] ||
18673                 error "objs not destroyed after unlink"
18674 }
18675 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18676
18677 zfs_oid_to_objid()
18678 {
18679         local ost=$1
18680         local objid=$2
18681
18682         local vdevdir=$(dirname $(facet_vdevice $ost))
18683         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18684         local zfs_zapid=$(do_facet $ost $cmd |
18685                           grep -w "/O/0/d$((objid%32))" -C 5 |
18686                           awk '/Object/{getline; print $1}')
18687         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18688                           awk "/$objid = /"'{printf $3}')
18689
18690         echo $zfs_objid
18691 }
18692
18693 zfs_object_blksz() {
18694         local ost=$1
18695         local objid=$2
18696
18697         local vdevdir=$(dirname $(facet_vdevice $ost))
18698         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18699         local blksz=$(do_facet $ost $cmd $objid |
18700                       awk '/dblk/{getline; printf $4}')
18701
18702         case "${blksz: -1}" in
18703                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18704                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18705                 *) ;;
18706         esac
18707
18708         echo $blksz
18709 }
18710
18711 test_312() { # LU-4856
18712         remote_ost_nodsh && skip "remote OST with nodsh"
18713         [ "$ost1_FSTYPE" = "zfs" ] ||
18714                 skip_env "the test only applies to zfs"
18715
18716         local max_blksz=$(do_facet ost1 \
18717                           $ZFS get -p recordsize $(facet_device ost1) |
18718                           awk '!/VALUE/{print $3}')
18719
18720         # to make life a little bit easier
18721         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18722         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18723
18724         local tf=$DIR/$tdir/$tfile
18725         touch $tf
18726         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18727
18728         # Get ZFS object id
18729         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18730         # block size change by sequential overwrite
18731         local bs
18732
18733         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18734                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18735
18736                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18737                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18738         done
18739         rm -f $tf
18740
18741         # block size change by sequential append write
18742         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18743         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18744         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18745         local count
18746
18747         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18748                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18749                         oflag=sync conv=notrunc
18750
18751                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18752                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18753                         error "blksz error, actual $blksz, " \
18754                                 "expected: 2 * $count * $PAGE_SIZE"
18755         done
18756         rm -f $tf
18757
18758         # random write
18759         touch $tf
18760         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18761         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18762
18763         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18764         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18765         [ $blksz -eq $PAGE_SIZE ] ||
18766                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18767
18768         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18769         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18770         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18771
18772         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18773         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18774         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18775 }
18776 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18777
18778 test_313() {
18779         remote_ost_nodsh && skip "remote OST with nodsh"
18780
18781         local file=$DIR/$tfile
18782
18783         rm -f $file
18784         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18785
18786         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18787         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18788         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18789                 error "write should failed"
18790         do_facet ost1 "$LCTL set_param fail_loc=0"
18791         rm -f $file
18792 }
18793 run_test 313 "io should fail after last_rcvd update fail"
18794
18795 test_314() {
18796         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18797
18798         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18799         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18800         rm -f $DIR/$tfile
18801         wait_delete_completed
18802         do_facet ost1 "$LCTL set_param fail_loc=0"
18803 }
18804 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18805
18806 test_315() { # LU-618
18807         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18808
18809         local file=$DIR/$tfile
18810         rm -f $file
18811
18812         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18813                 error "multiop file write failed"
18814         $MULTIOP $file oO_RDONLY:r4063232_c &
18815         PID=$!
18816
18817         sleep 2
18818
18819         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18820         kill -USR1 $PID
18821
18822         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18823         rm -f $file
18824 }
18825 run_test 315 "read should be accounted"
18826
18827 test_316() {
18828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18829         large_xattr_enabled || skip_env "ea_inode feature disabled"
18830
18831         rm -rf $DIR/$tdir/d
18832         mkdir -p $DIR/$tdir/d
18833         chown nobody $DIR/$tdir/d
18834         touch $DIR/$tdir/d/file
18835
18836         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18837 }
18838 run_test 316 "lfs mv"
18839
18840 test_317() {
18841         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18842                 skip "Need MDS version at least 2.11.53"
18843         local trunc_sz
18844         local grant_blk_size
18845
18846         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18847                 skip "LU-10370: no implementation for ZFS" && return
18848         fi
18849
18850         stack_trap "rm -f $DIR/$tfile" EXIT
18851         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18852                         awk '/grant_block_size:/ { print $2; exit; }')
18853         #
18854         # Create File of size 5M. Truncate it to below size's and verify
18855         # blocks count.
18856         #
18857         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18858                 error "Create file : $DIR/$tfile"
18859
18860         for trunc_sz in 2097152 4097 4000 509 0; do
18861                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18862                         error "truncate $tfile to $trunc_sz failed"
18863                 local sz=$(stat --format=%s $DIR/$tfile)
18864                 local blk=$(stat --format=%b $DIR/$tfile)
18865                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18866                                      grant_blk_size) * 8))
18867
18868                 if [[ $blk -ne $trunc_blk ]]; then
18869                         $(which stat) $DIR/$tfile
18870                         error "Expected Block $trunc_blk got $blk for $tfile"
18871                 fi
18872
18873                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18874                         error "Expected Size $trunc_sz got $sz for $tfile"
18875         done
18876
18877         #
18878         # sparse file test
18879         # Create file with a hole and write actual two blocks. Block count
18880         # must be 16.
18881         #
18882         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18883                 conv=fsync || error "Create file : $DIR/$tfile"
18884
18885         # Calculate the final truncate size.
18886         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18887
18888         #
18889         # truncate to size $trunc_sz bytes. Strip the last block
18890         # The block count must drop to 8
18891         #
18892         $TRUNCATE $DIR/$tfile $trunc_sz ||
18893                 error "truncate $tfile to $trunc_sz failed"
18894
18895         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18896         sz=$(stat --format=%s $DIR/$tfile)
18897         blk=$(stat --format=%b $DIR/$tfile)
18898
18899         if [[ $blk -ne $trunc_bsz ]]; then
18900                 $(which stat) $DIR/$tfile
18901                 error "Expected Block $trunc_bsz got $blk for $tfile"
18902         fi
18903
18904         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18905                 error "Expected Size $trunc_sz got $sz for $tfile"
18906 }
18907 run_test 317 "Verify blocks get correctly update after truncate"
18908
18909 test_319() {
18910         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18911
18912         local before=$(date +%s)
18913         local evict
18914         local mdir=$DIR/$tdir
18915         local file=$mdir/xxx
18916
18917         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18918         touch $file
18919
18920 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18921         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18922         $LFS mv -m1 $file &
18923
18924         sleep 1
18925         dd if=$file of=/dev/null
18926         wait
18927         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18928           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18929
18930         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18931 }
18932 run_test 319 "lost lease lock on migrate error"
18933
18934 test_fake_rw() {
18935         local read_write=$1
18936         if [ "$read_write" = "write" ]; then
18937                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18938         elif [ "$read_write" = "read" ]; then
18939                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18940         else
18941                 error "argument error"
18942         fi
18943
18944         # turn off debug for performance testing
18945         local saved_debug=$($LCTL get_param -n debug)
18946         $LCTL set_param debug=0
18947
18948         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18949
18950         # get ost1 size - lustre-OST0000
18951         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18952         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18953         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18954
18955         if [ "$read_write" = "read" ]; then
18956                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18957         fi
18958
18959         local start_time=$(date +%s.%N)
18960         $dd_cmd bs=1M count=$blocks oflag=sync ||
18961                 error "real dd $read_write error"
18962         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18963
18964         if [ "$read_write" = "write" ]; then
18965                 rm -f $DIR/$tfile
18966         fi
18967
18968         # define OBD_FAIL_OST_FAKE_RW           0x238
18969         do_facet ost1 $LCTL set_param fail_loc=0x238
18970
18971         local start_time=$(date +%s.%N)
18972         $dd_cmd bs=1M count=$blocks oflag=sync ||
18973                 error "fake dd $read_write error"
18974         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18975
18976         if [ "$read_write" = "write" ]; then
18977                 # verify file size
18978                 cancel_lru_locks osc
18979                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18980                         error "$tfile size not $blocks MB"
18981         fi
18982         do_facet ost1 $LCTL set_param fail_loc=0
18983
18984         echo "fake $read_write $duration_fake vs. normal $read_write" \
18985                 "$duration in seconds"
18986         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18987                 error_not_in_vm "fake write is slower"
18988
18989         $LCTL set_param -n debug="$saved_debug"
18990         rm -f $DIR/$tfile
18991 }
18992 test_399a() { # LU-7655 for OST fake write
18993         remote_ost_nodsh && skip "remote OST with nodsh"
18994
18995         test_fake_rw write
18996 }
18997 run_test 399a "fake write should not be slower than normal write"
18998
18999 test_399b() { # LU-8726 for OST fake read
19000         remote_ost_nodsh && skip "remote OST with nodsh"
19001         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19002                 skip_env "ldiskfs only test"
19003         fi
19004
19005         test_fake_rw read
19006 }
19007 run_test 399b "fake read should not be slower than normal read"
19008
19009 test_400a() { # LU-1606, was conf-sanity test_74
19010         if ! which $CC > /dev/null 2>&1; then
19011                 skip_env "$CC is not installed"
19012         fi
19013
19014         local extra_flags=''
19015         local out=$TMP/$tfile
19016         local prefix=/usr/include/lustre
19017         local prog
19018
19019         if ! [[ -d $prefix ]]; then
19020                 # Assume we're running in tree and fixup the include path.
19021                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19022                 extra_flags+=" -L$LUSTRE/utils/.lib"
19023         fi
19024
19025         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19026                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19027                         error "client api broken"
19028         done
19029         rm -f $out
19030 }
19031 run_test 400a "Lustre client api program can compile and link"
19032
19033 test_400b() { # LU-1606, LU-5011
19034         local header
19035         local out=$TMP/$tfile
19036         local prefix=/usr/include/linux/lustre
19037
19038         # We use a hard coded prefix so that this test will not fail
19039         # when run in tree. There are headers in lustre/include/lustre/
19040         # that are not packaged (like lustre_idl.h) and have more
19041         # complicated include dependencies (like config.h and lnet/types.h).
19042         # Since this test about correct packaging we just skip them when
19043         # they don't exist (see below) rather than try to fixup cppflags.
19044
19045         if ! which $CC > /dev/null 2>&1; then
19046                 skip_env "$CC is not installed"
19047         fi
19048
19049         for header in $prefix/*.h; do
19050                 if ! [[ -f "$header" ]]; then
19051                         continue
19052                 fi
19053
19054                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19055                         continue # lustre_ioctl.h is internal header
19056                 fi
19057
19058                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19059                         error "cannot compile '$header'"
19060         done
19061         rm -f $out
19062 }
19063 run_test 400b "packaged headers can be compiled"
19064
19065 test_401a() { #LU-7437
19066         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19067         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19068
19069         #count the number of parameters by "list_param -R"
19070         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19071         #count the number of parameters by listing proc files
19072         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19073         echo "proc_dirs='$proc_dirs'"
19074         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19075         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19076                       sort -u | wc -l)
19077
19078         [ $params -eq $procs ] ||
19079                 error "found $params parameters vs. $procs proc files"
19080
19081         # test the list_param -D option only returns directories
19082         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19083         #count the number of parameters by listing proc directories
19084         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19085                 sort -u | wc -l)
19086
19087         [ $params -eq $procs ] ||
19088                 error "found $params parameters vs. $procs proc files"
19089 }
19090 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19091
19092 test_401b() {
19093         local save=$($LCTL get_param -n jobid_var)
19094         local tmp=testing
19095
19096         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19097                 error "no error returned when setting bad parameters"
19098
19099         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19100         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19101
19102         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19103         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19104         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19105 }
19106 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19107
19108 test_401c() {
19109         local jobid_var_old=$($LCTL get_param -n jobid_var)
19110         local jobid_var_new
19111
19112         $LCTL set_param jobid_var= &&
19113                 error "no error returned for 'set_param a='"
19114
19115         jobid_var_new=$($LCTL get_param -n jobid_var)
19116         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19117                 error "jobid_var was changed by setting without value"
19118
19119         $LCTL set_param jobid_var &&
19120                 error "no error returned for 'set_param a'"
19121
19122         jobid_var_new=$($LCTL get_param -n jobid_var)
19123         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19124                 error "jobid_var was changed by setting without value"
19125 }
19126 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19127
19128 test_401d() {
19129         local jobid_var_old=$($LCTL get_param -n jobid_var)
19130         local jobid_var_new
19131         local new_value="foo=bar"
19132
19133         $LCTL set_param jobid_var=$new_value ||
19134                 error "'set_param a=b' did not accept a value containing '='"
19135
19136         jobid_var_new=$($LCTL get_param -n jobid_var)
19137         [[ "$jobid_var_new" == "$new_value" ]] ||
19138                 error "'set_param a=b' failed on a value containing '='"
19139
19140         # Reset the jobid_var to test the other format
19141         $LCTL set_param jobid_var=$jobid_var_old
19142         jobid_var_new=$($LCTL get_param -n jobid_var)
19143         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19144                 error "failed to reset jobid_var"
19145
19146         $LCTL set_param jobid_var $new_value ||
19147                 error "'set_param a b' did not accept a value containing '='"
19148
19149         jobid_var_new=$($LCTL get_param -n jobid_var)
19150         [[ "$jobid_var_new" == "$new_value" ]] ||
19151                 error "'set_param a b' failed on a value containing '='"
19152
19153         $LCTL set_param jobid_var $jobid_var_old
19154         jobid_var_new=$($LCTL get_param -n jobid_var)
19155         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19156                 error "failed to reset jobid_var"
19157 }
19158 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19159
19160 test_402() {
19161         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19162         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19163                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19164         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19165                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19166                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19167         remote_mds_nodsh && skip "remote MDS with nodsh"
19168
19169         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19170 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19171         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19172         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19173                 echo "Touch failed - OK"
19174 }
19175 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19176
19177 test_403() {
19178         local file1=$DIR/$tfile.1
19179         local file2=$DIR/$tfile.2
19180         local tfile=$TMP/$tfile
19181
19182         rm -f $file1 $file2 $tfile
19183
19184         touch $file1
19185         ln $file1 $file2
19186
19187         # 30 sec OBD_TIMEOUT in ll_getattr()
19188         # right before populating st_nlink
19189         $LCTL set_param fail_loc=0x80001409
19190         stat -c %h $file1 > $tfile &
19191
19192         # create an alias, drop all locks and reclaim the dentry
19193         < $file2
19194         cancel_lru_locks mdc
19195         cancel_lru_locks osc
19196         sysctl -w vm.drop_caches=2
19197
19198         wait
19199
19200         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19201
19202         rm -f $tfile $file1 $file2
19203 }
19204 run_test 403 "i_nlink should not drop to zero due to aliasing"
19205
19206 test_404() { # LU-6601
19207         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19208                 skip "Need server version newer than 2.8.52"
19209         remote_mds_nodsh && skip "remote MDS with nodsh"
19210
19211         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19212                 awk '/osp .*-osc-MDT/ { print $4}')
19213
19214         local osp
19215         for osp in $mosps; do
19216                 echo "Deactivate: " $osp
19217                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19218                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19219                         awk -vp=$osp '$4 == p { print $2 }')
19220                 [ $stat = IN ] || {
19221                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19222                         error "deactivate error"
19223                 }
19224                 echo "Activate: " $osp
19225                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19226                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19227                         awk -vp=$osp '$4 == p { print $2 }')
19228                 [ $stat = UP ] || {
19229                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19230                         error "activate error"
19231                 }
19232         done
19233 }
19234 run_test 404 "validate manual {de}activated works properly for OSPs"
19235
19236 test_405() {
19237         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19238         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19239                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19240                         skip "Layout swap lock is not supported"
19241
19242         check_swap_layouts_support
19243
19244         test_mkdir $DIR/$tdir
19245         swap_lock_test -d $DIR/$tdir ||
19246                 error "One layout swap locked test failed"
19247 }
19248 run_test 405 "Various layout swap lock tests"
19249
19250 test_406() {
19251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19252         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19253         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19255         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19256                 skip "Need MDS version at least 2.8.50"
19257
19258         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19259         local test_pool=$TESTNAME
19260
19261         if ! combined_mgs_mds ; then
19262                 mount_mgs_client
19263         fi
19264         pool_add $test_pool || error "pool_add failed"
19265         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19266                 error "pool_add_targets failed"
19267
19268         save_layout_restore_at_exit $MOUNT
19269
19270         # parent set default stripe count only, child will stripe from both
19271         # parent and fs default
19272         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19273                 error "setstripe $MOUNT failed"
19274         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19275         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19276         for i in $(seq 10); do
19277                 local f=$DIR/$tdir/$tfile.$i
19278                 touch $f || error "touch failed"
19279                 local count=$($LFS getstripe -c $f)
19280                 [ $count -eq $OSTCOUNT ] ||
19281                         error "$f stripe count $count != $OSTCOUNT"
19282                 local offset=$($LFS getstripe -i $f)
19283                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19284                 local size=$($LFS getstripe -S $f)
19285                 [ $size -eq $((def_stripe_size * 2)) ] ||
19286                         error "$f stripe size $size != $((def_stripe_size * 2))"
19287                 local pool=$($LFS getstripe -p $f)
19288                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19289         done
19290
19291         # change fs default striping, delete parent default striping, now child
19292         # will stripe from new fs default striping only
19293         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19294                 error "change $MOUNT default stripe failed"
19295         $LFS setstripe -c 0 $DIR/$tdir ||
19296                 error "delete $tdir default stripe failed"
19297         for i in $(seq 11 20); do
19298                 local f=$DIR/$tdir/$tfile.$i
19299                 touch $f || error "touch $f failed"
19300                 local count=$($LFS getstripe -c $f)
19301                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19302                 local offset=$($LFS getstripe -i $f)
19303                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19304                 local size=$($LFS getstripe -S $f)
19305                 [ $size -eq $def_stripe_size ] ||
19306                         error "$f stripe size $size != $def_stripe_size"
19307                 local pool=$($LFS getstripe -p $f)
19308                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19309         done
19310
19311         unlinkmany $DIR/$tdir/$tfile. 1 20
19312
19313         local f=$DIR/$tdir/$tfile
19314         pool_remove_all_targets $test_pool $f
19315         pool_remove $test_pool $f
19316
19317         if ! combined_mgs_mds ; then
19318                 umount_mgs_client
19319         fi
19320 }
19321 run_test 406 "DNE support fs default striping"
19322
19323 test_407() {
19324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19325         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19326                 skip "Need MDS version at least 2.8.55"
19327         remote_mds_nodsh && skip "remote MDS with nodsh"
19328
19329         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19330                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19331         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19332                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19333         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19334
19335         #define OBD_FAIL_DT_TXN_STOP    0x2019
19336         for idx in $(seq $MDSCOUNT); do
19337                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19338         done
19339         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19340         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19341                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19342         true
19343 }
19344 run_test 407 "transaction fail should cause operation fail"
19345
19346 test_408() {
19347         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19348
19349         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19350         lctl set_param fail_loc=0x8000040a
19351         # let ll_prepare_partial_page() fail
19352         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19353
19354         rm -f $DIR/$tfile
19355
19356         # create at least 100 unused inodes so that
19357         # shrink_icache_memory(0) should not return 0
19358         touch $DIR/$tfile-{0..100}
19359         rm -f $DIR/$tfile-{0..100}
19360         sync
19361
19362         echo 2 > /proc/sys/vm/drop_caches
19363 }
19364 run_test 408 "drop_caches should not hang due to page leaks"
19365
19366 test_409()
19367 {
19368         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19369
19370         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19371         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19372         touch $DIR/$tdir/guard || error "(2) Fail to create"
19373
19374         local PREFIX=$(str_repeat 'A' 128)
19375         echo "Create 1K hard links start at $(date)"
19376         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19377                 error "(3) Fail to hard link"
19378
19379         echo "Links count should be right although linkEA overflow"
19380         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19381         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19382         [ $linkcount -eq 1001 ] ||
19383                 error "(5) Unexpected hard links count: $linkcount"
19384
19385         echo "List all links start at $(date)"
19386         ls -l $DIR/$tdir/foo > /dev/null ||
19387                 error "(6) Fail to list $DIR/$tdir/foo"
19388
19389         echo "Unlink hard links start at $(date)"
19390         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19391                 error "(7) Fail to unlink"
19392         echo "Unlink hard links finished at $(date)"
19393 }
19394 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19395
19396 test_410()
19397 {
19398         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19399                 skip "Need client version at least 2.9.59"
19400
19401         # Create a file, and stat it from the kernel
19402         local testfile=$DIR/$tfile
19403         touch $testfile
19404
19405         local run_id=$RANDOM
19406         local my_ino=$(stat --format "%i" $testfile)
19407
19408         # Try to insert the module. This will always fail as the
19409         # module is designed to not be inserted.
19410         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19411             &> /dev/null
19412
19413         # Anything but success is a test failure
19414         dmesg | grep -q \
19415             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19416             error "no inode match"
19417 }
19418 run_test 410 "Test inode number returned from kernel thread"
19419
19420 cleanup_test411_cgroup() {
19421         trap 0
19422         rmdir "$1"
19423 }
19424
19425 test_411() {
19426         local cg_basedir=/sys/fs/cgroup/memory
19427         # LU-9966
19428         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19429                 skip "no setup for cgroup"
19430
19431         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19432                 error "test file creation failed"
19433         cancel_lru_locks osc
19434
19435         # Create a very small memory cgroup to force a slab allocation error
19436         local cgdir=$cg_basedir/osc_slab_alloc
19437         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19438         trap "cleanup_test411_cgroup $cgdir" EXIT
19439         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19440         echo 1M > $cgdir/memory.limit_in_bytes
19441
19442         # Should not LBUG, just be killed by oom-killer
19443         # dd will return 0 even allocation failure in some environment.
19444         # So don't check return value
19445         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19446         cleanup_test411_cgroup $cgdir
19447
19448         return 0
19449 }
19450 run_test 411 "Slab allocation error with cgroup does not LBUG"
19451
19452 test_412() {
19453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19454         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19455                 skip "Need server version at least 2.10.55"
19456         fi
19457
19458         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19459                 error "mkdir failed"
19460         $LFS getdirstripe $DIR/$tdir
19461         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19462         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19463                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19464         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19465         [ $stripe_count -eq 2 ] ||
19466                 error "expect 2 get $stripe_count"
19467 }
19468 run_test 412 "mkdir on specific MDTs"
19469
19470 test_413() {
19471         [ $MDSCOUNT -lt 2 ] &&
19472                 skip "We need at least 2 MDTs for this test"
19473
19474         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19475                 skip "Need server version at least 2.10.55"
19476         fi
19477
19478         mkdir $DIR/$tdir || error "mkdir failed"
19479
19480         # find MDT that is the most full
19481         local max=$($LFS df | grep MDT |
19482                 awk 'BEGIN { a=0 }
19483                         { sub("%", "", $5)
19484                           if (0+$5 >= a)
19485                           {
19486                                 a = $5
19487                                 b = $6
19488                           }
19489                         }
19490                      END { split(b, c, ":")
19491                            sub("]", "", c[2])
19492                            print c[2]
19493                          }')
19494
19495         for i in $(seq $((MDSCOUNT - 1))); do
19496                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19497                         error "mkdir d$i failed"
19498                 $LFS getdirstripe $DIR/$tdir/d$i
19499                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19500                 [ $stripe_index -ne $max ] ||
19501                         error "don't expect $max"
19502         done
19503 }
19504 run_test 413 "mkdir on less full MDTs"
19505
19506 test_414() {
19507 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19508         $LCTL set_param fail_loc=0x80000521
19509         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19510         rm -f $DIR/$tfile
19511 }
19512 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19513
19514 test_415() {
19515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19516         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19517                 skip "Need server version at least 2.11.52"
19518
19519         # LU-11102
19520         local total
19521         local setattr_pid
19522         local start_time
19523         local end_time
19524         local duration
19525
19526         total=500
19527         # this test may be slow on ZFS
19528         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19529
19530         # though this test is designed for striped directory, let's test normal
19531         # directory too since lock is always saved as CoS lock.
19532         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19533         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19534
19535         (
19536                 while true; do
19537                         touch $DIR/$tdir
19538                 done
19539         ) &
19540         setattr_pid=$!
19541
19542         start_time=$(date +%s)
19543         for i in $(seq $total); do
19544                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19545                         > /dev/null
19546         done
19547         end_time=$(date +%s)
19548         duration=$((end_time - start_time))
19549
19550         kill -9 $setattr_pid
19551
19552         echo "rename $total files took $duration sec"
19553         [ $duration -lt 100 ] || error "rename took $duration sec"
19554 }
19555 run_test 415 "lock revoke is not missing"
19556
19557 test_416() {
19558         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19559                 skip "Need server version at least 2.11.55"
19560
19561         # define OBD_FAIL_OSD_TXN_START    0x19a
19562         do_facet mds1 lctl set_param fail_loc=0x19a
19563
19564         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19565
19566         true
19567 }
19568 run_test 416 "transaction start failure won't cause system hung"
19569
19570 cleanup_417() {
19571         trap 0
19572         do_nodes $(comma_list $(mdts_nodes)) \
19573                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19574         do_nodes $(comma_list $(mdts_nodes)) \
19575                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19576         do_nodes $(comma_list $(mdts_nodes)) \
19577                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19578 }
19579
19580 test_417() {
19581         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19582         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19583                 skip "Need MDS version at least 2.11.56"
19584
19585         trap cleanup_417 RETURN EXIT
19586
19587         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19588         do_nodes $(comma_list $(mdts_nodes)) \
19589                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19590         $LFS migrate -m 0 $DIR/$tdir.1 &&
19591                 error "migrate dir $tdir.1 should fail"
19592
19593         do_nodes $(comma_list $(mdts_nodes)) \
19594                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19595         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19596                 error "create remote dir $tdir.2 should fail"
19597
19598         do_nodes $(comma_list $(mdts_nodes)) \
19599                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19600         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19601                 error "create striped dir $tdir.3 should fail"
19602         true
19603 }
19604 run_test 417 "disable remote dir, striped dir and dir migration"
19605
19606 # Checks that the outputs of df [-i] and lfs df [-i] match
19607 #
19608 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19609 check_lfs_df() {
19610         local dir=$2
19611         local inodes
19612         local df_out
19613         local lfs_df_out
19614         local count
19615         local passed=false
19616
19617         # blocks or inodes
19618         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19619
19620         for count in {1..100}; do
19621                 cancel_lru_locks
19622                 sync; sleep 0.2
19623
19624                 # read the lines of interest
19625                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19626                         error "df $inodes $dir | tail -n +2 failed"
19627                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19628                         error "lfs df $inodes $dir | grep summary: failed"
19629
19630                 # skip first substrings of each output as they are different
19631                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19632                 # compare the two outputs
19633                 passed=true
19634                 for i in {1..5}; do
19635                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19636                 done
19637                 $passed && break
19638         done
19639
19640         if ! $passed; then
19641                 df -P $inodes $dir
19642                 echo
19643                 lfs df $inodes $dir
19644                 error "df and lfs df $1 output mismatch: "      \
19645                       "df ${inodes}: ${df_out[*]}, "            \
19646                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19647         fi
19648 }
19649
19650 test_418() {
19651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19652
19653         local dir=$DIR/$tdir
19654         local numfiles=$((RANDOM % 4096 + 2))
19655         local numblocks=$((RANDOM % 256 + 1))
19656
19657         wait_delete_completed
19658         test_mkdir $dir
19659
19660         # check block output
19661         check_lfs_df blocks $dir
19662         # check inode output
19663         check_lfs_df inodes $dir
19664
19665         # create a single file and retest
19666         echo "Creating a single file and testing"
19667         createmany -o $dir/$tfile- 1 &>/dev/null ||
19668                 error "creating 1 file in $dir failed"
19669         check_lfs_df blocks $dir
19670         check_lfs_df inodes $dir
19671
19672         # create a random number of files
19673         echo "Creating $((numfiles - 1)) files and testing"
19674         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19675                 error "creating $((numfiles - 1)) files in $dir failed"
19676
19677         # write a random number of blocks to the first test file
19678         echo "Writing $numblocks 4K blocks and testing"
19679         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19680                 count=$numblocks &>/dev/null ||
19681                 error "dd to $dir/${tfile}-0 failed"
19682
19683         # retest
19684         check_lfs_df blocks $dir
19685         check_lfs_df inodes $dir
19686
19687         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19688                 error "unlinking $numfiles files in $dir failed"
19689 }
19690 run_test 418 "df and lfs df outputs match"
19691
19692 test_419()
19693 {
19694         local dir=$DIR/$tdir
19695
19696         mkdir -p $dir
19697         touch $dir/file
19698
19699         cancel_lru_locks mdc
19700
19701         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19702         $LCTL set_param fail_loc=0x1410
19703         cat $dir/file
19704         $LCTL set_param fail_loc=0
19705         rm -rf $dir
19706 }
19707 run_test 419 "Verify open file by name doesn't crash kernel"
19708
19709 prep_801() {
19710         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19711         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19712                 skip "Need server version at least 2.9.55"
19713
19714         start_full_debug_logging
19715 }
19716
19717 post_801() {
19718         stop_full_debug_logging
19719 }
19720
19721 barrier_stat() {
19722         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19723                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19724                            awk '/The barrier for/ { print $7 }')
19725                 echo $st
19726         else
19727                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19728                 echo \'$st\'
19729         fi
19730 }
19731
19732 barrier_expired() {
19733         local expired
19734
19735         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19736                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19737                           awk '/will be expired/ { print $7 }')
19738         else
19739                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19740         fi
19741
19742         echo $expired
19743 }
19744
19745 test_801a() {
19746         prep_801
19747
19748         echo "Start barrier_freeze at: $(date)"
19749         #define OBD_FAIL_BARRIER_DELAY          0x2202
19750         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19751         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19752
19753         sleep 2
19754         local b_status=$(barrier_stat)
19755         echo "Got barrier status at: $(date)"
19756         [ "$b_status" = "'freezing_p1'" ] ||
19757                 error "(1) unexpected barrier status $b_status"
19758
19759         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19760         wait
19761         b_status=$(barrier_stat)
19762         [ "$b_status" = "'frozen'" ] ||
19763                 error "(2) unexpected barrier status $b_status"
19764
19765         local expired=$(barrier_expired)
19766         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19767         sleep $((expired + 3))
19768
19769         b_status=$(barrier_stat)
19770         [ "$b_status" = "'expired'" ] ||
19771                 error "(3) unexpected barrier status $b_status"
19772
19773         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19774                 error "(4) fail to freeze barrier"
19775
19776         b_status=$(barrier_stat)
19777         [ "$b_status" = "'frozen'" ] ||
19778                 error "(5) unexpected barrier status $b_status"
19779
19780         echo "Start barrier_thaw at: $(date)"
19781         #define OBD_FAIL_BARRIER_DELAY          0x2202
19782         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19783         do_facet mgs $LCTL barrier_thaw $FSNAME &
19784
19785         sleep 2
19786         b_status=$(barrier_stat)
19787         echo "Got barrier status at: $(date)"
19788         [ "$b_status" = "'thawing'" ] ||
19789                 error "(6) unexpected barrier status $b_status"
19790
19791         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19792         wait
19793         b_status=$(barrier_stat)
19794         [ "$b_status" = "'thawed'" ] ||
19795                 error "(7) unexpected barrier status $b_status"
19796
19797         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19798         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19799         do_facet mgs $LCTL barrier_freeze $FSNAME
19800
19801         b_status=$(barrier_stat)
19802         [ "$b_status" = "'failed'" ] ||
19803                 error "(8) unexpected barrier status $b_status"
19804
19805         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19806         do_facet mgs $LCTL barrier_thaw $FSNAME
19807
19808         post_801
19809 }
19810 run_test 801a "write barrier user interfaces and stat machine"
19811
19812 test_801b() {
19813         prep_801
19814
19815         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19816         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19817         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19818         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19819         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19820
19821         cancel_lru_locks mdc
19822
19823         # 180 seconds should be long enough
19824         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19825
19826         local b_status=$(barrier_stat)
19827         [ "$b_status" = "'frozen'" ] ||
19828                 error "(6) unexpected barrier status $b_status"
19829
19830         mkdir $DIR/$tdir/d0/d10 &
19831         mkdir_pid=$!
19832
19833         touch $DIR/$tdir/d1/f13 &
19834         touch_pid=$!
19835
19836         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19837         ln_pid=$!
19838
19839         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19840         mv_pid=$!
19841
19842         rm -f $DIR/$tdir/d4/f12 &
19843         rm_pid=$!
19844
19845         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19846
19847         # To guarantee taht the 'stat' is not blocked
19848         b_status=$(barrier_stat)
19849         [ "$b_status" = "'frozen'" ] ||
19850                 error "(8) unexpected barrier status $b_status"
19851
19852         # let above commands to run at background
19853         sleep 5
19854
19855         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19856         ps -p $touch_pid || error "(10) touch should be blocked"
19857         ps -p $ln_pid || error "(11) link should be blocked"
19858         ps -p $mv_pid || error "(12) rename should be blocked"
19859         ps -p $rm_pid || error "(13) unlink should be blocked"
19860
19861         b_status=$(barrier_stat)
19862         [ "$b_status" = "'frozen'" ] ||
19863                 error "(14) unexpected barrier status $b_status"
19864
19865         do_facet mgs $LCTL barrier_thaw $FSNAME
19866         b_status=$(barrier_stat)
19867         [ "$b_status" = "'thawed'" ] ||
19868                 error "(15) unexpected barrier status $b_status"
19869
19870         wait $mkdir_pid || error "(16) mkdir should succeed"
19871         wait $touch_pid || error "(17) touch should succeed"
19872         wait $ln_pid || error "(18) link should succeed"
19873         wait $mv_pid || error "(19) rename should succeed"
19874         wait $rm_pid || error "(20) unlink should succeed"
19875
19876         post_801
19877 }
19878 run_test 801b "modification will be blocked by write barrier"
19879
19880 test_801c() {
19881         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19882
19883         prep_801
19884
19885         stop mds2 || error "(1) Fail to stop mds2"
19886
19887         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19888
19889         local b_status=$(barrier_stat)
19890         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19891                 do_facet mgs $LCTL barrier_thaw $FSNAME
19892                 error "(2) unexpected barrier status $b_status"
19893         }
19894
19895         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19896                 error "(3) Fail to rescan barrier bitmap"
19897
19898         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19899
19900         b_status=$(barrier_stat)
19901         [ "$b_status" = "'frozen'" ] ||
19902                 error "(4) unexpected barrier status $b_status"
19903
19904         do_facet mgs $LCTL barrier_thaw $FSNAME
19905         b_status=$(barrier_stat)
19906         [ "$b_status" = "'thawed'" ] ||
19907                 error "(5) unexpected barrier status $b_status"
19908
19909         local devname=$(mdsdevname 2)
19910
19911         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19912
19913         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19914                 error "(7) Fail to rescan barrier bitmap"
19915
19916         post_801
19917 }
19918 run_test 801c "rescan barrier bitmap"
19919
19920 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19921 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19922 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19923
19924 cleanup_802a() {
19925         trap 0
19926
19927         stopall
19928         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19929         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19930         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19931         setupall
19932 }
19933
19934 test_802a() {
19935
19936         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19937         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19938                 skip "Need server version at least 2.9.55"
19939
19940         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19941
19942         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19943
19944         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19945                 error "(2) Fail to copy"
19946
19947         trap cleanup_802a EXIT
19948
19949         # sync by force before remount as readonly
19950         sync; sync_all_data; sleep 3; sync_all_data
19951
19952         stopall
19953
19954         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19955         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19956         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19957
19958         echo "Mount the server as read only"
19959         setupall server_only || error "(3) Fail to start servers"
19960
19961         echo "Mount client without ro should fail"
19962         mount_client $MOUNT &&
19963                 error "(4) Mount client without 'ro' should fail"
19964
19965         echo "Mount client with ro should succeed"
19966         mount_client $MOUNT ro ||
19967                 error "(5) Mount client with 'ro' should succeed"
19968
19969         echo "Modify should be refused"
19970         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19971
19972         echo "Read should be allowed"
19973         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19974                 error "(7) Read should succeed under ro mode"
19975
19976         cleanup_802a
19977 }
19978 run_test 802a "simulate readonly device"
19979
19980 test_802b() {
19981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19982         remote_mds_nodsh && skip "remote MDS with nodsh"
19983
19984         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19985                 skip "readonly option not available"
19986
19987         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19988
19989         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19990                 error "(2) Fail to copy"
19991
19992         # write back all cached data before setting MDT to readonly
19993         cancel_lru_locks
19994         sync_all_data
19995
19996         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19997         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19998
19999         echo "Modify should be refused"
20000         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20001
20002         echo "Read should be allowed"
20003         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20004                 error "(7) Read should succeed under ro mode"
20005
20006         # disable readonly
20007         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20008 }
20009 run_test 802b "be able to set MDTs to readonly"
20010
20011 test_803() {
20012         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20013         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20014                 skip "MDS needs to be newer than 2.10.54"
20015
20016         mkdir -p $DIR/$tdir
20017         # Create some objects on all MDTs to trigger related logs objects
20018         for idx in $(seq $MDSCOUNT); do
20019                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20020                         $DIR/$tdir/dir${idx} ||
20021                         error "Fail to create $DIR/$tdir/dir${idx}"
20022         done
20023
20024         sync; sleep 3
20025         wait_delete_completed # ensure old test cleanups are finished
20026         echo "before create:"
20027         $LFS df -i $MOUNT
20028         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20029
20030         for i in {1..10}; do
20031                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20032                         error "Fail to create $DIR/$tdir/foo$i"
20033         done
20034
20035         sync; sleep 3
20036         echo "after create:"
20037         $LFS df -i $MOUNT
20038         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20039
20040         # allow for an llog to be cleaned up during the test
20041         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20042                 error "before ($before_used) + 10 > after ($after_used)"
20043
20044         for i in {1..10}; do
20045                 rm -rf $DIR/$tdir/foo$i ||
20046                         error "Fail to remove $DIR/$tdir/foo$i"
20047         done
20048
20049         sleep 3 # avoid MDT return cached statfs
20050         wait_delete_completed
20051         echo "after unlink:"
20052         $LFS df -i $MOUNT
20053         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20054
20055         # allow for an llog to be created during the test
20056         [ $after_used -le $((before_used + 1)) ] ||
20057                 error "after ($after_used) > before ($before_used) + 1"
20058 }
20059 run_test 803 "verify agent object for remote object"
20060
20061 test_804() {
20062         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20063         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20064                 skip "MDS needs to be newer than 2.10.54"
20065         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20066
20067         mkdir -p $DIR/$tdir
20068         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20069                 error "Fail to create $DIR/$tdir/dir0"
20070
20071         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20072         local dev=$(mdsdevname 2)
20073
20074         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20075                 grep ${fid} || error "NOT found agent entry for dir0"
20076
20077         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20078                 error "Fail to create $DIR/$tdir/dir1"
20079
20080         touch $DIR/$tdir/dir1/foo0 ||
20081                 error "Fail to create $DIR/$tdir/dir1/foo0"
20082         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20083         local rc=0
20084
20085         for idx in $(seq $MDSCOUNT); do
20086                 dev=$(mdsdevname $idx)
20087                 do_facet mds${idx} \
20088                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20089                         grep ${fid} && rc=$idx
20090         done
20091
20092         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20093                 error "Fail to rename foo0 to foo1"
20094         if [ $rc -eq 0 ]; then
20095                 for idx in $(seq $MDSCOUNT); do
20096                         dev=$(mdsdevname $idx)
20097                         do_facet mds${idx} \
20098                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20099                         grep ${fid} && rc=$idx
20100                 done
20101         fi
20102
20103         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20104                 error "Fail to rename foo1 to foo2"
20105         if [ $rc -eq 0 ]; then
20106                 for idx in $(seq $MDSCOUNT); do
20107                         dev=$(mdsdevname $idx)
20108                         do_facet mds${idx} \
20109                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20110                         grep ${fid} && rc=$idx
20111                 done
20112         fi
20113
20114         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20115
20116         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20117                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20118         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20119                 error "Fail to rename foo2 to foo0"
20120         unlink $DIR/$tdir/dir1/foo0 ||
20121                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20122         rm -rf $DIR/$tdir/dir0 ||
20123                 error "Fail to rm $DIR/$tdir/dir0"
20124
20125         for idx in $(seq $MDSCOUNT); do
20126                 dev=$(mdsdevname $idx)
20127                 rc=0
20128
20129                 stop mds${idx}
20130                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20131                         rc=$?
20132                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20133                         error "mount mds$idx failed"
20134                 df $MOUNT > /dev/null 2>&1
20135
20136                 # e2fsck should not return error
20137                 [ $rc -eq 0 ] ||
20138                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20139         done
20140 }
20141 run_test 804 "verify agent entry for remote entry"
20142
20143 cleanup_805() {
20144         do_facet $SINGLEMDS zfs set quota=$old $fsset
20145         unlinkmany $DIR/$tdir/f- 1000000
20146         trap 0
20147 }
20148
20149 test_805() {
20150         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20151         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20152         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20153                 skip "netfree not implemented before 0.7"
20154         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20155                 skip "Need MDS version at least 2.10.57"
20156
20157         local fsset
20158         local freekb
20159         local usedkb
20160         local old
20161         local quota
20162         local pref="osd-zfs.lustre-MDT0000."
20163
20164         # limit available space on MDS dataset to meet nospace issue
20165         # quickly. then ZFS 0.7.2 can use reserved space if asked
20166         # properly (using netfree flag in osd_declare_destroy()
20167         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20168         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20169                 gawk '{print $3}')
20170         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20171         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20172         let "usedkb=usedkb-freekb"
20173         let "freekb=freekb/2"
20174         if let "freekb > 5000"; then
20175                 let "freekb=5000"
20176         fi
20177         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20178         trap cleanup_805 EXIT
20179         mkdir $DIR/$tdir
20180         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20181         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20182         rm -rf $DIR/$tdir || error "not able to remove"
20183         do_facet $SINGLEMDS zfs set quota=$old $fsset
20184         trap 0
20185 }
20186 run_test 805 "ZFS can remove from full fs"
20187
20188 # Size-on-MDS test
20189 check_lsom_data()
20190 {
20191         local file=$1
20192         local size=$($LFS getsom -s $file)
20193         local expect=$(stat -c %s $file)
20194
20195         [[ $size == $expect ]] ||
20196                 error "$file expected size: $expect, got: $size"
20197
20198         local blocks=$($LFS getsom -b $file)
20199         expect=$(stat -c %b $file)
20200         [[ $blocks == $expect ]] ||
20201                 error "$file expected blocks: $expect, got: $blocks"
20202 }
20203
20204 check_lsom_size()
20205 {
20206         local size=$($LFS getsom -s $1)
20207         local expect=$2
20208
20209         [[ $size == $expect ]] ||
20210                 error "$file expected size: $expect, got: $size"
20211 }
20212
20213 test_806() {
20214         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20215                 skip "Need MDS version at least 2.11.52"
20216
20217         local bs=1048576
20218
20219         touch $DIR/$tfile || error "touch $tfile failed"
20220
20221         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20222         save_lustre_params client "llite.*.xattr_cache" > $save
20223         lctl set_param llite.*.xattr_cache=0
20224         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20225
20226         # single-threaded write
20227         echo "Test SOM for single-threaded write"
20228         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20229                 error "write $tfile failed"
20230         check_lsom_size $DIR/$tfile $bs
20231
20232         local num=32
20233         local size=$(($num * $bs))
20234         local offset=0
20235         local i
20236
20237         echo "Test SOM for single client multi-threaded($num) write"
20238         $TRUNCATE $DIR/$tfile 0
20239         for ((i = 0; i < $num; i++)); do
20240                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20241                 local pids[$i]=$!
20242                 offset=$((offset + $bs))
20243         done
20244         for (( i=0; i < $num; i++ )); do
20245                 wait ${pids[$i]}
20246         done
20247         check_lsom_size $DIR/$tfile $size
20248
20249         $TRUNCATE $DIR/$tfile 0
20250         for ((i = 0; i < $num; i++)); do
20251                 offset=$((offset - $bs))
20252                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20253                 local pids[$i]=$!
20254         done
20255         for (( i=0; i < $num; i++ )); do
20256                 wait ${pids[$i]}
20257         done
20258         check_lsom_size $DIR/$tfile $size
20259
20260         # multi-client wirtes
20261         num=$(get_node_count ${CLIENTS//,/ })
20262         size=$(($num * $bs))
20263         offset=0
20264         i=0
20265
20266         echo "Test SOM for multi-client ($num) writes"
20267         $TRUNCATE $DIR/$tfile 0
20268         for client in ${CLIENTS//,/ }; do
20269                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20270                 local pids[$i]=$!
20271                 i=$((i + 1))
20272                 offset=$((offset + $bs))
20273         done
20274         for (( i=0; i < $num; i++ )); do
20275                 wait ${pids[$i]}
20276         done
20277         check_lsom_size $DIR/$tfile $offset
20278
20279         i=0
20280         $TRUNCATE $DIR/$tfile 0
20281         for client in ${CLIENTS//,/ }; do
20282                 offset=$((offset - $bs))
20283                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20284                 local pids[$i]=$!
20285                 i=$((i + 1))
20286         done
20287         for (( i=0; i < $num; i++ )); do
20288                 wait ${pids[$i]}
20289         done
20290         check_lsom_size $DIR/$tfile $size
20291
20292         # verify truncate
20293         echo "Test SOM for truncate"
20294         $TRUNCATE $DIR/$tfile 1048576
20295         check_lsom_size $DIR/$tfile 1048576
20296         $TRUNCATE $DIR/$tfile 1234
20297         check_lsom_size $DIR/$tfile 1234
20298
20299         # verify SOM blocks count
20300         echo "Verify SOM block count"
20301         $TRUNCATE $DIR/$tfile 0
20302         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20303                 error "failed to write file $tfile"
20304         check_lsom_data $DIR/$tfile
20305 }
20306 run_test 806 "Verify Lazy Size on MDS"
20307
20308 test_807() {
20309         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20310         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20311                 skip "Need MDS version at least 2.11.52"
20312
20313         # Registration step
20314         changelog_register || error "changelog_register failed"
20315         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20316         changelog_users $SINGLEMDS | grep -q $cl_user ||
20317                 error "User $cl_user not found in changelog_users"
20318
20319         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20320         save_lustre_params client "llite.*.xattr_cache" > $save
20321         lctl set_param llite.*.xattr_cache=0
20322         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20323
20324         rm -rf $DIR/$tdir || error "rm $tdir failed"
20325         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20326         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20327         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20328         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20329                 error "truncate $tdir/trunc failed"
20330
20331         local bs=1048576
20332         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20333                 error "write $tfile failed"
20334
20335         # multi-client wirtes
20336         local num=$(get_node_count ${CLIENTS//,/ })
20337         local offset=0
20338         local i=0
20339
20340         echo "Test SOM for multi-client ($num) writes"
20341         touch $DIR/$tfile || error "touch $tfile failed"
20342         $TRUNCATE $DIR/$tfile 0
20343         for client in ${CLIENTS//,/ }; do
20344                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20345                 local pids[$i]=$!
20346                 i=$((i + 1))
20347                 offset=$((offset + $bs))
20348         done
20349         for (( i=0; i < $num; i++ )); do
20350                 wait ${pids[$i]}
20351         done
20352
20353         sleep 5
20354         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20355         check_lsom_data $DIR/$tdir/trunc
20356         check_lsom_data $DIR/$tdir/single_dd
20357         check_lsom_data $DIR/$tfile
20358
20359         rm -rf $DIR/$tdir
20360         # Deregistration step
20361         changelog_deregister || error "changelog_deregister failed"
20362 }
20363 run_test 807 "verify LSOM syncing tool"
20364
20365 check_som_nologged()
20366 {
20367         local lines=$($LFS changelog $FSNAME-MDT0000 |
20368                 grep 'x=trusted.som' | wc -l)
20369         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20370 }
20371
20372 test_808() {
20373         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20374                 skip "Need MDS version at least 2.11.55"
20375
20376         # Registration step
20377         changelog_register || error "changelog_register failed"
20378
20379         touch $DIR/$tfile || error "touch $tfile failed"
20380         check_som_nologged
20381
20382         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20383                 error "write $tfile failed"
20384         check_som_nologged
20385
20386         $TRUNCATE $DIR/$tfile 1234
20387         check_som_nologged
20388
20389         $TRUNCATE $DIR/$tfile 1048576
20390         check_som_nologged
20391
20392         # Deregistration step
20393         changelog_deregister || error "changelog_deregister failed"
20394 }
20395 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20396
20397 check_som_nodata()
20398 {
20399         $LFS getsom $1
20400         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20401 }
20402
20403 test_809() {
20404         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20405                 skip "Need MDS version at least 2.11.56"
20406
20407         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20408                 error "failed to create DoM-only file $DIR/$tfile"
20409         touch $DIR/$tfile || error "touch $tfile failed"
20410         check_som_nodata $DIR/$tfile
20411
20412         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20413                 error "write $tfile failed"
20414         check_som_nodata $DIR/$tfile
20415
20416         $TRUNCATE $DIR/$tfile 1234
20417         check_som_nodata $DIR/$tfile
20418
20419         $TRUNCATE $DIR/$tfile 4097
20420         check_som_nodata $DIR/$file
20421 }
20422 run_test 809 "Verify no SOM xattr store for DoM-only files"
20423
20424 test_810() {
20425         local ORIG
20426         local CSUM
20427
20428         # t10 seem to dislike partial pages
20429         lctl set_param osc.*.checksum_type=adler
20430         lctl set_param fail_loc=0x411
20431         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20432         ORIG=$(md5sum $DIR/$tfile)
20433         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20434         CSUM=$(md5sum $DIR/$tfile)
20435         set_checksum_type adler
20436         if [ "$ORIG" != "$CSUM" ]; then
20437                 error "$ORIG != $CSUM"
20438         fi
20439 }
20440 run_test 810 "partial page writes on ZFS (LU-11663)"
20441
20442 test_811() {
20443         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20444                 skip "Need MDS version at least 2.11.56"
20445
20446         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20447         do_facet mds1 $LCTL set_param fail_loc=0x165
20448         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20449
20450         stop mds1
20451         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20452
20453         sleep 5
20454         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20455                 error "MDD orphan cleanup thread not quit"
20456 }
20457 run_test 811 "orphan name stub can be cleaned up in startup"
20458
20459 test_812() {
20460         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20461                 skip "OST < 2.12.51 doesn't support this fail_loc"
20462
20463         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20464         # ensure ost1 is connected
20465         stat $DIR/$tfile >/dev/null || error "can't stat"
20466         wait_osc_import_state client ost1 FULL
20467         # no locks, no reqs to let the connection idle
20468         cancel_lru_locks osc
20469
20470         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20471 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20472         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20473         wait_osc_import_state client ost1 CONNECTING
20474         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20475
20476         stat $DIR/$tfile >/dev/null || error "can't stat file"
20477 }
20478 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20479
20480 test_813() {
20481         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20482         [ -z "$file_heat_sav" ] && skip "no file heat support"
20483
20484         local readsample
20485         local writesample
20486         local readbyte
20487         local writebyte
20488         local readsample1
20489         local writesample1
20490         local readbyte1
20491         local writebyte1
20492
20493         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20494         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20495
20496         $LCTL set_param -n llite.*.file_heat=1
20497         echo "Turn on file heat"
20498         echo "Period second: $period_second, Decay percentage: $decay_pct"
20499
20500         echo "QQQQ" > $DIR/$tfile
20501         echo "QQQQ" > $DIR/$tfile
20502         echo "QQQQ" > $DIR/$tfile
20503         cat $DIR/$tfile > /dev/null
20504         cat $DIR/$tfile > /dev/null
20505         cat $DIR/$tfile > /dev/null
20506         cat $DIR/$tfile > /dev/null
20507
20508         local out=$($LFS heat_get $DIR/$tfile)
20509
20510         $LFS heat_get $DIR/$tfile
20511         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20512         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20513         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20514         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20515
20516         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20517         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20518         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20519         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20520
20521         sleep $((period_second + 3))
20522         echo "Sleep $((period_second + 3)) seconds..."
20523         # The recursion formula to calculate the heat of the file f is as
20524         # follow:
20525         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20526         # Where Hi is the heat value in the period between time points i*I and
20527         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20528         # to the weight of Ci.
20529         out=$($LFS heat_get $DIR/$tfile)
20530         $LFS heat_get $DIR/$tfile
20531         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20532         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20533         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20534         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20535
20536         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20537                 error "read sample ($readsample) is wrong"
20538         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20539                 error "write sample ($writesample) is wrong"
20540         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20541                 error "read bytes ($readbyte) is wrong"
20542         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20543                 error "write bytes ($writebyte) is wrong"
20544
20545         echo "QQQQ" > $DIR/$tfile
20546         echo "QQQQ" > $DIR/$tfile
20547         echo "QQQQ" > $DIR/$tfile
20548         cat $DIR/$tfile > /dev/null
20549         cat $DIR/$tfile > /dev/null
20550         cat $DIR/$tfile > /dev/null
20551         cat $DIR/$tfile > /dev/null
20552
20553         sleep $((period_second + 3))
20554         echo "Sleep $((period_second + 3)) seconds..."
20555
20556         out=$($LFS heat_get $DIR/$tfile)
20557         $LFS heat_get $DIR/$tfile
20558         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20559         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20560         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20561         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20562
20563         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20564                 4 * $decay_pct) / 100") -eq 1 ] ||
20565                 error "read sample ($readsample1) is wrong"
20566         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20567                 3 * $decay_pct) / 100") -eq 1 ] ||
20568                 error "write sample ($writesample1) is wrong"
20569         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20570                 20 * $decay_pct) / 100") -eq 1 ] ||
20571                 error "read bytes ($readbyte1) is wrong"
20572         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20573                 15 * $decay_pct) / 100") -eq 1 ] ||
20574                 error "write bytes ($writebyte1) is wrong"
20575
20576         echo "Turn off file heat for the file $DIR/$tfile"
20577         $LFS heat_set -o $DIR/$tfile
20578
20579         echo "QQQQ" > $DIR/$tfile
20580         echo "QQQQ" > $DIR/$tfile
20581         echo "QQQQ" > $DIR/$tfile
20582         cat $DIR/$tfile > /dev/null
20583         cat $DIR/$tfile > /dev/null
20584         cat $DIR/$tfile > /dev/null
20585         cat $DIR/$tfile > /dev/null
20586
20587         out=$($LFS heat_get $DIR/$tfile)
20588         $LFS heat_get $DIR/$tfile
20589         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20590         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20591         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20592         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20593
20594         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20595         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20596         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20597         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20598
20599         echo "Trun on file heat for the file $DIR/$tfile"
20600         $LFS heat_set -O $DIR/$tfile
20601
20602         echo "QQQQ" > $DIR/$tfile
20603         echo "QQQQ" > $DIR/$tfile
20604         echo "QQQQ" > $DIR/$tfile
20605         cat $DIR/$tfile > /dev/null
20606         cat $DIR/$tfile > /dev/null
20607         cat $DIR/$tfile > /dev/null
20608         cat $DIR/$tfile > /dev/null
20609
20610         out=$($LFS heat_get $DIR/$tfile)
20611         $LFS heat_get $DIR/$tfile
20612         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20613         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20614         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20615         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20616
20617         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20618         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20619         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20620         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20621
20622         $LFS heat_set -c $DIR/$tfile
20623         $LCTL set_param -n llite.*.file_heat=0
20624         echo "Turn off file heat support for the Lustre filesystem"
20625
20626         echo "QQQQ" > $DIR/$tfile
20627         echo "QQQQ" > $DIR/$tfile
20628         echo "QQQQ" > $DIR/$tfile
20629         cat $DIR/$tfile > /dev/null
20630         cat $DIR/$tfile > /dev/null
20631         cat $DIR/$tfile > /dev/null
20632         cat $DIR/$tfile > /dev/null
20633
20634         out=$($LFS heat_get $DIR/$tfile)
20635         $LFS heat_get $DIR/$tfile
20636         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20637         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20638         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20639         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20640
20641         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20642         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20643         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20644         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20645
20646         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20647         rm -f $DIR/$tfile
20648 }
20649 run_test 813 "File heat verfication"
20650
20651 #
20652 # tests that do cleanup/setup should be run at the end
20653 #
20654
20655 test_900() {
20656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20657         local ls
20658
20659         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20660         $LCTL set_param fail_loc=0x903
20661
20662         cancel_lru_locks MGC
20663
20664         FAIL_ON_ERROR=true cleanup
20665         FAIL_ON_ERROR=true setup
20666 }
20667 run_test 900 "umount should not race with any mgc requeue thread"
20668
20669 complete $SECONDS
20670 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20671 check_and_cleanup_lustre
20672 if [ "$I_MOUNTED" != "yes" ]; then
20673         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20674 fi
20675 exit_status