Whamcloud - gitweb
LU-12195 tests: use sleep instead of wrapped multiop
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_25a() {
1444         echo '== symlink sanity ============================================='
1445
1446         test_mkdir $DIR/d25
1447         ln -s d25 $DIR/s25
1448         touch $DIR/s25/foo ||
1449                 error "File creation in symlinked directory failed"
1450 }
1451 run_test 25a "create file in symlinked directory ==============="
1452
1453 test_25b() {
1454         [ ! -d $DIR/d25 ] && test_25a
1455         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1456 }
1457 run_test 25b "lookup file in symlinked directory ==============="
1458
1459 test_26a() {
1460         test_mkdir $DIR/d26
1461         test_mkdir $DIR/d26/d26-2
1462         ln -s d26/d26-2 $DIR/s26
1463         touch $DIR/s26/foo || error "File creation failed"
1464 }
1465 run_test 26a "multiple component symlink ======================="
1466
1467 test_26b() {
1468         test_mkdir -p $DIR/$tdir/d26-2
1469         ln -s $tdir/d26-2/foo $DIR/s26-2
1470         touch $DIR/s26-2 || error "File creation failed"
1471 }
1472 run_test 26b "multiple component symlink at end of lookup ======"
1473
1474 test_26c() {
1475         test_mkdir $DIR/d26.2
1476         touch $DIR/d26.2/foo
1477         ln -s d26.2 $DIR/s26.2-1
1478         ln -s s26.2-1 $DIR/s26.2-2
1479         ln -s s26.2-2 $DIR/s26.2-3
1480         chmod 0666 $DIR/s26.2-3/foo
1481 }
1482 run_test 26c "chain of symlinks"
1483
1484 # recursive symlinks (bug 439)
1485 test_26d() {
1486         ln -s d26-3/foo $DIR/d26-3
1487 }
1488 run_test 26d "create multiple component recursive symlink"
1489
1490 test_26e() {
1491         [ ! -h $DIR/d26-3 ] && test_26d
1492         rm $DIR/d26-3
1493 }
1494 run_test 26e "unlink multiple component recursive symlink"
1495
1496 # recursive symlinks (bug 7022)
1497 test_26f() {
1498         test_mkdir $DIR/$tdir
1499         test_mkdir $DIR/$tdir/$tfile
1500         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1501         test_mkdir -p lndir/bar1
1502         test_mkdir $DIR/$tdir/$tfile/$tfile
1503         cd $tfile                || error "cd $tfile failed"
1504         ln -s .. dotdot          || error "ln dotdot failed"
1505         ln -s dotdot/lndir lndir || error "ln lndir failed"
1506         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1507         output=`ls $tfile/$tfile/lndir/bar1`
1508         [ "$output" = bar1 ] && error "unexpected output"
1509         rm -r $tfile             || error "rm $tfile failed"
1510         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1511 }
1512 run_test 26f "rm -r of a directory which has recursive symlink"
1513
1514 test_27a() {
1515         test_mkdir $DIR/$tdir
1516         $LFS getstripe $DIR/$tdir
1517         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1518         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1519         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1520 }
1521 run_test 27a "one stripe file"
1522
1523 test_27b() {
1524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1525
1526         test_mkdir $DIR/$tdir
1527         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1528         $LFS getstripe -c $DIR/$tdir/$tfile
1529         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1530                 error "two-stripe file doesn't have two stripes"
1531
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533 }
1534 run_test 27b "create and write to two stripe file"
1535
1536 test_27d() {
1537         test_mkdir $DIR/$tdir
1538         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1539                 error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1542 }
1543 run_test 27d "create file with default settings"
1544
1545 test_27e() {
1546         # LU-5839 adds check for existed layout before setting it
1547         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1548                 skip "Need MDS version at least 2.7.56"
1549
1550         test_mkdir $DIR/$tdir
1551         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1552         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1553         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1554 }
1555 run_test 27e "setstripe existing file (should return error)"
1556
1557 test_27f() {
1558         test_mkdir $DIR/$tdir
1559         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1560                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1561         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1562                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1564         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1565 }
1566 run_test 27f "setstripe with bad stripe size (should return error)"
1567
1568 test_27g() {
1569         test_mkdir $DIR/$tdir
1570         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1571         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1572                 error "$DIR/$tdir/$tfile has object"
1573 }
1574 run_test 27g "$LFS getstripe with no objects"
1575
1576 test_27i() {
1577         test_mkdir $DIR/$tdir
1578         touch $DIR/$tdir/$tfile || error "touch failed"
1579         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1580                 error "missing objects"
1581 }
1582 run_test 27i "$LFS getstripe with some objects"
1583
1584 test_27j() {
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1587                 error "setstripe failed" || true
1588 }
1589 run_test 27j "setstripe with bad stripe offset (should return error)"
1590
1591 test_27k() { # bug 2844
1592         test_mkdir $DIR/$tdir
1593         local file=$DIR/$tdir/$tfile
1594         local ll_max_blksize=$((4 * 1024 * 1024))
1595         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1596         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1597         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1598         dd if=/dev/zero of=$file bs=4k count=1
1599         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1600         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1601 }
1602 run_test 27k "limit i_blksize for broken user apps"
1603
1604 test_27l() {
1605         mcreate $DIR/$tfile || error "creating file"
1606         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1607                 error "setstripe should have failed" || true
1608 }
1609 run_test 27l "check setstripe permissions (should return error)"
1610
1611 test_27m() {
1612         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1613
1614         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1615                    head -n1)
1616         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1617                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1618         fi
1619         trap simple_cleanup_common EXIT
1620         test_mkdir $DIR/$tdir
1621         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1622         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1623                 error "dd should fill OST0"
1624         i=2
1625         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1626                 i=$((i + 1))
1627                 [ $i -gt 256 ] && break
1628         done
1629         i=$((i + 1))
1630         touch $DIR/$tdir/$tfile.$i
1631         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1632             awk '{print $1}'| grep -w "0") ] &&
1633                 error "OST0 was full but new created file still use it"
1634         i=$((i + 1))
1635         touch $DIR/$tdir/$tfile.$i
1636         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1637             awk '{print $1}'| grep -w "0") ] &&
1638                 error "OST0 was full but new created file still use it"
1639         simple_cleanup_common
1640 }
1641 run_test 27m "create file while OST0 was full"
1642
1643 sleep_maxage() {
1644         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1645                       awk '{ print $1 * 2; exit; }')
1646         sleep $delay
1647 }
1648
1649 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1650 # if the OST isn't full anymore.
1651 reset_enospc() {
1652         local OSTIDX=${1:-""}
1653
1654         local list=$(comma_list $(osts_nodes))
1655         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1656
1657         do_nodes $list lctl set_param fail_loc=0
1658         sync    # initiate all OST_DESTROYs from MDS to OST
1659         sleep_maxage
1660 }
1661
1662 exhaust_precreations() {
1663         local OSTIDX=$1
1664         local FAILLOC=$2
1665         local FAILIDX=${3:-$OSTIDX}
1666         local ofacet=ost$((OSTIDX + 1))
1667
1668         test_mkdir -p -c1 $DIR/$tdir
1669         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1670         local mfacet=mds$((mdtidx + 1))
1671         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1672
1673         local OST=$(ostname_from_index $OSTIDX)
1674
1675         # on the mdt's osc
1676         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1677         local last_id=$(do_facet $mfacet lctl get_param -n \
1678                         osc.$mdtosc_proc1.prealloc_last_id)
1679         local next_id=$(do_facet $mfacet lctl get_param -n \
1680                         osc.$mdtosc_proc1.prealloc_next_id)
1681
1682         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1683         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1684
1685         test_mkdir -p $DIR/$tdir/${OST}
1686         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1687 #define OBD_FAIL_OST_ENOSPC              0x215
1688         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1689         echo "Creating to objid $last_id on ost $OST..."
1690         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1691         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1692         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1693         sleep_maxage
1694 }
1695
1696 exhaust_all_precreations() {
1697         local i
1698         for (( i=0; i < OSTCOUNT; i++ )) ; do
1699                 exhaust_precreations $i $1 -1
1700         done
1701 }
1702
1703 test_27n() {
1704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1706         remote_mds_nodsh && skip "remote MDS with nodsh"
1707         remote_ost_nodsh && skip "remote OST with nodsh"
1708
1709         reset_enospc
1710         rm -f $DIR/$tdir/$tfile
1711         exhaust_precreations 0 0x80000215
1712         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1713         touch $DIR/$tdir/$tfile || error "touch failed"
1714         $LFS getstripe $DIR/$tdir/$tfile
1715         reset_enospc
1716 }
1717 run_test 27n "create file with some full OSTs"
1718
1719 test_27o() {
1720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1722         remote_mds_nodsh && skip "remote MDS with nodsh"
1723         remote_ost_nodsh && skip "remote OST with nodsh"
1724
1725         reset_enospc
1726         rm -f $DIR/$tdir/$tfile
1727         exhaust_all_precreations 0x215
1728
1729         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1730
1731         reset_enospc
1732         rm -rf $DIR/$tdir/*
1733 }
1734 run_test 27o "create file with all full OSTs (should error)"
1735
1736 test_27p() {
1737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1739         remote_mds_nodsh && skip "remote MDS with nodsh"
1740         remote_ost_nodsh && skip "remote OST with nodsh"
1741
1742         reset_enospc
1743         rm -f $DIR/$tdir/$tfile
1744         test_mkdir $DIR/$tdir
1745
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1748         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1749
1750         exhaust_precreations 0 0x80000215
1751         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1752         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1753         $LFS getstripe $DIR/$tdir/$tfile
1754
1755         reset_enospc
1756 }
1757 run_test 27p "append to a truncated file with some full OSTs"
1758
1759 test_27q() {
1760         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1762         remote_mds_nodsh && skip "remote MDS with nodsh"
1763         remote_ost_nodsh && skip "remote OST with nodsh"
1764
1765         reset_enospc
1766         rm -f $DIR/$tdir/$tfile
1767
1768         test_mkdir $DIR/$tdir
1769         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1770         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1771                 error "truncate $DIR/$tdir/$tfile failed"
1772         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1773
1774         exhaust_all_precreations 0x215
1775
1776         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1777         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1778
1779         reset_enospc
1780 }
1781 run_test 27q "append to truncated file with all OSTs full (should error)"
1782
1783 test_27r() {
1784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1786         remote_mds_nodsh && skip "remote MDS with nodsh"
1787         remote_ost_nodsh && skip "remote OST with nodsh"
1788
1789         reset_enospc
1790         rm -f $DIR/$tdir/$tfile
1791         exhaust_precreations 0 0x80000215
1792
1793         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1794
1795         reset_enospc
1796 }
1797 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1798
1799 test_27s() { # bug 10725
1800         test_mkdir $DIR/$tdir
1801         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1802         local stripe_count=0
1803         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1804         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1805                 error "stripe width >= 2^32 succeeded" || true
1806
1807 }
1808 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1809
1810 test_27t() { # bug 10864
1811         WDIR=$(pwd)
1812         WLFS=$(which lfs)
1813         cd $DIR
1814         touch $tfile
1815         $WLFS getstripe $tfile
1816         cd $WDIR
1817 }
1818 run_test 27t "check that utils parse path correctly"
1819
1820 test_27u() { # bug 4900
1821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1822         remote_mds_nodsh && skip "remote MDS with nodsh"
1823
1824         local index
1825         local list=$(comma_list $(mdts_nodes))
1826
1827 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1828         do_nodes $list $LCTL set_param fail_loc=0x139
1829         test_mkdir -p $DIR/$tdir
1830         trap simple_cleanup_common EXIT
1831         createmany -o $DIR/$tdir/t- 1000
1832         do_nodes $list $LCTL set_param fail_loc=0
1833
1834         TLOG=$TMP/$tfile.getstripe
1835         $LFS getstripe $DIR/$tdir > $TLOG
1836         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1837         unlinkmany $DIR/$tdir/t- 1000
1838         trap 0
1839         [[ $OBJS -gt 0 ]] &&
1840                 error "$OBJS objects created on OST-0. See $TLOG" ||
1841                 rm -f $TLOG
1842 }
1843 run_test 27u "skip object creation on OSC w/o objects"
1844
1845 test_27v() { # bug 4900
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1848         remote_mds_nodsh && skip "remote MDS with nodsh"
1849         remote_ost_nodsh && skip "remote OST with nodsh"
1850
1851         exhaust_all_precreations 0x215
1852         reset_enospc
1853
1854         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1855
1856         touch $DIR/$tdir/$tfile
1857         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1858         # all except ost1
1859         for (( i=1; i < OSTCOUNT; i++ )); do
1860                 do_facet ost$i lctl set_param fail_loc=0x705
1861         done
1862         local START=`date +%s`
1863         createmany -o $DIR/$tdir/$tfile 32
1864
1865         local FINISH=`date +%s`
1866         local TIMEOUT=`lctl get_param -n timeout`
1867         local PROCESS=$((FINISH - START))
1868         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1869                error "$FINISH - $START >= $TIMEOUT / 2"
1870         sleep $((TIMEOUT / 2 - PROCESS))
1871         reset_enospc
1872 }
1873 run_test 27v "skip object creation on slow OST"
1874
1875 test_27w() { # bug 10997
1876         test_mkdir $DIR/$tdir
1877         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1878         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1879                 error "stripe size $size != 65536" || true
1880         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1881                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1882 }
1883 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1884
1885 test_27wa() {
1886         [[ $OSTCOUNT -lt 2 ]] &&
1887                 skip_env "skipping multiple stripe count/offset test"
1888
1889         test_mkdir $DIR/$tdir
1890         for i in $(seq 1 $OSTCOUNT); do
1891                 offset=$((i - 1))
1892                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1893                         error "setstripe -c $i -i $offset failed"
1894                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1895                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1896                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1897                 [ $index -ne $offset ] &&
1898                         error "stripe offset $index != $offset" || true
1899         done
1900 }
1901 run_test 27wa "check $LFS setstripe -c -i options"
1902
1903 test_27x() {
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907
1908         OFFSET=$(($OSTCOUNT - 1))
1909         OSTIDX=0
1910         local OST=$(ostname_from_index $OSTIDX)
1911
1912         test_mkdir $DIR/$tdir
1913         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1914         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1915         sleep_maxage
1916         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1917         for i in $(seq 0 $OFFSET); do
1918                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1919                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1920                 error "OST0 was degraded but new created file still use it"
1921         done
1922         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1923 }
1924 run_test 27x "create files while OST0 is degraded"
1925
1926 test_27y() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931
1932         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1933         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1934                 osc.$mdtosc.prealloc_last_id)
1935         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1936                 osc.$mdtosc.prealloc_next_id)
1937         local fcount=$((last_id - next_id))
1938         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1939         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1940
1941         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1942                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1943         local OST_DEACTIVE_IDX=-1
1944         local OSC
1945         local OSTIDX
1946         local OST
1947
1948         for OSC in $MDS_OSCS; do
1949                 OST=$(osc_to_ost $OSC)
1950                 OSTIDX=$(index_from_ostuuid $OST)
1951                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1952                         OST_DEACTIVE_IDX=$OSTIDX
1953                 fi
1954                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1955                         echo $OSC "is Deactivated:"
1956                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1957                 fi
1958         done
1959
1960         OSTIDX=$(index_from_ostuuid $OST)
1961         test_mkdir $DIR/$tdir
1962         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1963
1964         for OSC in $MDS_OSCS; do
1965                 OST=$(osc_to_ost $OSC)
1966                 OSTIDX=$(index_from_ostuuid $OST)
1967                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1968                         echo $OST "is degraded:"
1969                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1970                                                 obdfilter.$OST.degraded=1
1971                 fi
1972         done
1973
1974         sleep_maxage
1975         createmany -o $DIR/$tdir/$tfile $fcount
1976
1977         for OSC in $MDS_OSCS; do
1978                 OST=$(osc_to_ost $OSC)
1979                 OSTIDX=$(index_from_ostuuid $OST)
1980                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1981                         echo $OST "is recovered from degraded:"
1982                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1983                                                 obdfilter.$OST.degraded=0
1984                 else
1985                         do_facet $SINGLEMDS lctl --device %$OSC activate
1986                 fi
1987         done
1988
1989         # all osp devices get activated, hence -1 stripe count restored
1990         local stripe_count=0
1991
1992         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1993         # devices get activated.
1994         sleep_maxage
1995         $LFS setstripe -c -1 $DIR/$tfile
1996         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1997         rm -f $DIR/$tfile
1998         [ $stripe_count -ne $OSTCOUNT ] &&
1999                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2000         return 0
2001 }
2002 run_test 27y "create files while OST0 is degraded and the rest inactive"
2003
2004 check_seq_oid()
2005 {
2006         log "check file $1"
2007
2008         lmm_count=$($LFS getstripe -c $1)
2009         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2010         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2011
2012         local old_ifs="$IFS"
2013         IFS=$'[:]'
2014         fid=($($LFS path2fid $1))
2015         IFS="$old_ifs"
2016
2017         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2018         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2019
2020         # compare lmm_seq and lu_fid->f_seq
2021         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2022         # compare lmm_object_id and lu_fid->oid
2023         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2024
2025         # check the trusted.fid attribute of the OST objects of the file
2026         local have_obdidx=false
2027         local stripe_nr=0
2028         $LFS getstripe $1 | while read obdidx oid hex seq; do
2029                 # skip lines up to and including "obdidx"
2030                 [ -z "$obdidx" ] && break
2031                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2032                 $have_obdidx || continue
2033
2034                 local ost=$((obdidx + 1))
2035                 local dev=$(ostdevname $ost)
2036                 local oid_hex
2037
2038                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2039
2040                 seq=$(echo $seq | sed -e "s/^0x//g")
2041                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2042                         oid_hex=$(echo $oid)
2043                 else
2044                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2045                 fi
2046                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2047
2048                 local ff=""
2049                 #
2050                 # Don't unmount/remount the OSTs if we don't need to do that.
2051                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2052                 # update too, until that use mount/ll_decode_filter_fid/mount.
2053                 # Re-enable when debugfs will understand new filter_fid.
2054                 #
2055                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2056                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2057                                 $dev 2>/dev/null" | grep "parent=")
2058                 fi
2059                 if [ -z "$ff" ]; then
2060                         stop ost$ost
2061                         mount_fstype ost$ost
2062                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2063                                 $(facet_mntpt ost$ost)/$obj_file)
2064                         unmount_fstype ost$ost
2065                         start ost$ost $dev $OST_MOUNT_OPTS
2066                         clients_up
2067                 fi
2068
2069                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2070
2071                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2072
2073                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2074                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2075                 #
2076                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2077                 #       stripe_size=1048576 component_id=1 component_start=0 \
2078                 #       component_end=33554432
2079                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2080                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2081                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2082                 local ff_pstripe
2083                 if grep -q 'stripe=' <<<$ff; then
2084                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2085                 else
2086                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2087                         # into f_ver in this case.  See comment on ff_parent.
2088                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2089                 fi
2090
2091                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2092                 [ $ff_pseq = $lmm_seq ] ||
2093                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2094                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2095                 [ $ff_poid = $lmm_oid ] ||
2096                         error "FF parent OID $ff_poid != $lmm_oid"
2097                 (($ff_pstripe == $stripe_nr)) ||
2098                         error "FF stripe $ff_pstripe != $stripe_nr"
2099
2100                 stripe_nr=$((stripe_nr + 1))
2101                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2102                         continue
2103                 if grep -q 'stripe_count=' <<<$ff; then
2104                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2105                                             -e 's/ .*//' <<<$ff)
2106                         [ $lmm_count = $ff_scnt ] ||
2107                                 error "FF stripe count $lmm_count != $ff_scnt"
2108                 fi
2109         done
2110 }
2111
2112 test_27z() {
2113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2114         remote_ost_nodsh && skip "remote OST with nodsh"
2115
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2118                 { error "setstripe -c -1 failed"; return 1; }
2119         # We need to send a write to every object to get parent FID info set.
2120         # This _should_ also work for setattr, but does not currently.
2121         # touch $DIR/$tdir/$tfile-1 ||
2122         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2123                 { error "dd $tfile-1 failed"; return 2; }
2124         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2125                 { error "setstripe -c -1 failed"; return 3; }
2126         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2127                 { error "dd $tfile-2 failed"; return 4; }
2128
2129         # make sure write RPCs have been sent to OSTs
2130         sync; sleep 5; sync
2131
2132         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2133         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2134 }
2135 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2136
2137 test_27A() { # b=19102
2138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2139
2140         save_layout_restore_at_exit $MOUNT
2141         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2142         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2143                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2144         local default_size=$($LFS getstripe -S $MOUNT)
2145         local default_offset=$($LFS getstripe -i $MOUNT)
2146         local dsize=$(do_facet $SINGLEMDS \
2147                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2148         [ $default_size -eq $dsize ] ||
2149                 error "stripe size $default_size != $dsize"
2150         [ $default_offset -eq -1 ] ||
2151                 error "stripe offset $default_offset != -1"
2152 }
2153 run_test 27A "check filesystem-wide default LOV EA values"
2154
2155 test_27B() { # LU-2523
2156         test_mkdir $DIR/$tdir
2157         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2158         touch $DIR/$tdir/f0
2159         # open f1 with O_LOV_DELAY_CREATE
2160         # rename f0 onto f1
2161         # call setstripe ioctl on open file descriptor for f1
2162         # close
2163         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2164                 $DIR/$tdir/f0
2165
2166         rm -f $DIR/$tdir/f1
2167         # open f1 with O_LOV_DELAY_CREATE
2168         # unlink f1
2169         # call setstripe ioctl on open file descriptor for f1
2170         # close
2171         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2172
2173         # Allow multiop to fail in imitation of NFS's busted semantics.
2174         true
2175 }
2176 run_test 27B "call setstripe on open unlinked file/rename victim"
2177
2178 test_27C() { #LU-2871
2179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2180
2181         declare -a ost_idx
2182         local index
2183         local found
2184         local i
2185         local j
2186
2187         test_mkdir $DIR/$tdir
2188         cd $DIR/$tdir
2189         for i in $(seq 0 $((OSTCOUNT - 1))); do
2190                 # set stripe across all OSTs starting from OST$i
2191                 $LFS setstripe -i $i -c -1 $tfile$i
2192                 # get striping information
2193                 ost_idx=($($LFS getstripe $tfile$i |
2194                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2195                 echo ${ost_idx[@]}
2196
2197                 # check the layout
2198                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2199                         error "${#ost_idx[@]} != $OSTCOUNT"
2200
2201                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2202                         found=0
2203                         for j in $(echo ${ost_idx[@]}); do
2204                                 if [ $index -eq $j ]; then
2205                                         found=1
2206                                         break
2207                                 fi
2208                         done
2209                         [ $found = 1 ] ||
2210                                 error "Can not find $index in ${ost_idx[@]}"
2211                 done
2212         done
2213 }
2214 run_test 27C "check full striping across all OSTs"
2215
2216 test_27D() {
2217         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2218         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2219         remote_mds_nodsh && skip "remote MDS with nodsh"
2220
2221         local POOL=${POOL:-testpool}
2222         local first_ost=0
2223         local last_ost=$(($OSTCOUNT - 1))
2224         local ost_step=1
2225         local ost_list=$(seq $first_ost $ost_step $last_ost)
2226         local ost_range="$first_ost $last_ost $ost_step"
2227
2228         if ! combined_mgs_mds ; then
2229                 mount_mgs_client
2230         fi
2231
2232         test_mkdir $DIR/$tdir
2233         pool_add $POOL || error "pool_add failed"
2234         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2235
2236         local skip27D
2237         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2238                 skip27D+="-s 29"
2239         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2240                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2241                         skip27D+=" -s 30,31"
2242         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2243                 error "llapi_layout_test failed"
2244
2245         destroy_test_pools || error "destroy test pools failed"
2246
2247         if ! combined_mgs_mds ; then
2248                 umount_mgs_client
2249         fi
2250 }
2251 run_test 27D "validate llapi_layout API"
2252
2253 # Verify that default_easize is increased from its initial value after
2254 # accessing a widely striped file.
2255 test_27E() {
2256         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2257         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2258                 skip "client does not have LU-3338 fix"
2259
2260         # 72 bytes is the minimum space required to store striping
2261         # information for a file striped across one OST:
2262         # (sizeof(struct lov_user_md_v3) +
2263         #  sizeof(struct lov_user_ost_data_v1))
2264         local min_easize=72
2265         $LCTL set_param -n llite.*.default_easize $min_easize ||
2266                 error "lctl set_param failed"
2267         local easize=$($LCTL get_param -n llite.*.default_easize)
2268
2269         [ $easize -eq $min_easize ] ||
2270                 error "failed to set default_easize"
2271
2272         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2273                 error "setstripe failed"
2274         cat $DIR/$tfile
2275         rm $DIR/$tfile
2276
2277         easize=$($LCTL get_param -n llite.*.default_easize)
2278
2279         [ $easize -gt $min_easize ] ||
2280                 error "default_easize not updated"
2281 }
2282 run_test 27E "check that default extended attribute size properly increases"
2283
2284 test_27F() { # LU-5346/LU-7975
2285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2286         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2287         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2288                 skip "Need MDS version at least 2.8.51"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         rm -f $DIR/$tdir/f0
2293         $LFS setstripe -c 2 $DIR/$tdir
2294
2295         # stop all OSTs to reproduce situation for LU-7975 ticket
2296         for num in $(seq $OSTCOUNT); do
2297                 stop ost$num
2298         done
2299
2300         # open/create f0 with O_LOV_DELAY_CREATE
2301         # truncate f0 to a non-0 size
2302         # close
2303         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2304
2305         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2306         # open/write it again to force delayed layout creation
2307         cat /etc/hosts > $DIR/$tdir/f0 &
2308         catpid=$!
2309
2310         # restart OSTs
2311         for num in $(seq $OSTCOUNT); do
2312                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2313                         error "ost$num failed to start"
2314         done
2315
2316         wait $catpid || error "cat failed"
2317
2318         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2319         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2320                 error "wrong stripecount"
2321
2322 }
2323 run_test 27F "Client resend delayed layout creation with non-zero size"
2324
2325 test_27G() { #LU-10629
2326         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2327                 skip "Need MDS version at least 2.11.51"
2328         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2329         remote_mds_nodsh && skip "remote MDS with nodsh"
2330         local POOL=${POOL:-testpool}
2331         local ostrange="0 0 1"
2332
2333         test_mkdir $DIR/$tdir
2334         pool_add $POOL || error "pool_add failed"
2335         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2336         $LFS setstripe -p $POOL $DIR/$tdir
2337
2338         local pool=$($LFS getstripe -p $DIR/$tdir)
2339
2340         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2341
2342         $LFS setstripe -d $DIR/$tdir
2343
2344         pool=$($LFS getstripe -p $DIR/$tdir)
2345
2346         rmdir $DIR/$tdir
2347
2348         [ -z "$pool" ] || error "'$pool' is not empty"
2349 }
2350 run_test 27G "Clear OST pool from stripe"
2351
2352 test_27H() {
2353         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2354                 skip "Need MDS version newer than 2.11.54"
2355         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2358         touch $DIR/$tdir/$tfile
2359         $LFS getstripe -c $DIR/$tdir/$tfile
2360         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2361                 error "two-stripe file doesn't have two stripes"
2362
2363         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2364         $LFS getstripe -y $DIR/$tdir/$tfile
2365         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2366              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2367                 error "expected l_ost_idx: [02]$ not matched"
2368
2369         # make sure ost list has been cleared
2370         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2371         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2372                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2373         touch $DIR/$tdir/f3
2374         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2375 }
2376 run_test 27H "Set specific OSTs stripe"
2377
2378 test_27I() {
2379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2380         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2381         local pool=$TESTNAME
2382         local ostrange="1 1 1"
2383
2384         save_layout_restore_at_exit $MOUNT
2385         $LFS setstripe -c 2 -i 0 $MOUNT
2386         pool_add $pool || error "pool_add failed"
2387         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2388         test_mkdir $DIR/$tdir
2389         $LFS setstripe -p $pool $DIR/$tdir
2390         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2391         $LFS getstripe $DIR/$tdir/$tfile
2392 }
2393 run_test 27I "check that root dir striping does not break parent dir one"
2394
2395 # createtest also checks that device nodes are created and
2396 # then visible correctly (#2091)
2397 test_28() { # bug 2091
2398         test_mkdir $DIR/d28
2399         $CREATETEST $DIR/d28/ct || error "createtest failed"
2400 }
2401 run_test 28 "create/mknod/mkdir with bad file types ============"
2402
2403 test_29() {
2404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2405
2406         sync; sleep 1; sync # flush out any dirty pages from previous tests
2407         cancel_lru_locks
2408         test_mkdir $DIR/d29
2409         touch $DIR/d29/foo
2410         log 'first d29'
2411         ls -l $DIR/d29
2412
2413         declare -i LOCKCOUNTORIG=0
2414         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2415                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2416         done
2417         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2418
2419         declare -i LOCKUNUSEDCOUNTORIG=0
2420         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2421                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2422         done
2423
2424         log 'second d29'
2425         ls -l $DIR/d29
2426         log 'done'
2427
2428         declare -i LOCKCOUNTCURRENT=0
2429         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2430                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2431         done
2432
2433         declare -i LOCKUNUSEDCOUNTCURRENT=0
2434         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2435                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2436         done
2437
2438         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2439                 $LCTL set_param -n ldlm.dump_namespaces ""
2440                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2441                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2442                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2443                 return 2
2444         fi
2445         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2446                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2447                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2448                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2449                 return 3
2450         fi
2451 }
2452 run_test 29 "IT_GETATTR regression  ============================"
2453
2454 test_30a() { # was test_30
2455         cp $(which ls) $DIR || cp /bin/ls $DIR
2456         $DIR/ls / || error "Can't execute binary from lustre"
2457         rm $DIR/ls
2458 }
2459 run_test 30a "execute binary from Lustre (execve) =============="
2460
2461 test_30b() {
2462         cp `which ls` $DIR || cp /bin/ls $DIR
2463         chmod go+rx $DIR/ls
2464         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2465         rm $DIR/ls
2466 }
2467 run_test 30b "execute binary from Lustre as non-root ==========="
2468
2469 test_30c() { # b=22376
2470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2471
2472         cp `which ls` $DIR || cp /bin/ls $DIR
2473         chmod a-rw $DIR/ls
2474         cancel_lru_locks mdc
2475         cancel_lru_locks osc
2476         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2477         rm -f $DIR/ls
2478 }
2479 run_test 30c "execute binary from Lustre without read perms ===="
2480
2481 test_31a() {
2482         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2483         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2484 }
2485 run_test 31a "open-unlink file =================================="
2486
2487 test_31b() {
2488         touch $DIR/f31 || error "touch $DIR/f31 failed"
2489         ln $DIR/f31 $DIR/f31b || error "ln failed"
2490         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2491         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2492 }
2493 run_test 31b "unlink file with multiple links while open ======="
2494
2495 test_31c() {
2496         touch $DIR/f31 || error "touch $DIR/f31 failed"
2497         ln $DIR/f31 $DIR/f31c || error "ln failed"
2498         multiop_bg_pause $DIR/f31 O_uc ||
2499                 error "multiop_bg_pause for $DIR/f31 failed"
2500         MULTIPID=$!
2501         $MULTIOP $DIR/f31c Ouc
2502         kill -USR1 $MULTIPID
2503         wait $MULTIPID
2504 }
2505 run_test 31c "open-unlink file with multiple links ============="
2506
2507 test_31d() {
2508         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2509         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2510 }
2511 run_test 31d "remove of open directory ========================="
2512
2513 test_31e() { # bug 2904
2514         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2515 }
2516 run_test 31e "remove of open non-empty directory ==============="
2517
2518 test_31f() { # bug 4554
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520
2521         set -vx
2522         test_mkdir $DIR/d31f
2523         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2524         cp /etc/hosts $DIR/d31f
2525         ls -l $DIR/d31f
2526         $LFS getstripe $DIR/d31f/hosts
2527         multiop_bg_pause $DIR/d31f D_c || return 1
2528         MULTIPID=$!
2529
2530         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2531         test_mkdir $DIR/d31f
2532         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2533         cp /etc/hosts $DIR/d31f
2534         ls -l $DIR/d31f
2535         $LFS getstripe $DIR/d31f/hosts
2536         multiop_bg_pause $DIR/d31f D_c || return 1
2537         MULTIPID2=$!
2538
2539         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2540         wait $MULTIPID || error "first opendir $MULTIPID failed"
2541
2542         sleep 6
2543
2544         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2545         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2546         set +vx
2547 }
2548 run_test 31f "remove of open directory with open-unlink file ==="
2549
2550 test_31g() {
2551         echo "-- cross directory link --"
2552         test_mkdir -c1 $DIR/${tdir}ga
2553         test_mkdir -c1 $DIR/${tdir}gb
2554         touch $DIR/${tdir}ga/f
2555         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2556         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2557         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2558         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2559         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2560 }
2561 run_test 31g "cross directory link==============="
2562
2563 test_31h() {
2564         echo "-- cross directory link --"
2565         test_mkdir -c1 $DIR/${tdir}
2566         test_mkdir -c1 $DIR/${tdir}/dir
2567         touch $DIR/${tdir}/f
2568         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2569         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2570         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2571         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2572         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2573 }
2574 run_test 31h "cross directory link under child==============="
2575
2576 test_31i() {
2577         echo "-- cross directory link --"
2578         test_mkdir -c1 $DIR/$tdir
2579         test_mkdir -c1 $DIR/$tdir/dir
2580         touch $DIR/$tdir/dir/f
2581         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2582         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2583         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2584         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2585         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2586 }
2587 run_test 31i "cross directory link under parent==============="
2588
2589 test_31j() {
2590         test_mkdir -c1 -p $DIR/$tdir
2591         test_mkdir -c1 -p $DIR/$tdir/dir1
2592         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2593         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2594         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2595         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2596         return 0
2597 }
2598 run_test 31j "link for directory==============="
2599
2600 test_31k() {
2601         test_mkdir -c1 -p $DIR/$tdir
2602         touch $DIR/$tdir/s
2603         touch $DIR/$tdir/exist
2604         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2605         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2606         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2607         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2608         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2609         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2610         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2611         return 0
2612 }
2613 run_test 31k "link to file: the same, non-existing, dir==============="
2614
2615 test_31m() {
2616         mkdir $DIR/d31m
2617         touch $DIR/d31m/s
2618         mkdir $DIR/d31m2
2619         touch $DIR/d31m2/exist
2620         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2621         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2622         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2623         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2624         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2625         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2626         return 0
2627 }
2628 run_test 31m "link to file: the same, non-existing, dir==============="
2629
2630 test_31n() {
2631         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2632         nlink=$(stat --format=%h $DIR/$tfile)
2633         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2634         local fd=$(free_fd)
2635         local cmd="exec $fd<$DIR/$tfile"
2636         eval $cmd
2637         cmd="exec $fd<&-"
2638         trap "eval $cmd" EXIT
2639         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2640         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2641         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2643         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2644         eval $cmd
2645 }
2646 run_test 31n "check link count of unlinked file"
2647
2648 link_one() {
2649         local TEMPNAME=$(mktemp $1_XXXXXX)
2650         mlink $TEMPNAME $1 2> /dev/null &&
2651                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2652         munlink $TEMPNAME
2653 }
2654
2655 test_31o() { # LU-2901
2656         test_mkdir $DIR/$tdir
2657         for LOOP in $(seq 100); do
2658                 rm -f $DIR/$tdir/$tfile*
2659                 for THREAD in $(seq 8); do
2660                         link_one $DIR/$tdir/$tfile.$LOOP &
2661                 done
2662                 wait
2663                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2664                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2665                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2666                         break || true
2667         done
2668 }
2669 run_test 31o "duplicate hard links with same filename"
2670
2671 test_31p() {
2672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2673
2674         test_mkdir $DIR/$tdir
2675         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2676         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2677
2678         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2679                 error "open unlink test1 failed"
2680         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2681                 error "open unlink test2 failed"
2682
2683         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2684                 error "test1 still exists"
2685         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2686                 error "test2 still exists"
2687 }
2688 run_test 31p "remove of open striped directory"
2689
2690 cleanup_test32_mount() {
2691         local rc=0
2692         trap 0
2693         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2694         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2695         losetup -d $loopdev || true
2696         rm -rf $DIR/$tdir
2697         return $rc
2698 }
2699
2700 test_32a() {
2701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2702
2703         echo "== more mountpoints and symlinks ================="
2704         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2705         trap cleanup_test32_mount EXIT
2706         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2707         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2708                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2709         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2710                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2711         cleanup_test32_mount
2712 }
2713 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2714
2715 test_32b() {
2716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2717
2718         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2719         trap cleanup_test32_mount EXIT
2720         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2721         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2722                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2723         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2724                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2725         cleanup_test32_mount
2726 }
2727 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2728
2729 test_32c() {
2730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2731
2732         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2733         trap cleanup_test32_mount EXIT
2734         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2735         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2736                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2737         test_mkdir -p $DIR/$tdir/d2/test_dir
2738         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2739                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2740         cleanup_test32_mount
2741 }
2742 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2743
2744 test_32d() {
2745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2746
2747         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2748         trap cleanup_test32_mount EXIT
2749         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2750         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2751                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2752         test_mkdir -p $DIR/$tdir/d2/test_dir
2753         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2754                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2755         cleanup_test32_mount
2756 }
2757 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2758
2759 test_32e() {
2760         rm -fr $DIR/$tdir
2761         test_mkdir -p $DIR/$tdir/tmp
2762         local tmp_dir=$DIR/$tdir/tmp
2763         ln -s $DIR/$tdir $tmp_dir/symlink11
2764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2765         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2766         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2767 }
2768 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2769
2770 test_32f() {
2771         rm -fr $DIR/$tdir
2772         test_mkdir -p $DIR/$tdir/tmp
2773         local tmp_dir=$DIR/$tdir/tmp
2774         ln -s $DIR/$tdir $tmp_dir/symlink11
2775         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2776         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2777         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2778 }
2779 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2780
2781 test_32g() {
2782         local tmp_dir=$DIR/$tdir/tmp
2783         test_mkdir -p $tmp_dir
2784         test_mkdir $DIR/${tdir}2
2785         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2786         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2787         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2788         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2789         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2790         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2791 }
2792 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2793
2794 test_32h() {
2795         rm -fr $DIR/$tdir $DIR/${tdir}2
2796         tmp_dir=$DIR/$tdir/tmp
2797         test_mkdir -p $tmp_dir
2798         test_mkdir $DIR/${tdir}2
2799         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2800         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2801         ls $tmp_dir/symlink12 || error "listing symlink12"
2802         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2803 }
2804 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2805
2806 test_32i() {
2807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2808
2809         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2810         trap cleanup_test32_mount EXIT
2811         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2812         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2813                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2814         touch $DIR/$tdir/test_file
2815         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2816                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2817         cleanup_test32_mount
2818 }
2819 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2820
2821 test_32j() {
2822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2823
2824         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2825         trap cleanup_test32_mount EXIT
2826         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2827         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2828                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2829         touch $DIR/$tdir/test_file
2830         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2831                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2832         cleanup_test32_mount
2833 }
2834 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2835
2836 test_32k() {
2837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2838
2839         rm -fr $DIR/$tdir
2840         trap cleanup_test32_mount EXIT
2841         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2842         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2843                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2844         test_mkdir -p $DIR/$tdir/d2
2845         touch $DIR/$tdir/d2/test_file || error "touch failed"
2846         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2847                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2848         cleanup_test32_mount
2849 }
2850 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2851
2852 test_32l() {
2853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2854
2855         rm -fr $DIR/$tdir
2856         trap cleanup_test32_mount EXIT
2857         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2858         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2859                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2860         test_mkdir -p $DIR/$tdir/d2
2861         touch $DIR/$tdir/d2/test_file || error "touch failed"
2862         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2863                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2864         cleanup_test32_mount
2865 }
2866 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2867
2868 test_32m() {
2869         rm -fr $DIR/d32m
2870         test_mkdir -p $DIR/d32m/tmp
2871         TMP_DIR=$DIR/d32m/tmp
2872         ln -s $DIR $TMP_DIR/symlink11
2873         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2874         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2875                 error "symlink11 not a link"
2876         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2877                 error "symlink01 not a link"
2878 }
2879 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2880
2881 test_32n() {
2882         rm -fr $DIR/d32n
2883         test_mkdir -p $DIR/d32n/tmp
2884         TMP_DIR=$DIR/d32n/tmp
2885         ln -s $DIR $TMP_DIR/symlink11
2886         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2887         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2888         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2889 }
2890 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2891
2892 test_32o() {
2893         touch $DIR/$tfile
2894         test_mkdir -p $DIR/d32o/tmp
2895         TMP_DIR=$DIR/d32o/tmp
2896         ln -s $DIR/$tfile $TMP_DIR/symlink12
2897         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2898         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2899                 error "symlink12 not a link"
2900         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2901         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2902                 error "$DIR/d32o/tmp/symlink12 not file type"
2903         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2904                 error "$DIR/d32o/symlink02 not file type"
2905 }
2906 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2907
2908 test_32p() {
2909         log 32p_1
2910         rm -fr $DIR/d32p
2911         log 32p_2
2912         rm -f $DIR/$tfile
2913         log 32p_3
2914         touch $DIR/$tfile
2915         log 32p_4
2916         test_mkdir -p $DIR/d32p/tmp
2917         log 32p_5
2918         TMP_DIR=$DIR/d32p/tmp
2919         log 32p_6
2920         ln -s $DIR/$tfile $TMP_DIR/symlink12
2921         log 32p_7
2922         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2923         log 32p_8
2924         cat $DIR/d32p/tmp/symlink12 ||
2925                 error "Can't open $DIR/d32p/tmp/symlink12"
2926         log 32p_9
2927         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2928         log 32p_10
2929 }
2930 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2931
2932 test_32q() {
2933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2934
2935         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2936         trap cleanup_test32_mount EXIT
2937         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2938         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2941         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2942         cleanup_test32_mount
2943 }
2944 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2945
2946 test_32r() {
2947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2948
2949         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2950         trap cleanup_test32_mount EXIT
2951         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2952         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2953         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2954                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2955         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2956         cleanup_test32_mount
2957 }
2958 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2959
2960 test_33aa() {
2961         rm -f $DIR/$tfile
2962         touch $DIR/$tfile
2963         chmod 444 $DIR/$tfile
2964         chown $RUNAS_ID $DIR/$tfile
2965         log 33_1
2966         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2967         log 33_2
2968 }
2969 run_test 33aa "write file with mode 444 (should return error)"
2970
2971 test_33a() {
2972         rm -fr $DIR/$tdir
2973         test_mkdir $DIR/$tdir
2974         chown $RUNAS_ID $DIR/$tdir
2975         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2976                 error "$RUNAS create $tdir/$tfile failed"
2977         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2978                 error "open RDWR" || true
2979 }
2980 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2981
2982 test_33b() {
2983         rm -fr $DIR/$tdir
2984         test_mkdir $DIR/$tdir
2985         chown $RUNAS_ID $DIR/$tdir
2986         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2987 }
2988 run_test 33b "test open file with malformed flags (No panic)"
2989
2990 test_33c() {
2991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2992         remote_ost_nodsh && skip "remote OST with nodsh"
2993
2994         local ostnum
2995         local ostname
2996         local write_bytes
2997         local all_zeros
2998
2999         all_zeros=:
3000         rm -fr $DIR/$tdir
3001         test_mkdir $DIR/$tdir
3002         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3003
3004         sync
3005         for ostnum in $(seq $OSTCOUNT); do
3006                 # test-framework's OST numbering is one-based, while Lustre's
3007                 # is zero-based
3008                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3009                 # Parsing llobdstat's output sucks; we could grep the /proc
3010                 # path, but that's likely to not be as portable as using the
3011                 # llobdstat utility.  So we parse lctl output instead.
3012                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3013                         obdfilter/$ostname/stats |
3014                         awk '/^write_bytes/ {print $7}' )
3015                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3016                 if (( ${write_bytes:-0} > 0 ))
3017                 then
3018                         all_zeros=false
3019                         break;
3020                 fi
3021         done
3022
3023         $all_zeros || return 0
3024
3025         # Write four bytes
3026         echo foo > $DIR/$tdir/bar
3027         # Really write them
3028         sync
3029
3030         # Total up write_bytes after writing.  We'd better find non-zeros.
3031         for ostnum in $(seq $OSTCOUNT); do
3032                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3033                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3034                         obdfilter/$ostname/stats |
3035                         awk '/^write_bytes/ {print $7}' )
3036                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3037                 if (( ${write_bytes:-0} > 0 ))
3038                 then
3039                         all_zeros=false
3040                         break;
3041                 fi
3042         done
3043
3044         if $all_zeros
3045         then
3046                 for ostnum in $(seq $OSTCOUNT); do
3047                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3048                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3049                         do_facet ost$ostnum lctl get_param -n \
3050                                 obdfilter/$ostname/stats
3051                 done
3052                 error "OST not keeping write_bytes stats (b22312)"
3053         fi
3054 }
3055 run_test 33c "test llobdstat and write_bytes"
3056
3057 test_33d() {
3058         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         local MDTIDX=1
3062         local remote_dir=$DIR/$tdir/remote_dir
3063
3064         test_mkdir $DIR/$tdir
3065         $LFS mkdir -i $MDTIDX $remote_dir ||
3066                 error "create remote directory failed"
3067
3068         touch $remote_dir/$tfile
3069         chmod 444 $remote_dir/$tfile
3070         chown $RUNAS_ID $remote_dir/$tfile
3071
3072         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3073
3074         chown $RUNAS_ID $remote_dir
3075         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3076                                         error "create" || true
3077         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3078                                     error "open RDWR" || true
3079         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3080 }
3081 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3082
3083 test_33e() {
3084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3085
3086         mkdir $DIR/$tdir
3087
3088         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3089         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3090         mkdir $DIR/$tdir/local_dir
3091
3092         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3093         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3094         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3095
3096         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3097                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3098
3099         rmdir $DIR/$tdir/* || error "rmdir failed"
3100
3101         umask 777
3102         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3103         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3104         mkdir $DIR/$tdir/local_dir
3105
3106         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3107         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3108         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3109
3110         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3111                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3112
3113         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3114
3115         umask 000
3116         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3117         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3118         mkdir $DIR/$tdir/local_dir
3119
3120         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3121         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3122         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3123
3124         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3125                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3126 }
3127 run_test 33e "mkdir and striped directory should have same mode"
3128
3129 cleanup_33f() {
3130         trap 0
3131         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3132 }
3133
3134 test_33f() {
3135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3136         remote_mds_nodsh && skip "remote MDS with nodsh"
3137
3138         mkdir $DIR/$tdir
3139         chmod go+rwx $DIR/$tdir
3140         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3141         trap cleanup_33f EXIT
3142
3143         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3144                 error "cannot create striped directory"
3145
3146         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3147                 error "cannot create files in striped directory"
3148
3149         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3150                 error "cannot remove files in striped directory"
3151
3152         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3153                 error "cannot remove striped directory"
3154
3155         cleanup_33f
3156 }
3157 run_test 33f "nonroot user can create, access, and remove a striped directory"
3158
3159 test_33g() {
3160         mkdir -p $DIR/$tdir/dir2
3161
3162         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3163         echo $err
3164         [[ $err =~ "exists" ]] || error "Not exists error"
3165 }
3166 run_test 33g "nonroot user create already existing root created file"
3167
3168 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3169 test_34a() {
3170         rm -f $DIR/f34
3171         $MCREATE $DIR/f34 || error "mcreate failed"
3172         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3173                 error "getstripe failed"
3174         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3175         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3176                 error "getstripe failed"
3177         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3178                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3179 }
3180 run_test 34a "truncate file that has not been opened ==========="
3181
3182 test_34b() {
3183         [ ! -f $DIR/f34 ] && test_34a
3184         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3185                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3186         $OPENFILE -f O_RDONLY $DIR/f34
3187         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3188                 error "getstripe failed"
3189         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3190                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3191 }
3192 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3193
3194 test_34c() {
3195         [ ! -f $DIR/f34 ] && test_34a
3196         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3197                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3198         $OPENFILE -f O_RDWR $DIR/f34
3199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3200                 error "$LFS getstripe failed"
3201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3203 }
3204 run_test 34c "O_RDWR opening file-with-size works =============="
3205
3206 test_34d() {
3207         [ ! -f $DIR/f34 ] && test_34a
3208         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3209                 error "dd failed"
3210         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3211                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3212         rm $DIR/f34
3213 }
3214 run_test 34d "write to sparse file ============================="
3215
3216 test_34e() {
3217         rm -f $DIR/f34e
3218         $MCREATE $DIR/f34e || error "mcreate failed"
3219         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3220         $CHECKSTAT -s 1000 $DIR/f34e ||
3221                 error "Size of $DIR/f34e not equal to 1000 bytes"
3222         $OPENFILE -f O_RDWR $DIR/f34e
3223         $CHECKSTAT -s 1000 $DIR/f34e ||
3224                 error "Size of $DIR/f34e not equal to 1000 bytes"
3225 }
3226 run_test 34e "create objects, some with size and some without =="
3227
3228 test_34f() { # bug 6242, 6243
3229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3230
3231         SIZE34F=48000
3232         rm -f $DIR/f34f
3233         $MCREATE $DIR/f34f || error "mcreate failed"
3234         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3235         dd if=$DIR/f34f of=$TMP/f34f
3236         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3237         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3238         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3239         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3240         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3241 }
3242 run_test 34f "read from a file with no objects until EOF ======="
3243
3244 test_34g() {
3245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3246
3247         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3248                 error "dd failed"
3249         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3250         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3251                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3252         cancel_lru_locks osc
3253         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3254                 error "wrong size after lock cancel"
3255
3256         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3257         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3258                 error "expanding truncate failed"
3259         cancel_lru_locks osc
3260         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3261                 error "wrong expanded size after lock cancel"
3262 }
3263 run_test 34g "truncate long file ==============================="
3264
3265 test_34h() {
3266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3267
3268         local gid=10
3269         local sz=1000
3270
3271         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3272         sync # Flush the cache so that multiop below does not block on cache
3273              # flush when getting the group lock
3274         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3275         MULTIPID=$!
3276
3277         # Since just timed wait is not good enough, let's do a sync write
3278         # that way we are sure enough time for a roundtrip + processing
3279         # passed + 2 seconds of extra margin.
3280         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3281         rm $DIR/${tfile}-1
3282         sleep 2
3283
3284         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3285                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3286                 kill -9 $MULTIPID
3287         fi
3288         wait $MULTIPID
3289         local nsz=`stat -c %s $DIR/$tfile`
3290         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3291 }
3292 run_test 34h "ftruncate file under grouplock should not block"
3293
3294 test_35a() {
3295         cp /bin/sh $DIR/f35a
3296         chmod 444 $DIR/f35a
3297         chown $RUNAS_ID $DIR/f35a
3298         $RUNAS $DIR/f35a && error || true
3299         rm $DIR/f35a
3300 }
3301 run_test 35a "exec file with mode 444 (should return and not leak)"
3302
3303 test_36a() {
3304         rm -f $DIR/f36
3305         utime $DIR/f36 || error "utime failed for MDS"
3306 }
3307 run_test 36a "MDS utime check (mknod, utime)"
3308
3309 test_36b() {
3310         echo "" > $DIR/f36
3311         utime $DIR/f36 || error "utime failed for OST"
3312 }
3313 run_test 36b "OST utime check (open, utime)"
3314
3315 test_36c() {
3316         rm -f $DIR/d36/f36
3317         test_mkdir $DIR/d36
3318         chown $RUNAS_ID $DIR/d36
3319         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3320 }
3321 run_test 36c "non-root MDS utime check (mknod, utime)"
3322
3323 test_36d() {
3324         [ ! -d $DIR/d36 ] && test_36c
3325         echo "" > $DIR/d36/f36
3326         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3327 }
3328 run_test 36d "non-root OST utime check (open, utime)"
3329
3330 test_36e() {
3331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3332
3333         test_mkdir $DIR/$tdir
3334         touch $DIR/$tdir/$tfile
3335         $RUNAS utime $DIR/$tdir/$tfile &&
3336                 error "utime worked, expected failure" || true
3337 }
3338 run_test 36e "utime on non-owned file (should return error)"
3339
3340 subr_36fh() {
3341         local fl="$1"
3342         local LANG_SAVE=$LANG
3343         local LC_LANG_SAVE=$LC_LANG
3344         export LANG=C LC_LANG=C # for date language
3345
3346         DATESTR="Dec 20  2000"
3347         test_mkdir $DIR/$tdir
3348         lctl set_param fail_loc=$fl
3349         date; date +%s
3350         cp /etc/hosts $DIR/$tdir/$tfile
3351         sync & # write RPC generated with "current" inode timestamp, but delayed
3352         sleep 1
3353         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3354         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3355         cancel_lru_locks $OSC
3356         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3357         date; date +%s
3358         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3359                 echo "BEFORE: $LS_BEFORE" && \
3360                 echo "AFTER : $LS_AFTER" && \
3361                 echo "WANT  : $DATESTR" && \
3362                 error "$DIR/$tdir/$tfile timestamps changed" || true
3363
3364         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3365 }
3366
3367 test_36f() {
3368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3369
3370         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3371         subr_36fh "0x80000214"
3372 }
3373 run_test 36f "utime on file racing with OST BRW write =========="
3374
3375 test_36g() {
3376         remote_ost_nodsh && skip "remote OST with nodsh"
3377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3378         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3379                 skip "Need MDS version at least 2.12.51"
3380
3381         local fmd_max_age
3382         local fmd
3383         local facet="ost1"
3384         local tgt="obdfilter"
3385
3386         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3387
3388         test_mkdir $DIR/$tdir
3389         fmd_max_age=$(do_facet $facet \
3390                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3391                 head -n 1")
3392
3393         echo "FMD max age: ${fmd_max_age}s"
3394         touch $DIR/$tdir/$tfile
3395         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3396                 gawk '{cnt=cnt+$1}  END{print cnt}')
3397         echo "FMD before: $fmd"
3398         [[ $fmd == 0 ]] &&
3399                 error "FMD wasn't create by touch"
3400         sleep $((fmd_max_age + 12))
3401         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3402                 gawk '{cnt=cnt+$1}  END{print cnt}')
3403         echo "FMD after: $fmd"
3404         [[ $fmd == 0 ]] ||
3405                 error "FMD wasn't expired by ping"
3406 }
3407 run_test 36g "FMD cache expiry ====================="
3408
3409 test_36h() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3413         subr_36fh "0x80000227"
3414 }
3415 run_test 36h "utime on file racing with OST BRW write =========="
3416
3417 test_36i() {
3418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3419
3420         test_mkdir $DIR/$tdir
3421         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3422
3423         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3424         local new_mtime=$((mtime + 200))
3425
3426         #change Modify time of striped dir
3427         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3428                         error "change mtime failed"
3429
3430         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3431
3432         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3433 }
3434 run_test 36i "change mtime on striped directory"
3435
3436 # test_37 - duplicate with tests 32q 32r
3437
3438 test_38() {
3439         local file=$DIR/$tfile
3440         touch $file
3441         openfile -f O_DIRECTORY $file
3442         local RC=$?
3443         local ENOTDIR=20
3444         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3445         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3446 }
3447 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3448
3449 test_39a() { # was test_39
3450         touch $DIR/$tfile
3451         touch $DIR/${tfile}2
3452 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3453 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3454 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3455         sleep 2
3456         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3457         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3458                 echo "mtime"
3459                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3460                 echo "atime"
3461                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3462                 echo "ctime"
3463                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3464                 error "O_TRUNC didn't change timestamps"
3465         fi
3466 }
3467 run_test 39a "mtime changed on create"
3468
3469 test_39b() {
3470         test_mkdir -c1 $DIR/$tdir
3471         cp -p /etc/passwd $DIR/$tdir/fopen
3472         cp -p /etc/passwd $DIR/$tdir/flink
3473         cp -p /etc/passwd $DIR/$tdir/funlink
3474         cp -p /etc/passwd $DIR/$tdir/frename
3475         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3476
3477         sleep 1
3478         echo "aaaaaa" >> $DIR/$tdir/fopen
3479         echo "aaaaaa" >> $DIR/$tdir/flink
3480         echo "aaaaaa" >> $DIR/$tdir/funlink
3481         echo "aaaaaa" >> $DIR/$tdir/frename
3482
3483         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3484         local link_new=`stat -c %Y $DIR/$tdir/flink`
3485         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3486         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3487
3488         cat $DIR/$tdir/fopen > /dev/null
3489         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3490         rm -f $DIR/$tdir/funlink2
3491         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3492
3493         for (( i=0; i < 2; i++ )) ; do
3494                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3495                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3496                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3497                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3498
3499                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3500                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3501                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3502                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3503
3504                 cancel_lru_locks $OSC
3505                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3506         done
3507 }
3508 run_test 39b "mtime change on open, link, unlink, rename  ======"
3509
3510 # this should be set to past
3511 TEST_39_MTIME=`date -d "1 year ago" +%s`
3512
3513 # bug 11063
3514 test_39c() {
3515         touch $DIR1/$tfile
3516         sleep 2
3517         local mtime0=`stat -c %Y $DIR1/$tfile`
3518
3519         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3520         local mtime1=`stat -c %Y $DIR1/$tfile`
3521         [ "$mtime1" = $TEST_39_MTIME ] || \
3522                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3523
3524         local d1=`date +%s`
3525         echo hello >> $DIR1/$tfile
3526         local d2=`date +%s`
3527         local mtime2=`stat -c %Y $DIR1/$tfile`
3528         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3529                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3530
3531         mv $DIR1/$tfile $DIR1/$tfile-1
3532
3533         for (( i=0; i < 2; i++ )) ; do
3534                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3535                 [ "$mtime2" = "$mtime3" ] || \
3536                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3537
3538                 cancel_lru_locks $OSC
3539                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3540         done
3541 }
3542 run_test 39c "mtime change on rename ==========================="
3543
3544 # bug 21114
3545 test_39d() {
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         touch $DIR1/$tfile
3549         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3550
3551         for (( i=0; i < 2; i++ )) ; do
3552                 local mtime=`stat -c %Y $DIR1/$tfile`
3553                 [ $mtime = $TEST_39_MTIME ] || \
3554                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3555
3556                 cancel_lru_locks $OSC
3557                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3558         done
3559 }
3560 run_test 39d "create, utime, stat =============================="
3561
3562 # bug 21114
3563 test_39e() {
3564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3565
3566         touch $DIR1/$tfile
3567         local mtime1=`stat -c %Y $DIR1/$tfile`
3568
3569         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3570
3571         for (( i=0; i < 2; i++ )) ; do
3572                 local mtime2=`stat -c %Y $DIR1/$tfile`
3573                 [ $mtime2 = $TEST_39_MTIME ] || \
3574                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3575
3576                 cancel_lru_locks $OSC
3577                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3578         done
3579 }
3580 run_test 39e "create, stat, utime, stat ========================"
3581
3582 # bug 21114
3583 test_39f() {
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         touch $DIR1/$tfile
3587         mtime1=`stat -c %Y $DIR1/$tfile`
3588
3589         sleep 2
3590         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3591
3592         for (( i=0; i < 2; i++ )) ; do
3593                 local mtime2=`stat -c %Y $DIR1/$tfile`
3594                 [ $mtime2 = $TEST_39_MTIME ] || \
3595                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3596
3597                 cancel_lru_locks $OSC
3598                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3599         done
3600 }
3601 run_test 39f "create, stat, sleep, utime, stat ================="
3602
3603 # bug 11063
3604 test_39g() {
3605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3606
3607         echo hello >> $DIR1/$tfile
3608         local mtime1=`stat -c %Y $DIR1/$tfile`
3609
3610         sleep 2
3611         chmod o+r $DIR1/$tfile
3612
3613         for (( i=0; i < 2; i++ )) ; do
3614                 local mtime2=`stat -c %Y $DIR1/$tfile`
3615                 [ "$mtime1" = "$mtime2" ] || \
3616                         error "lost mtime: $mtime2, should be $mtime1"
3617
3618                 cancel_lru_locks $OSC
3619                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3620         done
3621 }
3622 run_test 39g "write, chmod, stat ==============================="
3623
3624 # bug 11063
3625 test_39h() {
3626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3627
3628         touch $DIR1/$tfile
3629         sleep 1
3630
3631         local d1=`date`
3632         echo hello >> $DIR1/$tfile
3633         local mtime1=`stat -c %Y $DIR1/$tfile`
3634
3635         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3636         local d2=`date`
3637         if [ "$d1" != "$d2" ]; then
3638                 echo "write and touch not within one second"
3639         else
3640                 for (( i=0; i < 2; i++ )) ; do
3641                         local mtime2=`stat -c %Y $DIR1/$tfile`
3642                         [ "$mtime2" = $TEST_39_MTIME ] || \
3643                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3644
3645                         cancel_lru_locks $OSC
3646                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3647                 done
3648         fi
3649 }
3650 run_test 39h "write, utime within one second, stat ============="
3651
3652 test_39i() {
3653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3654
3655         touch $DIR1/$tfile
3656         sleep 1
3657
3658         echo hello >> $DIR1/$tfile
3659         local mtime1=`stat -c %Y $DIR1/$tfile`
3660
3661         mv $DIR1/$tfile $DIR1/$tfile-1
3662
3663         for (( i=0; i < 2; i++ )) ; do
3664                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3665
3666                 [ "$mtime1" = "$mtime2" ] || \
3667                         error "lost mtime: $mtime2, should be $mtime1"
3668
3669                 cancel_lru_locks $OSC
3670                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3671         done
3672 }
3673 run_test 39i "write, rename, stat =============================="
3674
3675 test_39j() {
3676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3677
3678         start_full_debug_logging
3679         touch $DIR1/$tfile
3680         sleep 1
3681
3682         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3683         lctl set_param fail_loc=0x80000412
3684         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3685                 error "multiop failed"
3686         local multipid=$!
3687         local mtime1=`stat -c %Y $DIR1/$tfile`
3688
3689         mv $DIR1/$tfile $DIR1/$tfile-1
3690
3691         kill -USR1 $multipid
3692         wait $multipid || error "multiop close failed"
3693
3694         for (( i=0; i < 2; i++ )) ; do
3695                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3696                 [ "$mtime1" = "$mtime2" ] ||
3697                         error "mtime is lost on close: $mtime2, " \
3698                               "should be $mtime1"
3699
3700                 cancel_lru_locks $OSC
3701                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3702         done
3703         lctl set_param fail_loc=0
3704         stop_full_debug_logging
3705 }
3706 run_test 39j "write, rename, close, stat ======================="
3707
3708 test_39k() {
3709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3710
3711         touch $DIR1/$tfile
3712         sleep 1
3713
3714         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3715         local multipid=$!
3716         local mtime1=`stat -c %Y $DIR1/$tfile`
3717
3718         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3719
3720         kill -USR1 $multipid
3721         wait $multipid || error "multiop close failed"
3722
3723         for (( i=0; i < 2; i++ )) ; do
3724                 local mtime2=`stat -c %Y $DIR1/$tfile`
3725
3726                 [ "$mtime2" = $TEST_39_MTIME ] || \
3727                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3728
3729                 cancel_lru_locks osc
3730                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3731         done
3732 }
3733 run_test 39k "write, utime, close, stat ========================"
3734
3735 # this should be set to future
3736 TEST_39_ATIME=`date -d "1 year" +%s`
3737
3738 test_39l() {
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3740         remote_mds_nodsh && skip "remote MDS with nodsh"
3741
3742         local atime_diff=$(do_facet $SINGLEMDS \
3743                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3744         rm -rf $DIR/$tdir
3745         mkdir -p $DIR/$tdir
3746
3747         # test setting directory atime to future
3748         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3749         local atime=$(stat -c %X $DIR/$tdir)
3750         [ "$atime" = $TEST_39_ATIME ] ||
3751                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3752
3753         # test setting directory atime from future to now
3754         local now=$(date +%s)
3755         touch -a -d @$now $DIR/$tdir
3756
3757         atime=$(stat -c %X $DIR/$tdir)
3758         [ "$atime" -eq "$now"  ] ||
3759                 error "atime is not updated from future: $atime, $now"
3760
3761         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3762         sleep 3
3763
3764         # test setting directory atime when now > dir atime + atime_diff
3765         local d1=$(date +%s)
3766         ls $DIR/$tdir
3767         local d2=$(date +%s)
3768         cancel_lru_locks mdc
3769         atime=$(stat -c %X $DIR/$tdir)
3770         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3771                 error "atime is not updated  : $atime, should be $d2"
3772
3773         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3774         sleep 3
3775
3776         # test not setting directory atime when now < dir atime + atime_diff
3777         ls $DIR/$tdir
3778         cancel_lru_locks mdc
3779         atime=$(stat -c %X $DIR/$tdir)
3780         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3781                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3782
3783         do_facet $SINGLEMDS \
3784                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3785 }
3786 run_test 39l "directory atime update ==========================="
3787
3788 test_39m() {
3789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3790
3791         touch $DIR1/$tfile
3792         sleep 2
3793         local far_past_mtime=$(date -d "May 29 1953" +%s)
3794         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3795
3796         touch -m -d @$far_past_mtime $DIR1/$tfile
3797         touch -a -d @$far_past_atime $DIR1/$tfile
3798
3799         for (( i=0; i < 2; i++ )) ; do
3800                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3801                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3802                         error "atime or mtime set incorrectly"
3803
3804                 cancel_lru_locks $OSC
3805                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3806         done
3807 }
3808 run_test 39m "test atime and mtime before 1970"
3809
3810 test_39n() { # LU-3832
3811         remote_mds_nodsh && skip "remote MDS with nodsh"
3812
3813         local atime_diff=$(do_facet $SINGLEMDS \
3814                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3815         local atime0
3816         local atime1
3817         local atime2
3818
3819         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3820
3821         rm -rf $DIR/$tfile
3822         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3823         atime0=$(stat -c %X $DIR/$tfile)
3824
3825         sleep 5
3826         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3827         atime1=$(stat -c %X $DIR/$tfile)
3828
3829         sleep 5
3830         cancel_lru_locks mdc
3831         cancel_lru_locks osc
3832         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3833         atime2=$(stat -c %X $DIR/$tfile)
3834
3835         do_facet $SINGLEMDS \
3836                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3837
3838         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3839         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3840 }
3841 run_test 39n "check that O_NOATIME is honored"
3842
3843 test_39o() {
3844         TESTDIR=$DIR/$tdir/$tfile
3845         [ -e $TESTDIR ] && rm -rf $TESTDIR
3846         mkdir -p $TESTDIR
3847         cd $TESTDIR
3848         links1=2
3849         ls
3850         mkdir a b
3851         ls
3852         links2=$(stat -c %h .)
3853         [ $(($links1 + 2)) != $links2 ] &&
3854                 error "wrong links count $(($links1 + 2)) != $links2"
3855         rmdir b
3856         links3=$(stat -c %h .)
3857         [ $(($links1 + 1)) != $links3 ] &&
3858                 error "wrong links count $links1 != $links3"
3859         return 0
3860 }
3861 run_test 39o "directory cached attributes updated after create"
3862
3863 test_39p() {
3864         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3865
3866         local MDTIDX=1
3867         TESTDIR=$DIR/$tdir/$tdir
3868         [ -e $TESTDIR ] && rm -rf $TESTDIR
3869         test_mkdir -p $TESTDIR
3870         cd $TESTDIR
3871         links1=2
3872         ls
3873         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3874         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3875         ls
3876         links2=$(stat -c %h .)
3877         [ $(($links1 + 2)) != $links2 ] &&
3878                 error "wrong links count $(($links1 + 2)) != $links2"
3879         rmdir remote_dir2
3880         links3=$(stat -c %h .)
3881         [ $(($links1 + 1)) != $links3 ] &&
3882                 error "wrong links count $links1 != $links3"
3883         return 0
3884 }
3885 run_test 39p "remote directory cached attributes updated after create ========"
3886
3887
3888 test_39q() { # LU-8041
3889         local testdir=$DIR/$tdir
3890         mkdir -p $testdir
3891         multiop_bg_pause $testdir D_c || error "multiop failed"
3892         local multipid=$!
3893         cancel_lru_locks mdc
3894         kill -USR1 $multipid
3895         local atime=$(stat -c %X $testdir)
3896         [ "$atime" -ne 0 ] || error "atime is zero"
3897 }
3898 run_test 39q "close won't zero out atime"
3899
3900 test_40() {
3901         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3902         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3903                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3904         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3905                 error "$tfile is not 4096 bytes in size"
3906 }
3907 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3908
3909 test_41() {
3910         # bug 1553
3911         small_write $DIR/f41 18
3912 }
3913 run_test 41 "test small file write + fstat ====================="
3914
3915 count_ost_writes() {
3916         lctl get_param -n ${OSC}.*.stats |
3917                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3918                         END { printf("%0.0f", writes) }'
3919 }
3920
3921 # decent default
3922 WRITEBACK_SAVE=500
3923 DIRTY_RATIO_SAVE=40
3924 MAX_DIRTY_RATIO=50
3925 BG_DIRTY_RATIO_SAVE=10
3926 MAX_BG_DIRTY_RATIO=25
3927
3928 start_writeback() {
3929         trap 0
3930         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3931         # dirty_ratio, dirty_background_ratio
3932         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3933                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3934                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3935                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3936         else
3937                 # if file not here, we are a 2.4 kernel
3938                 kill -CONT `pidof kupdated`
3939         fi
3940 }
3941
3942 stop_writeback() {
3943         # setup the trap first, so someone cannot exit the test at the
3944         # exact wrong time and mess up a machine
3945         trap start_writeback EXIT
3946         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3947         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3948                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3949                 sysctl -w vm.dirty_writeback_centisecs=0
3950                 sysctl -w vm.dirty_writeback_centisecs=0
3951                 # save and increase /proc/sys/vm/dirty_ratio
3952                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3953                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3954                 # save and increase /proc/sys/vm/dirty_background_ratio
3955                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3956                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3957         else
3958                 # if file not here, we are a 2.4 kernel
3959                 kill -STOP `pidof kupdated`
3960         fi
3961 }
3962
3963 # ensure that all stripes have some grant before we test client-side cache
3964 setup_test42() {
3965         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3966                 dd if=/dev/zero of=$i bs=4k count=1
3967                 rm $i
3968         done
3969 }
3970
3971 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3972 # file truncation, and file removal.
3973 test_42a() {
3974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3975
3976         setup_test42
3977         cancel_lru_locks $OSC
3978         stop_writeback
3979         sync; sleep 1; sync # just to be safe
3980         BEFOREWRITES=`count_ost_writes`
3981         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3982         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3983         AFTERWRITES=`count_ost_writes`
3984         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3985                 error "$BEFOREWRITES < $AFTERWRITES"
3986         start_writeback
3987 }
3988 run_test 42a "ensure that we don't flush on close"
3989
3990 test_42b() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         setup_test42
3994         cancel_lru_locks $OSC
3995         stop_writeback
3996         sync
3997         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3998         BEFOREWRITES=$(count_ost_writes)
3999         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4000         AFTERWRITES=$(count_ost_writes)
4001         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4002                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4003         fi
4004         BEFOREWRITES=$(count_ost_writes)
4005         sync || error "sync: $?"
4006         AFTERWRITES=$(count_ost_writes)
4007         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4008                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4009         fi
4010         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4011         start_writeback
4012         return 0
4013 }
4014 run_test 42b "test destroy of file with cached dirty data ======"
4015
4016 # if these tests just want to test the effect of truncation,
4017 # they have to be very careful.  consider:
4018 # - the first open gets a {0,EOF}PR lock
4019 # - the first write conflicts and gets a {0, count-1}PW
4020 # - the rest of the writes are under {count,EOF}PW
4021 # - the open for truncate tries to match a {0,EOF}PR
4022 #   for the filesize and cancels the PWs.
4023 # any number of fixes (don't get {0,EOF} on open, match
4024 # composite locks, do smarter file size management) fix
4025 # this, but for now we want these tests to verify that
4026 # the cancellation with truncate intent works, so we
4027 # start the file with a full-file pw lock to match against
4028 # until the truncate.
4029 trunc_test() {
4030         test=$1
4031         file=$DIR/$test
4032         offset=$2
4033         cancel_lru_locks $OSC
4034         stop_writeback
4035         # prime the file with 0,EOF PW to match
4036         touch $file
4037         $TRUNCATE $file 0
4038         sync; sync
4039         # now the real test..
4040         dd if=/dev/zero of=$file bs=1024 count=100
4041         BEFOREWRITES=`count_ost_writes`
4042         $TRUNCATE $file $offset
4043         cancel_lru_locks $OSC
4044         AFTERWRITES=`count_ost_writes`
4045         start_writeback
4046 }
4047
4048 test_42c() {
4049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4050
4051         trunc_test 42c 1024
4052         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4053                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4054         rm $file
4055 }
4056 run_test 42c "test partial truncate of file with cached dirty data"
4057
4058 test_42d() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         trunc_test 42d 0
4062         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4063                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4064         rm $file
4065 }
4066 run_test 42d "test complete truncate of file with cached dirty data"
4067
4068 test_42e() { # bug22074
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070
4071         local TDIR=$DIR/${tdir}e
4072         local pages=16 # hardcoded 16 pages, don't change it.
4073         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4074         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4075         local max_dirty_mb
4076         local warmup_files
4077
4078         test_mkdir $DIR/${tdir}e
4079         $LFS setstripe -c 1 $TDIR
4080         createmany -o $TDIR/f $files
4081
4082         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4083
4084         # we assume that with $OSTCOUNT files, at least one of them will
4085         # be allocated on OST0.
4086         warmup_files=$((OSTCOUNT * max_dirty_mb))
4087         createmany -o $TDIR/w $warmup_files
4088
4089         # write a large amount of data into one file and sync, to get good
4090         # avail_grant number from OST.
4091         for ((i=0; i<$warmup_files; i++)); do
4092                 idx=$($LFS getstripe -i $TDIR/w$i)
4093                 [ $idx -ne 0 ] && continue
4094                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4095                 break
4096         done
4097         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4098         sync
4099         $LCTL get_param $proc_osc0/cur_dirty_bytes
4100         $LCTL get_param $proc_osc0/cur_grant_bytes
4101
4102         # create as much dirty pages as we can while not to trigger the actual
4103         # RPCs directly. but depends on the env, VFS may trigger flush during this
4104         # period, hopefully we are good.
4105         for ((i=0; i<$warmup_files; i++)); do
4106                 idx=$($LFS getstripe -i $TDIR/w$i)
4107                 [ $idx -ne 0 ] && continue
4108                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4109         done
4110         $LCTL get_param $proc_osc0/cur_dirty_bytes
4111         $LCTL get_param $proc_osc0/cur_grant_bytes
4112
4113         # perform the real test
4114         $LCTL set_param $proc_osc0/rpc_stats 0
4115         for ((;i<$files; i++)); do
4116                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4117                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4118         done
4119         sync
4120         $LCTL get_param $proc_osc0/rpc_stats
4121
4122         local percent=0
4123         local have_ppr=false
4124         $LCTL get_param $proc_osc0/rpc_stats |
4125                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4126                         # skip lines until we are at the RPC histogram data
4127                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4128                         $have_ppr || continue
4129
4130                         # we only want the percent stat for < 16 pages
4131                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4132
4133                         percent=$((percent + WPCT))
4134                         if [[ $percent -gt 15 ]]; then
4135                                 error "less than 16-pages write RPCs" \
4136                                       "$percent% > 15%"
4137                                 break
4138                         fi
4139                 done
4140         rm -rf $TDIR
4141 }
4142 run_test 42e "verify sub-RPC writes are not done synchronously"
4143
4144 test_43A() { # was test_43
4145         test_mkdir $DIR/$tdir
4146         cp -p /bin/ls $DIR/$tdir/$tfile
4147         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4148         pid=$!
4149         # give multiop a chance to open
4150         sleep 1
4151
4152         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4153         kill -USR1 $pid
4154 }
4155 run_test 43A "execution of file opened for write should return -ETXTBSY"
4156
4157 test_43a() {
4158         test_mkdir $DIR/$tdir
4159         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4160         $DIR/$tdir/sleep 60 &
4161         SLEEP_PID=$!
4162         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4163         kill $SLEEP_PID
4164 }
4165 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4166
4167 test_43b() {
4168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4169
4170         test_mkdir $DIR/$tdir
4171         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4172         $DIR/$tdir/sleep 60 &
4173         SLEEP_PID=$!
4174         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4175         kill $SLEEP_PID
4176 }
4177 run_test 43b "truncate of file being executed should return -ETXTBSY"
4178
4179 test_43c() {
4180         local testdir="$DIR/$tdir"
4181         test_mkdir $testdir
4182         cp $SHELL $testdir/
4183         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4184                 ( cd $testdir && md5sum -c )
4185 }
4186 run_test 43c "md5sum of copy into lustre"
4187
4188 test_44A() { # was test_44
4189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4190
4191         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4192         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4193 }
4194 run_test 44A "zero length read from a sparse stripe"
4195
4196 test_44a() {
4197         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4198                 awk '{ print $2 }')
4199         [ -z "$nstripe" ] && skip "can't get stripe info"
4200         [[ $nstripe -gt $OSTCOUNT ]] &&
4201                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4202
4203         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4204                 awk '{ print $2 }')
4205         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4206                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4207                         awk '{ print $2 }')
4208         fi
4209
4210         OFFSETS="0 $((stride/2)) $((stride-1))"
4211         for offset in $OFFSETS; do
4212                 for i in $(seq 0 $((nstripe-1))); do
4213                         local GLOBALOFFSETS=""
4214                         # size in Bytes
4215                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4216                         local myfn=$DIR/d44a-$size
4217                         echo "--------writing $myfn at $size"
4218                         ll_sparseness_write $myfn $size ||
4219                                 error "ll_sparseness_write"
4220                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4221                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4222                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4223
4224                         for j in $(seq 0 $((nstripe-1))); do
4225                                 # size in Bytes
4226                                 size=$((((j + $nstripe )*$stride + $offset)))
4227                                 ll_sparseness_write $myfn $size ||
4228                                         error "ll_sparseness_write"
4229                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4230                         done
4231                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4232                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4233                         rm -f $myfn
4234                 done
4235         done
4236 }
4237 run_test 44a "test sparse pwrite ==============================="
4238
4239 dirty_osc_total() {
4240         tot=0
4241         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4242                 tot=$(($tot + $d))
4243         done
4244         echo $tot
4245 }
4246 do_dirty_record() {
4247         before=`dirty_osc_total`
4248         echo executing "\"$*\""
4249         eval $*
4250         after=`dirty_osc_total`
4251         echo before $before, after $after
4252 }
4253 test_45() {
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         f="$DIR/f45"
4257         # Obtain grants from OST if it supports it
4258         echo blah > ${f}_grant
4259         stop_writeback
4260         sync
4261         do_dirty_record "echo blah > $f"
4262         [[ $before -eq $after ]] && error "write wasn't cached"
4263         do_dirty_record "> $f"
4264         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4265         do_dirty_record "echo blah > $f"
4266         [[ $before -eq $after ]] && error "write wasn't cached"
4267         do_dirty_record "sync"
4268         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4269         do_dirty_record "echo blah > $f"
4270         [[ $before -eq $after ]] && error "write wasn't cached"
4271         do_dirty_record "cancel_lru_locks osc"
4272         [[ $before -gt $after ]] ||
4273                 error "lock cancellation didn't lower dirty count"
4274         start_writeback
4275 }
4276 run_test 45 "osc io page accounting ============================"
4277
4278 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4279 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4280 # objects offset and an assert hit when an rpc was built with 1023's mapped
4281 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4282 test_46() {
4283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4284
4285         f="$DIR/f46"
4286         stop_writeback
4287         sync
4288         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4289         sync
4290         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4291         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4292         sync
4293         start_writeback
4294 }
4295 run_test 46 "dirtying a previously written page ================"
4296
4297 # test_47 is removed "Device nodes check" is moved to test_28
4298
4299 test_48a() { # bug 2399
4300         [ "$mds1_FSTYPE" = "zfs" ] &&
4301         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4302                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4303
4304         test_mkdir $DIR/$tdir
4305         cd $DIR/$tdir
4306         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4307         test_mkdir $DIR/$tdir
4308         touch foo || error "'touch foo' failed after recreating cwd"
4309         test_mkdir bar
4310         touch .foo || error "'touch .foo' failed after recreating cwd"
4311         test_mkdir .bar
4312         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4313         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4314         cd . || error "'cd .' failed after recreating cwd"
4315         mkdir . && error "'mkdir .' worked after recreating cwd"
4316         rmdir . && error "'rmdir .' worked after recreating cwd"
4317         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4318         cd .. || error "'cd ..' failed after recreating cwd"
4319 }
4320 run_test 48a "Access renamed working dir (should return errors)="
4321
4322 test_48b() { # bug 2399
4323         rm -rf $DIR/$tdir
4324         test_mkdir $DIR/$tdir
4325         cd $DIR/$tdir
4326         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4327         touch foo && error "'touch foo' worked after removing cwd"
4328         mkdir foo && error "'mkdir foo' worked after removing cwd"
4329         touch .foo && error "'touch .foo' worked after removing cwd"
4330         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4331         ls . > /dev/null && error "'ls .' worked after removing cwd"
4332         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4333         mkdir . && error "'mkdir .' worked after removing cwd"
4334         rmdir . && error "'rmdir .' worked after removing cwd"
4335         ln -s . foo && error "'ln -s .' worked after removing cwd"
4336         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4337 }
4338 run_test 48b "Access removed working dir (should return errors)="
4339
4340 test_48c() { # bug 2350
4341         #lctl set_param debug=-1
4342         #set -vx
4343         rm -rf $DIR/$tdir
4344         test_mkdir -p $DIR/$tdir/dir
4345         cd $DIR/$tdir/dir
4346         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4347         $TRACE touch foo && error "touch foo worked after removing cwd"
4348         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4349         touch .foo && error "touch .foo worked after removing cwd"
4350         mkdir .foo && error "mkdir .foo worked after removing cwd"
4351         $TRACE ls . && error "'ls .' worked after removing cwd"
4352         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4353         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4354         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4355         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4356         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4357 }
4358 run_test 48c "Access removed working subdir (should return errors)"
4359
4360 test_48d() { # bug 2350
4361         #lctl set_param debug=-1
4362         #set -vx
4363         rm -rf $DIR/$tdir
4364         test_mkdir -p $DIR/$tdir/dir
4365         cd $DIR/$tdir/dir
4366         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4367         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4368         $TRACE touch foo && error "'touch foo' worked after removing parent"
4369         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4370         touch .foo && error "'touch .foo' worked after removing parent"
4371         mkdir .foo && error "mkdir .foo worked after removing parent"
4372         $TRACE ls . && error "'ls .' worked after removing parent"
4373         $TRACE ls .. && error "'ls ..' worked after removing parent"
4374         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4375         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4376         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4377         true
4378 }
4379 run_test 48d "Access removed parent subdir (should return errors)"
4380
4381 test_48e() { # bug 4134
4382         #lctl set_param debug=-1
4383         #set -vx
4384         rm -rf $DIR/$tdir
4385         test_mkdir -p $DIR/$tdir/dir
4386         cd $DIR/$tdir/dir
4387         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4388         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4389         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4390         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4391         # On a buggy kernel addition of "touch foo" after cd .. will
4392         # produce kernel oops in lookup_hash_it
4393         touch ../foo && error "'cd ..' worked after recreate parent"
4394         cd $DIR
4395         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4396 }
4397 run_test 48e "Access to recreated parent subdir (should return errors)"
4398
4399 test_49() { # LU-1030
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402
4403         # get ost1 size - lustre-OST0000
4404         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4405                 awk '{ print $4 }')
4406         # write 800M at maximum
4407         [[ $ost1_size -lt 2 ]] && ost1_size=2
4408         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4409
4410         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4411         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4412         local dd_pid=$!
4413
4414         # change max_pages_per_rpc while writing the file
4415         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4416         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4417         # loop until dd process exits
4418         while ps ax -opid | grep -wq $dd_pid; do
4419                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4420                 sleep $((RANDOM % 5 + 1))
4421         done
4422         # restore original max_pages_per_rpc
4423         $LCTL set_param $osc1_mppc=$orig_mppc
4424         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4425 }
4426 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4427
4428 test_50() {
4429         # bug 1485
4430         test_mkdir $DIR/$tdir
4431         cd $DIR/$tdir
4432         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4433 }
4434 run_test 50 "special situations: /proc symlinks  ==============="
4435
4436 test_51a() {    # was test_51
4437         # bug 1516 - create an empty entry right after ".." then split dir
4438         test_mkdir -c1 $DIR/$tdir
4439         touch $DIR/$tdir/foo
4440         $MCREATE $DIR/$tdir/bar
4441         rm $DIR/$tdir/foo
4442         createmany -m $DIR/$tdir/longfile 201
4443         FNUM=202
4444         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4445                 $MCREATE $DIR/$tdir/longfile$FNUM
4446                 FNUM=$(($FNUM + 1))
4447                 echo -n "+"
4448         done
4449         echo
4450         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4451 }
4452 run_test 51a "special situations: split htree with empty entry =="
4453
4454 cleanup_print_lfs_df () {
4455         trap 0
4456         $LFS df
4457         $LFS df -i
4458 }
4459
4460 test_51b() {
4461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4462
4463         local dir=$DIR/$tdir
4464         local nrdirs=$((65536 + 100))
4465
4466         # cleanup the directory
4467         rm -fr $dir
4468
4469         test_mkdir -c1 $dir
4470
4471         $LFS df
4472         $LFS df -i
4473         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4474         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4475         [[ $numfree -lt $nrdirs ]] &&
4476                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4477
4478         # need to check free space for the directories as well
4479         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4480         numfree=$(( blkfree / $(fs_inode_ksize) ))
4481         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4482
4483         trap cleanup_print_lfs_df EXIT
4484
4485         # create files
4486         createmany -d $dir/d $nrdirs || {
4487                 unlinkmany $dir/d $nrdirs
4488                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4489         }
4490
4491         # really created :
4492         nrdirs=$(ls -U $dir | wc -l)
4493
4494         # unlink all but 100 subdirectories, then check it still works
4495         local left=100
4496         local delete=$((nrdirs - left))
4497
4498         $LFS df
4499         $LFS df -i
4500
4501         # for ldiskfs the nlink count should be 1, but this is OSD specific
4502         # and so this is listed for informational purposes only
4503         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4504         unlinkmany -d $dir/d $delete ||
4505                 error "unlink of first $delete subdirs failed"
4506
4507         echo "nlink between: $(stat -c %h $dir)"
4508         local found=$(ls -U $dir | wc -l)
4509         [ $found -ne $left ] &&
4510                 error "can't find subdirs: found only $found, expected $left"
4511
4512         unlinkmany -d $dir/d $delete $left ||
4513                 error "unlink of second $left subdirs failed"
4514         # regardless of whether the backing filesystem tracks nlink accurately
4515         # or not, the nlink count shouldn't be more than "." and ".." here
4516         local after=$(stat -c %h $dir)
4517         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4518                 echo "nlink after: $after"
4519
4520         cleanup_print_lfs_df
4521 }
4522 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4523
4524 test_51d() {
4525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4526         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4527
4528         test_mkdir $DIR/$tdir
4529         createmany -o $DIR/$tdir/t- 1000
4530         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4531         for N in $(seq 0 $((OSTCOUNT - 1))); do
4532                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4533                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4534                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4535                         '($1 == '$N') { objs += 1 } \
4536                         END { printf("%0.0f", objs) }')
4537                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4538         done
4539         unlinkmany $DIR/$tdir/t- 1000
4540
4541         NLAST=0
4542         for N in $(seq 1 $((OSTCOUNT - 1))); do
4543                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4544                         error "OST $N has less objects vs OST $NLAST" \
4545                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4546                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4547                         error "OST $N has less objects vs OST $NLAST" \
4548                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4549
4550                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4551                         error "OST $N has less #0 objects vs OST $NLAST" \
4552                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4553                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4554                         error "OST $N has less #0 objects vs OST $NLAST" \
4555                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4556                 NLAST=$N
4557         done
4558         rm -f $TMP/$tfile
4559 }
4560 run_test 51d "check object distribution"
4561
4562 test_51e() {
4563         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4564                 skip_env "ldiskfs only test"
4565         fi
4566
4567         test_mkdir -c1 $DIR/$tdir
4568         test_mkdir -c1 $DIR/$tdir/d0
4569
4570         touch $DIR/$tdir/d0/foo
4571         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4572                 error "file exceed 65000 nlink limit!"
4573         unlinkmany $DIR/$tdir/d0/f- 65001
4574         return 0
4575 }
4576 run_test 51e "check file nlink limit"
4577
4578 test_51f() {
4579         test_mkdir $DIR/$tdir
4580
4581         local max=100000
4582         local ulimit_old=$(ulimit -n)
4583         local spare=20 # number of spare fd's for scripts/libraries, etc.
4584         local mdt=$($LFS getstripe -m $DIR/$tdir)
4585         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4586
4587         echo "MDT$mdt numfree=$numfree, max=$max"
4588         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4589         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4590                 while ! ulimit -n $((numfree + spare)); do
4591                         numfree=$((numfree * 3 / 4))
4592                 done
4593                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4594         else
4595                 echo "left ulimit at $ulimit_old"
4596         fi
4597
4598         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4599                 unlinkmany $DIR/$tdir/f $numfree
4600                 error "create+open $numfree files in $DIR/$tdir failed"
4601         }
4602         ulimit -n $ulimit_old
4603
4604         # if createmany exits at 120s there will be fewer than $numfree files
4605         unlinkmany $DIR/$tdir/f $numfree || true
4606 }
4607 run_test 51f "check many open files limit"
4608
4609 test_52a() {
4610         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4611         test_mkdir $DIR/$tdir
4612         touch $DIR/$tdir/foo
4613         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4614         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4615         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4616         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4617         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4618                                         error "link worked"
4619         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4620         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4621         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4622                                                      error "lsattr"
4623         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4624         cp -r $DIR/$tdir $TMP/
4625         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4626 }
4627 run_test 52a "append-only flag test (should return errors)"
4628
4629 test_52b() {
4630         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4631         test_mkdir $DIR/$tdir
4632         touch $DIR/$tdir/foo
4633         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4634         cat test > $DIR/$tdir/foo && error "cat test worked"
4635         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4636         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4637         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4638                                         error "link worked"
4639         echo foo >> $DIR/$tdir/foo && error "echo worked"
4640         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4641         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4642         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4643         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4644                                                         error "lsattr"
4645         chattr -i $DIR/$tdir/foo || error "chattr failed"
4646
4647         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4648 }
4649 run_test 52b "immutable flag test (should return errors) ======="
4650
4651 test_53() {
4652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4653         remote_mds_nodsh && skip "remote MDS with nodsh"
4654         remote_ost_nodsh && skip "remote OST with nodsh"
4655
4656         local param
4657         local param_seq
4658         local ostname
4659         local mds_last
4660         local mds_last_seq
4661         local ost_last
4662         local ost_last_seq
4663         local ost_last_id
4664         local ostnum
4665         local node
4666         local found=false
4667         local support_last_seq=true
4668
4669         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4670                 support_last_seq=false
4671
4672         # only test MDT0000
4673         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4674         local value
4675         for value in $(do_facet $SINGLEMDS \
4676                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4677                 param=$(echo ${value[0]} | cut -d "=" -f1)
4678                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4679
4680                 if $support_last_seq; then
4681                         param_seq=$(echo $param |
4682                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4683                         mds_last_seq=$(do_facet $SINGLEMDS \
4684                                        $LCTL get_param -n $param_seq)
4685                 fi
4686                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4687
4688                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4689                 node=$(facet_active_host ost$((ostnum+1)))
4690                 param="obdfilter.$ostname.last_id"
4691                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4692                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4693                         ost_last_id=$ost_last
4694
4695                         if $support_last_seq; then
4696                                 ost_last_id=$(echo $ost_last |
4697                                               awk -F':' '{print $2}' |
4698                                               sed -e "s/^0x//g")
4699                                 ost_last_seq=$(echo $ost_last |
4700                                                awk -F':' '{print $1}')
4701                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4702                         fi
4703
4704                         if [[ $ost_last_id != $mds_last ]]; then
4705                                 error "$ost_last_id != $mds_last"
4706                         else
4707                                 found=true
4708                                 break
4709                         fi
4710                 done
4711         done
4712         $found || error "can not match last_seq/last_id for $mdtosc"
4713         return 0
4714 }
4715 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4716
4717 test_54a() {
4718         perl -MSocket -e ';' || skip "no Socket perl module installed"
4719
4720         $SOCKETSERVER $DIR/socket ||
4721                 error "$SOCKETSERVER $DIR/socket failed: $?"
4722         $SOCKETCLIENT $DIR/socket ||
4723                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4724         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4725 }
4726 run_test 54a "unix domain socket test =========================="
4727
4728 test_54b() {
4729         f="$DIR/f54b"
4730         mknod $f c 1 3
4731         chmod 0666 $f
4732         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4733 }
4734 run_test 54b "char device works in lustre ======================"
4735
4736 find_loop_dev() {
4737         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4738         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4739         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4740
4741         for i in $(seq 3 7); do
4742                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4743                 LOOPDEV=$LOOPBASE$i
4744                 LOOPNUM=$i
4745                 break
4746         done
4747 }
4748
4749 cleanup_54c() {
4750         local rc=0
4751         loopdev="$DIR/loop54c"
4752
4753         trap 0
4754         $UMOUNT $DIR/$tdir || rc=$?
4755         losetup -d $loopdev || true
4756         losetup -d $LOOPDEV || true
4757         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4758         return $rc
4759 }
4760
4761 test_54c() {
4762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4763
4764         loopdev="$DIR/loop54c"
4765
4766         find_loop_dev
4767         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4768         trap cleanup_54c EXIT
4769         mknod $loopdev b 7 $LOOPNUM
4770         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4771         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4772         losetup $loopdev $DIR/$tfile ||
4773                 error "can't set up $loopdev for $DIR/$tfile"
4774         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4775         test_mkdir $DIR/$tdir
4776         mount -t ext2 $loopdev $DIR/$tdir ||
4777                 error "error mounting $loopdev on $DIR/$tdir"
4778         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4779                 error "dd write"
4780         df $DIR/$tdir
4781         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4782                 error "dd read"
4783         cleanup_54c
4784 }
4785 run_test 54c "block device works in lustre ====================="
4786
4787 test_54d() {
4788         f="$DIR/f54d"
4789         string="aaaaaa"
4790         mknod $f p
4791         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4792 }
4793 run_test 54d "fifo device works in lustre ======================"
4794
4795 test_54e() {
4796         f="$DIR/f54e"
4797         string="aaaaaa"
4798         cp -aL /dev/console $f
4799         echo $string > $f || error "echo $string to $f failed"
4800 }
4801 run_test 54e "console/tty device works in lustre ======================"
4802
4803 test_56a() {
4804         local numfiles=3
4805         local dir=$DIR/$tdir
4806
4807         rm -rf $dir
4808         test_mkdir -p $dir/dir
4809         for i in $(seq $numfiles); do
4810                 touch $dir/file$i
4811                 touch $dir/dir/file$i
4812         done
4813
4814         local numcomp=$($LFS getstripe --component-count $dir)
4815
4816         [[ $numcomp == 0 ]] && numcomp=1
4817
4818         # test lfs getstripe with --recursive
4819         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4820
4821         [[ $filenum -eq $((numfiles * 2)) ]] ||
4822                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4823         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4824         [[ $filenum -eq $numfiles ]] ||
4825                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4826         echo "$LFS getstripe showed obdidx or l_ost_idx"
4827
4828         # test lfs getstripe with file instead of dir
4829         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4830         [[ $filenum -eq 1 ]] ||
4831                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4832         echo "$LFS getstripe file1 passed"
4833
4834         #test lfs getstripe with --verbose
4835         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4836         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4837                 error "$LFS getstripe --verbose $dir: "\
4838                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4839         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4840                 error "$LFS getstripe $dir: showed lmm_magic"
4841
4842         #test lfs getstripe with -v prints lmm_fid
4843         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4844         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4845                 error "$LFS getstripe -v $dir: "\
4846                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4847         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4848                 error "$LFS getstripe $dir: showed lmm_fid by default"
4849         echo "$LFS getstripe --verbose passed"
4850
4851         #check for FID information
4852         local fid1=$($LFS getstripe --fid $dir/file1)
4853         local fid2=$($LFS getstripe --verbose $dir/file1 |
4854                      awk '/lmm_fid: / { print $2; exit; }')
4855         local fid3=$($LFS path2fid $dir/file1)
4856
4857         [ "$fid1" != "$fid2" ] &&
4858                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4859         [ "$fid1" != "$fid3" ] &&
4860                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4861         echo "$LFS getstripe --fid passed"
4862
4863         #test lfs getstripe with --obd
4864         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4865                 error "$LFS getstripe --obd wrong_uuid: should return error"
4866
4867         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4868
4869         local ostidx=1
4870         local obduuid=$(ostuuid_from_index $ostidx)
4871         local found=$($LFS getstripe -r --obd $obduuid $dir |
4872                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4873
4874         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4875         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4876                 ((filenum--))
4877         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4878                 ((filenum--))
4879
4880         [[ $found -eq $filenum ]] ||
4881                 error "$LFS getstripe --obd: found $found expect $filenum"
4882         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4883                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4884                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4885                 error "$LFS getstripe --obd: should not show file on other obd"
4886         echo "$LFS getstripe --obd passed"
4887 }
4888 run_test 56a "check $LFS getstripe"
4889
4890 test_56b() {
4891         local dir=$DIR/$tdir
4892         local numdirs=3
4893
4894         test_mkdir $dir
4895         for i in $(seq $numdirs); do
4896                 test_mkdir $dir/dir$i
4897         done
4898
4899         # test lfs getdirstripe default mode is non-recursion, which is
4900         # different from lfs getstripe
4901         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4902
4903         [[ $dircnt -eq 1 ]] ||
4904                 error "$LFS getdirstripe: found $dircnt, not 1"
4905         dircnt=$($LFS getdirstripe --recursive $dir |
4906                 grep -c lmv_stripe_count)
4907         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4908                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4909 }
4910 run_test 56b "check $LFS getdirstripe"
4911
4912 test_56c() {
4913         remote_ost_nodsh && skip "remote OST with nodsh"
4914
4915         local ost_idx=0
4916         local ost_name=$(ostname_from_index $ost_idx)
4917         local old_status=$(ost_dev_status $ost_idx)
4918
4919         [[ -z "$old_status" ]] ||
4920                 skip_env "OST $ost_name is in $old_status status"
4921
4922         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4923         sleep_maxage
4924
4925         local new_status=$(ost_dev_status $ost_idx)
4926
4927         [[ "$new_status" = "D" ]] ||
4928                 error "OST $ost_name is in status of '$new_status', not 'D'"
4929
4930         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4931         sleep_maxage
4932
4933         new_status=$(ost_dev_status $ost_idx)
4934         [[ -z "$new_status" ]] ||
4935                 error "OST $ost_name is in status of '$new_status', not ''"
4936 }
4937 run_test 56c "check 'lfs df' showing device status"
4938
4939 NUMFILES=3
4940 NUMDIRS=3
4941 setup_56() {
4942         local local_tdir="$1"
4943         local local_numfiles="$2"
4944         local local_numdirs="$3"
4945         local dir_params="$4"
4946         local dir_stripe_params="$5"
4947
4948         if [ ! -d "$local_tdir" ] ; then
4949                 test_mkdir -p $dir_stripe_params $local_tdir
4950                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4951                 for i in $(seq $local_numfiles) ; do
4952                         touch $local_tdir/file$i
4953                 done
4954                 for i in $(seq $local_numdirs) ; do
4955                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4956                         for j in $(seq $local_numfiles) ; do
4957                                 touch $local_tdir/dir$i/file$j
4958                         done
4959                 done
4960         fi
4961 }
4962
4963 setup_56_special() {
4964         local local_tdir=$1
4965         local local_numfiles=$2
4966         local local_numdirs=$3
4967
4968         setup_56 $local_tdir $local_numfiles $local_numdirs
4969
4970         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4971                 for i in $(seq $local_numfiles) ; do
4972                         mknod $local_tdir/loop${i}b b 7 $i
4973                         mknod $local_tdir/null${i}c c 1 3
4974                         ln -s $local_tdir/file1 $local_tdir/link${i}
4975                 done
4976                 for i in $(seq $local_numdirs) ; do
4977                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4978                         mknod $local_tdir/dir$i/null${i}c c 1 3
4979                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4980                 done
4981         fi
4982 }
4983
4984 test_56g() {
4985         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4986         local expected=$(($NUMDIRS + 2))
4987
4988         setup_56 $dir $NUMFILES $NUMDIRS
4989
4990         # test lfs find with -name
4991         for i in $(seq $NUMFILES) ; do
4992                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4993
4994                 [ $nums -eq $expected ] ||
4995                         error "lfs find -name '*$i' $dir wrong: "\
4996                               "found $nums, expected $expected"
4997         done
4998 }
4999 run_test 56g "check lfs find -name"
5000
5001 test_56h() {
5002         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5003         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5004
5005         setup_56 $dir $NUMFILES $NUMDIRS
5006
5007         # test lfs find with ! -name
5008         for i in $(seq $NUMFILES) ; do
5009                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5010
5011                 [ $nums -eq $expected ] ||
5012                         error "lfs find ! -name '*$i' $dir wrong: "\
5013                               "found $nums, expected $expected"
5014         done
5015 }
5016 run_test 56h "check lfs find ! -name"
5017
5018 test_56i() {
5019         local dir=$DIR/$tdir
5020
5021         test_mkdir $dir
5022
5023         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5024         local out=$($cmd)
5025
5026         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5027 }
5028 run_test 56i "check 'lfs find -ost UUID' skips directories"
5029
5030 test_56j() {
5031         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5032
5033         setup_56_special $dir $NUMFILES $NUMDIRS
5034
5035         local expected=$((NUMDIRS + 1))
5036         local cmd="$LFS find -type d $dir"
5037         local nums=$($cmd | wc -l)
5038
5039         [ $nums -eq $expected ] ||
5040                 error "'$cmd' wrong: found $nums, expected $expected"
5041 }
5042 run_test 56j "check lfs find -type d"
5043
5044 test_56k() {
5045         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5046
5047         setup_56_special $dir $NUMFILES $NUMDIRS
5048
5049         local expected=$(((NUMDIRS + 1) * NUMFILES))
5050         local cmd="$LFS find -type f $dir"
5051         local nums=$($cmd | wc -l)
5052
5053         [ $nums -eq $expected ] ||
5054                 error "'$cmd' wrong: found $nums, expected $expected"
5055 }
5056 run_test 56k "check lfs find -type f"
5057
5058 test_56l() {
5059         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5060
5061         setup_56_special $dir $NUMFILES $NUMDIRS
5062
5063         local expected=$((NUMDIRS + NUMFILES))
5064         local cmd="$LFS find -type b $dir"
5065         local nums=$($cmd | wc -l)
5066
5067         [ $nums -eq $expected ] ||
5068                 error "'$cmd' wrong: found $nums, expected $expected"
5069 }
5070 run_test 56l "check lfs find -type b"
5071
5072 test_56m() {
5073         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5074
5075         setup_56_special $dir $NUMFILES $NUMDIRS
5076
5077         local expected=$((NUMDIRS + NUMFILES))
5078         local cmd="$LFS find -type c $dir"
5079         local nums=$($cmd | wc -l)
5080         [ $nums -eq $expected ] ||
5081                 error "'$cmd' wrong: found $nums, expected $expected"
5082 }
5083 run_test 56m "check lfs find -type c"
5084
5085 test_56n() {
5086         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5087         setup_56_special $dir $NUMFILES $NUMDIRS
5088
5089         local expected=$((NUMDIRS + NUMFILES))
5090         local cmd="$LFS find -type l $dir"
5091         local nums=$($cmd | wc -l)
5092
5093         [ $nums -eq $expected ] ||
5094                 error "'$cmd' wrong: found $nums, expected $expected"
5095 }
5096 run_test 56n "check lfs find -type l"
5097
5098 test_56o() {
5099         local dir=$DIR/$tdir
5100
5101         setup_56 $dir $NUMFILES $NUMDIRS
5102         utime $dir/file1 > /dev/null || error "utime (1)"
5103         utime $dir/file2 > /dev/null || error "utime (2)"
5104         utime $dir/dir1 > /dev/null || error "utime (3)"
5105         utime $dir/dir2 > /dev/null || error "utime (4)"
5106         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5107         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5108
5109         local expected=4
5110         local nums=$($LFS find -mtime +0 $dir | wc -l)
5111
5112         [ $nums -eq $expected ] ||
5113                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5114
5115         expected=12
5116         cmd="$LFS find -mtime 0 $dir"
5117         nums=$($cmd | wc -l)
5118         [ $nums -eq $expected ] ||
5119                 error "'$cmd' wrong: found $nums, expected $expected"
5120 }
5121 run_test 56o "check lfs find -mtime for old files"
5122
5123 test_56ob() {
5124         local dir=$DIR/$tdir
5125         local expected=1
5126         local count=0
5127
5128         # just to make sure there is something that won't be found
5129         test_mkdir $dir
5130         touch $dir/$tfile.now
5131
5132         for age in year week day hour min; do
5133                 count=$((count + 1))
5134
5135                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5136                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5137                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5138
5139                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5140                 local nums=$($cmd | wc -l)
5141                 [ $nums -eq $expected ] ||
5142                         error "'$cmd' wrong: found $nums, expected $expected"
5143
5144                 cmd="$LFS find $dir -atime $count${age:0:1}"
5145                 nums=$($cmd | wc -l)
5146                 [ $nums -eq $expected ] ||
5147                         error "'$cmd' wrong: found $nums, expected $expected"
5148         done
5149
5150         sleep 2
5151         cmd="$LFS find $dir -ctime +1s -type f"
5152         nums=$($cmd | wc -l)
5153         (( $nums == $count * 2 + 1)) ||
5154                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5155 }
5156 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5157
5158 test_56p() {
5159         [ $RUNAS_ID -eq $UID ] &&
5160                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5161
5162         local dir=$DIR/$tdir
5163
5164         setup_56 $dir $NUMFILES $NUMDIRS
5165         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5166
5167         local expected=$NUMFILES
5168         local cmd="$LFS find -uid $RUNAS_ID $dir"
5169         local nums=$($cmd | wc -l)
5170
5171         [ $nums -eq $expected ] ||
5172                 error "'$cmd' wrong: found $nums, expected $expected"
5173
5174         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5175         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5176         nums=$($cmd | wc -l)
5177         [ $nums -eq $expected ] ||
5178                 error "'$cmd' wrong: found $nums, expected $expected"
5179 }
5180 run_test 56p "check lfs find -uid and ! -uid"
5181
5182 test_56q() {
5183         [ $RUNAS_ID -eq $UID ] &&
5184                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5185
5186         local dir=$DIR/$tdir
5187
5188         setup_56 $dir $NUMFILES $NUMDIRS
5189         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5190
5191         local expected=$NUMFILES
5192         local cmd="$LFS find -gid $RUNAS_GID $dir"
5193         local nums=$($cmd | wc -l)
5194
5195         [ $nums -eq $expected ] ||
5196                 error "'$cmd' wrong: found $nums, expected $expected"
5197
5198         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5199         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5200         nums=$($cmd | wc -l)
5201         [ $nums -eq $expected ] ||
5202                 error "'$cmd' wrong: found $nums, expected $expected"
5203 }
5204 run_test 56q "check lfs find -gid and ! -gid"
5205
5206 test_56r() {
5207         local dir=$DIR/$tdir
5208
5209         setup_56 $dir $NUMFILES $NUMDIRS
5210
5211         local expected=12
5212         local cmd="$LFS find -size 0 -type f $dir"
5213         local nums=$($cmd | wc -l)
5214
5215         [ $nums -eq $expected ] ||
5216                 error "'$cmd' wrong: found $nums, expected $expected"
5217         expected=0
5218         cmd="$LFS find ! -size 0 -type f $dir"
5219         nums=$($cmd | wc -l)
5220         [ $nums -eq $expected ] ||
5221                 error "'$cmd' wrong: found $nums, expected $expected"
5222         echo "test" > $dir/$tfile
5223         echo "test2" > $dir/$tfile.2 && sync
5224         expected=1
5225         cmd="$LFS find -size 5 -type f $dir"
5226         nums=$($cmd | wc -l)
5227         [ $nums -eq $expected ] ||
5228                 error "'$cmd' wrong: found $nums, expected $expected"
5229         expected=1
5230         cmd="$LFS find -size +5 -type f $dir"
5231         nums=$($cmd | wc -l)
5232         [ $nums -eq $expected ] ||
5233                 error "'$cmd' wrong: found $nums, expected $expected"
5234         expected=2
5235         cmd="$LFS find -size +0 -type f $dir"
5236         nums=$($cmd | wc -l)
5237         [ $nums -eq $expected ] ||
5238                 error "'$cmd' wrong: found $nums, expected $expected"
5239         expected=2
5240         cmd="$LFS find ! -size -5 -type f $dir"
5241         nums=$($cmd | wc -l)
5242         [ $nums -eq $expected ] ||
5243                 error "'$cmd' wrong: found $nums, expected $expected"
5244         expected=12
5245         cmd="$LFS find -size -5 -type f $dir"
5246         nums=$($cmd | wc -l)
5247         [ $nums -eq $expected ] ||
5248                 error "'$cmd' wrong: found $nums, expected $expected"
5249 }
5250 run_test 56r "check lfs find -size works"
5251
5252 test_56s() { # LU-611 #LU-9369
5253         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5254
5255         local dir=$DIR/$tdir
5256         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5257
5258         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5259         for i in $(seq $NUMDIRS); do
5260                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5261         done
5262
5263         local expected=$NUMDIRS
5264         local cmd="$LFS find -c $OSTCOUNT $dir"
5265         local nums=$($cmd | wc -l)
5266
5267         [ $nums -eq $expected ] || {
5268                 $LFS getstripe -R $dir
5269                 error "'$cmd' wrong: found $nums, expected $expected"
5270         }
5271
5272         expected=$((NUMDIRS + onestripe))
5273         cmd="$LFS find -stripe-count +0 -type f $dir"
5274         nums=$($cmd | wc -l)
5275         [ $nums -eq $expected ] || {
5276                 $LFS getstripe -R $dir
5277                 error "'$cmd' wrong: found $nums, expected $expected"
5278         }
5279
5280         expected=$onestripe
5281         cmd="$LFS find -stripe-count 1 -type f $dir"
5282         nums=$($cmd | wc -l)
5283         [ $nums -eq $expected ] || {
5284                 $LFS getstripe -R $dir
5285                 error "'$cmd' wrong: found $nums, expected $expected"
5286         }
5287
5288         cmd="$LFS find -stripe-count -2 -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         expected=0
5296         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5297         nums=$($cmd | wc -l)
5298         [ $nums -eq $expected ] || {
5299                 $LFS getstripe -R $dir
5300                 error "'$cmd' wrong: found $nums, expected $expected"
5301         }
5302 }
5303 run_test 56s "check lfs find -stripe-count works"
5304
5305 test_56t() { # LU-611 #LU-9369
5306         local dir=$DIR/$tdir
5307
5308         setup_56 $dir 0 $NUMDIRS
5309         for i in $(seq $NUMDIRS); do
5310                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5311         done
5312
5313         local expected=$NUMDIRS
5314         local cmd="$LFS find -S 8M $dir"
5315         local nums=$($cmd | wc -l)
5316
5317         [ $nums -eq $expected ] || {
5318                 $LFS getstripe -R $dir
5319                 error "'$cmd' wrong: found $nums, expected $expected"
5320         }
5321         rm -rf $dir
5322
5323         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5324
5325         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5326
5327         expected=$(((NUMDIRS + 1) * NUMFILES))
5328         cmd="$LFS find -stripe-size 512k -type f $dir"
5329         nums=$($cmd | wc -l)
5330         [ $nums -eq $expected ] ||
5331                 error "'$cmd' wrong: found $nums, expected $expected"
5332
5333         cmd="$LFS find -stripe-size +320k -type f $dir"
5334         nums=$($cmd | wc -l)
5335         [ $nums -eq $expected ] ||
5336                 error "'$cmd' wrong: found $nums, expected $expected"
5337
5338         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5339         cmd="$LFS find -stripe-size +200k -type f $dir"
5340         nums=$($cmd | wc -l)
5341         [ $nums -eq $expected ] ||
5342                 error "'$cmd' wrong: found $nums, expected $expected"
5343
5344         cmd="$LFS find -stripe-size -640k -type f $dir"
5345         nums=$($cmd | wc -l)
5346         [ $nums -eq $expected ] ||
5347                 error "'$cmd' wrong: found $nums, expected $expected"
5348
5349         expected=4
5350         cmd="$LFS find -stripe-size 256k -type f $dir"
5351         nums=$($cmd | wc -l)
5352         [ $nums -eq $expected ] ||
5353                 error "'$cmd' wrong: found $nums, expected $expected"
5354
5355         cmd="$LFS find -stripe-size -320k -type f $dir"
5356         nums=$($cmd | wc -l)
5357         [ $nums -eq $expected ] ||
5358                 error "'$cmd' wrong: found $nums, expected $expected"
5359
5360         expected=0
5361         cmd="$LFS find -stripe-size 1024k -type f $dir"
5362         nums=$($cmd | wc -l)
5363         [ $nums -eq $expected ] ||
5364                 error "'$cmd' wrong: found $nums, expected $expected"
5365 }
5366 run_test 56t "check lfs find -stripe-size works"
5367
5368 test_56u() { # LU-611
5369         local dir=$DIR/$tdir
5370
5371         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5372
5373         if [[ $OSTCOUNT -gt 1 ]]; then
5374                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5375                 onestripe=4
5376         else
5377                 onestripe=0
5378         fi
5379
5380         local expected=$(((NUMDIRS + 1) * NUMFILES))
5381         local cmd="$LFS find -stripe-index 0 -type f $dir"
5382         local nums=$($cmd | wc -l)
5383
5384         [ $nums -eq $expected ] ||
5385                 error "'$cmd' wrong: found $nums, expected $expected"
5386
5387         expected=$onestripe
5388         cmd="$LFS find -stripe-index 1 -type f $dir"
5389         nums=$($cmd | wc -l)
5390         [ $nums -eq $expected ] ||
5391                 error "'$cmd' wrong: found $nums, expected $expected"
5392
5393         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5394         nums=$($cmd | wc -l)
5395         [ $nums -eq $expected ] ||
5396                 error "'$cmd' wrong: found $nums, expected $expected"
5397
5398         expected=0
5399         # This should produce an error and not return any files
5400         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5401         nums=$($cmd 2>/dev/null | wc -l)
5402         [ $nums -eq $expected ] ||
5403                 error "'$cmd' wrong: found $nums, expected $expected"
5404
5405         if [[ $OSTCOUNT -gt 1 ]]; then
5406                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5407                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5408                 nums=$($cmd | wc -l)
5409                 [ $nums -eq $expected ] ||
5410                         error "'$cmd' wrong: found $nums, expected $expected"
5411         fi
5412 }
5413 run_test 56u "check lfs find -stripe-index works"
5414
5415 test_56v() {
5416         local mdt_idx=0
5417         local dir=$DIR/$tdir
5418
5419         setup_56 $dir $NUMFILES $NUMDIRS
5420
5421         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5422         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5423
5424         for file in $($LFS find -m $UUID $dir); do
5425                 file_midx=$($LFS getstripe -m $file)
5426                 [ $file_midx -eq $mdt_idx ] ||
5427                         error "lfs find -m $UUID != getstripe -m $file_midx"
5428         done
5429 }
5430 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5431
5432 test_56w() {
5433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5435
5436         local dir=$DIR/$tdir
5437
5438         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5439
5440         local stripe_size=$($LFS getstripe -S -d $dir) ||
5441                 error "$LFS getstripe -S -d $dir failed"
5442         stripe_size=${stripe_size%% *}
5443
5444         local file_size=$((stripe_size * OSTCOUNT))
5445         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5446         local required_space=$((file_num * file_size))
5447         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5448                            head -n1)
5449         [[ $free_space -le $((required_space / 1024)) ]] &&
5450                 skip_env "need $required_space, have $free_space kbytes"
5451
5452         local dd_bs=65536
5453         local dd_count=$((file_size / dd_bs))
5454
5455         # write data into the files
5456         local i
5457         local j
5458         local file
5459
5460         for i in $(seq $NUMFILES); do
5461                 file=$dir/file$i
5462                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5463                         error "write data into $file failed"
5464         done
5465         for i in $(seq $NUMDIRS); do
5466                 for j in $(seq $NUMFILES); do
5467                         file=$dir/dir$i/file$j
5468                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5469                                 error "write data into $file failed"
5470                 done
5471         done
5472
5473         # $LFS_MIGRATE will fail if hard link migration is unsupported
5474         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5475                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5476                         error "creating links to $dir/dir1/file1 failed"
5477         fi
5478
5479         local expected=-1
5480
5481         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5482
5483         # lfs_migrate file
5484         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5485
5486         echo "$cmd"
5487         eval $cmd || error "$cmd failed"
5488
5489         check_stripe_count $dir/file1 $expected
5490
5491         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5492         then
5493                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5494                 # OST 1 if it is on OST 0. This file is small enough to
5495                 # be on only one stripe.
5496                 file=$dir/migr_1_ost
5497                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5498                         error "write data into $file failed"
5499                 local obdidx=$($LFS getstripe -i $file)
5500                 local oldmd5=$(md5sum $file)
5501                 local newobdidx=0
5502
5503                 [[ $obdidx -eq 0 ]] && newobdidx=1
5504                 cmd="$LFS migrate -i $newobdidx $file"
5505                 echo $cmd
5506                 eval $cmd || error "$cmd failed"
5507
5508                 local realobdix=$($LFS getstripe -i $file)
5509                 local newmd5=$(md5sum $file)
5510
5511                 [[ $newobdidx -ne $realobdix ]] &&
5512                         error "new OST is different (was=$obdidx, "\
5513                               "wanted=$newobdidx, got=$realobdix)"
5514                 [[ "$oldmd5" != "$newmd5" ]] &&
5515                         error "md5sum differ: $oldmd5, $newmd5"
5516         fi
5517
5518         # lfs_migrate dir
5519         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5520         echo "$cmd"
5521         eval $cmd || error "$cmd failed"
5522
5523         for j in $(seq $NUMFILES); do
5524                 check_stripe_count $dir/dir1/file$j $expected
5525         done
5526
5527         # lfs_migrate works with lfs find
5528         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5529              $LFS_MIGRATE -y -c $expected"
5530         echo "$cmd"
5531         eval $cmd || error "$cmd failed"
5532
5533         for i in $(seq 2 $NUMFILES); do
5534                 check_stripe_count $dir/file$i $expected
5535         done
5536         for i in $(seq 2 $NUMDIRS); do
5537                 for j in $(seq $NUMFILES); do
5538                 check_stripe_count $dir/dir$i/file$j $expected
5539                 done
5540         done
5541 }
5542 run_test 56w "check lfs_migrate -c stripe_count works"
5543
5544 test_56wb() {
5545         local file1=$DIR/$tdir/file1
5546         local create_pool=false
5547         local initial_pool=$($LFS getstripe -p $DIR)
5548         local pool_list=()
5549         local pool=""
5550
5551         echo -n "Creating test dir..."
5552         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5553         echo "done."
5554
5555         echo -n "Creating test file..."
5556         touch $file1 || error "cannot create file"
5557         echo "done."
5558
5559         echo -n "Detecting existing pools..."
5560         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5561
5562         if [ ${#pool_list[@]} -gt 0 ]; then
5563                 echo "${pool_list[@]}"
5564                 for thispool in "${pool_list[@]}"; do
5565                         if [[ -z "$initial_pool" ||
5566                               "$initial_pool" != "$thispool" ]]; then
5567                                 pool="$thispool"
5568                                 echo "Using existing pool '$pool'"
5569                                 break
5570                         fi
5571                 done
5572         else
5573                 echo "none detected."
5574         fi
5575         if [ -z "$pool" ]; then
5576                 pool=${POOL:-testpool}
5577                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5578                 echo -n "Creating pool '$pool'..."
5579                 create_pool=true
5580                 pool_add $pool &> /dev/null ||
5581                         error "pool_add failed"
5582                 echo "done."
5583
5584                 echo -n "Adding target to pool..."
5585                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5586                         error "pool_add_targets failed"
5587                 echo "done."
5588         fi
5589
5590         echo -n "Setting pool using -p option..."
5591         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5592                 error "migrate failed rc = $?"
5593         echo "done."
5594
5595         echo -n "Verifying test file is in pool after migrating..."
5596         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5597                 error "file was not migrated to pool $pool"
5598         echo "done."
5599
5600         echo -n "Removing test file from pool '$pool'..."
5601         $LFS migrate $file1 &> /dev/null ||
5602                 error "cannot remove from pool"
5603         [ "$($LFS getstripe -p $file1)" ] &&
5604                 error "pool still set"
5605         echo "done."
5606
5607         echo -n "Setting pool using --pool option..."
5608         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5609                 error "migrate failed rc = $?"
5610         echo "done."
5611
5612         # Clean up
5613         rm -f $file1
5614         if $create_pool; then
5615                 destroy_test_pools 2> /dev/null ||
5616                         error "destroy test pools failed"
5617         fi
5618 }
5619 run_test 56wb "check lfs_migrate pool support"
5620
5621 test_56wc() {
5622         local file1="$DIR/$tdir/file1"
5623
5624         echo -n "Creating test dir..."
5625         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5626         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5627         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5628                 error "cannot set stripe"
5629         echo "done"
5630
5631         echo -n "Setting initial stripe for test file..."
5632         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5633                 error "cannot set stripe"
5634         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5635                 error "stripe size not set"
5636         echo "done."
5637
5638         # File currently set to -S 512K -c 1
5639
5640         # Ensure -c and -S options are rejected when -R is set
5641         echo -n "Verifying incompatible options are detected..."
5642         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5643                 error "incompatible -c and -R options not detected"
5644         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5645                 error "incompatible -S and -R options not detected"
5646         echo "done."
5647
5648         # Ensure unrecognized options are passed through to 'lfs migrate'
5649         echo -n "Verifying -S option is passed through to lfs migrate..."
5650         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5651                 error "migration failed"
5652         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5653                 error "file was not restriped"
5654         echo "done."
5655
5656         # File currently set to -S 1M -c 1
5657
5658         # Ensure long options are supported
5659         echo -n "Verifying long options supported..."
5660         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5661                 error "long option without argument not supported"
5662         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5663                 error "long option with argument not supported"
5664         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5665                 error "file not restriped with --stripe-size option"
5666         echo "done."
5667
5668         # File currently set to -S 512K -c 1
5669
5670         if [ "$OSTCOUNT" -gt 1 ]; then
5671                 echo -n "Verifying explicit stripe count can be set..."
5672                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5673                         error "migrate failed"
5674                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5675                         error "file not restriped to explicit count"
5676                 echo "done."
5677         fi
5678
5679         # File currently set to -S 512K -c 1 or -S 512K -c 2
5680
5681         # Ensure parent striping is used if -R is set, and no stripe
5682         # count or size is specified
5683         echo -n "Setting stripe for parent directory..."
5684         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5685                 error "cannot set stripe"
5686         echo "done."
5687
5688         echo -n "Verifying restripe option uses parent stripe settings..."
5689         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5690                 error "migrate failed"
5691         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5692                 error "file not restriped to parent settings"
5693         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5694                 error "file not restriped to parent settings"
5695         echo "done."
5696
5697         # File currently set to -S 1M -c 1
5698
5699         # Ensure striping is preserved if -R is not set, and no stripe
5700         # count or size is specified
5701         echo -n "Verifying striping size preserved when not specified..."
5702         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5703         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5704                 error "cannot set stripe on parent directory"
5705         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5706                 error "migrate failed"
5707         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5708                 error "file was restriped"
5709         echo "done."
5710
5711         # Ensure file name properly detected when final option has no argument
5712         echo -n "Verifying file name properly detected..."
5713         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5714                 error "file name interpreted as option argument"
5715         echo "done."
5716
5717         # Clean up
5718         rm -f "$file1"
5719 }
5720 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5721
5722 test_56wd() {
5723         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5724
5725         local file1=$DIR/$tdir/file1
5726
5727         echo -n "Creating test dir..."
5728         test_mkdir $DIR/$tdir || error "cannot create dir"
5729         echo "done."
5730
5731         echo -n "Creating test file..."
5732         touch $file1
5733         echo "done."
5734
5735         # Ensure 'lfs migrate' will fail by using a non-existent option,
5736         # and make sure rsync is not called to recover
5737         echo -n "Make sure --no-rsync option works..."
5738         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5739                 grep -q 'refusing to fall back to rsync' ||
5740                 error "rsync was called with --no-rsync set"
5741         echo "done."
5742
5743         # Ensure rsync is called without trying 'lfs migrate' first
5744         echo -n "Make sure --rsync option works..."
5745         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5746                 grep -q 'falling back to rsync' &&
5747                 error "lfs migrate was called with --rsync set"
5748         echo "done."
5749
5750         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5751         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5752                 grep -q 'at the same time' ||
5753                 error "--rsync and --no-rsync accepted concurrently"
5754         echo "done."
5755
5756         # Clean up
5757         rm -f $file1
5758 }
5759 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5760
5761 test_56x() {
5762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5763         check_swap_layouts_support
5764
5765         local dir=$DIR/$tdir
5766         local ref1=/etc/passwd
5767         local file1=$dir/file1
5768
5769         test_mkdir $dir || error "creating dir $dir"
5770         $LFS setstripe -c 2 $file1
5771         cp $ref1 $file1
5772         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5773         stripe=$($LFS getstripe -c $file1)
5774         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5775         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5776
5777         # clean up
5778         rm -f $file1
5779 }
5780 run_test 56x "lfs migration support"
5781
5782 test_56xa() {
5783         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5784         check_swap_layouts_support
5785
5786         local dir=$DIR/$tdir/$testnum
5787
5788         test_mkdir -p $dir
5789
5790         local ref1=/etc/passwd
5791         local file1=$dir/file1
5792
5793         $LFS setstripe -c 2 $file1
5794         cp $ref1 $file1
5795         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5796
5797         local stripe=$($LFS getstripe -c $file1)
5798
5799         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5800         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5801
5802         # clean up
5803         rm -f $file1
5804 }
5805 run_test 56xa "lfs migration --block support"
5806
5807 check_migrate_links() {
5808         local dir="$1"
5809         local file1="$dir/file1"
5810         local begin="$2"
5811         local count="$3"
5812         local total_count=$(($begin + $count - 1))
5813         local symlink_count=10
5814         local uniq_count=10
5815
5816         if [ ! -f "$file1" ]; then
5817                 echo -n "creating initial file..."
5818                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5819                         error "cannot setstripe initial file"
5820                 echo "done"
5821
5822                 echo -n "creating symlinks..."
5823                 for s in $(seq 1 $symlink_count); do
5824                         ln -s "$file1" "$dir/slink$s" ||
5825                                 error "cannot create symlinks"
5826                 done
5827                 echo "done"
5828
5829                 echo -n "creating nonlinked files..."
5830                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5831                         error "cannot create nonlinked files"
5832                 echo "done"
5833         fi
5834
5835         # create hard links
5836         if [ ! -f "$dir/file$total_count" ]; then
5837                 echo -n "creating hard links $begin:$total_count..."
5838                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5839                         /dev/null || error "cannot create hard links"
5840                 echo "done"
5841         fi
5842
5843         echo -n "checking number of hard links listed in xattrs..."
5844         local fid=$($LFS getstripe -F "$file1")
5845         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5846
5847         echo "${#paths[*]}"
5848         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5849                         skip "hard link list has unexpected size, skipping test"
5850         fi
5851         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5852                         error "link names should exceed xattrs size"
5853         fi
5854
5855         echo -n "migrating files..."
5856         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5857         local rc=$?
5858         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5859         echo "done"
5860
5861         # make sure all links have been properly migrated
5862         echo -n "verifying files..."
5863         fid=$($LFS getstripe -F "$file1") ||
5864                 error "cannot get fid for file $file1"
5865         for i in $(seq 2 $total_count); do
5866                 local fid2=$($LFS getstripe -F $dir/file$i)
5867
5868                 [ "$fid2" == "$fid" ] ||
5869                         error "migrated hard link has mismatched FID"
5870         done
5871
5872         # make sure hard links were properly detected, and migration was
5873         # performed only once for the entire link set; nonlinked files should
5874         # also be migrated
5875         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5876         local expected=$(($uniq_count + 1))
5877
5878         [ "$actual" -eq  "$expected" ] ||
5879                 error "hard links individually migrated ($actual != $expected)"
5880
5881         # make sure the correct number of hard links are present
5882         local hardlinks=$(stat -c '%h' "$file1")
5883
5884         [ $hardlinks -eq $total_count ] ||
5885                 error "num hard links $hardlinks != $total_count"
5886         echo "done"
5887
5888         return 0
5889 }
5890
5891 test_56xb() {
5892         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5893                 skip "Need MDS version at least 2.10.55"
5894
5895         local dir="$DIR/$tdir"
5896
5897         test_mkdir "$dir" || error "cannot create dir $dir"
5898
5899         echo "testing lfs migrate mode when all links fit within xattrs"
5900         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5901
5902         echo "testing rsync mode when all links fit within xattrs"
5903         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5904
5905         echo "testing lfs migrate mode when all links do not fit within xattrs"
5906         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5907
5908         echo "testing rsync mode when all links do not fit within xattrs"
5909         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5910
5911
5912         # clean up
5913         rm -rf $dir
5914 }
5915 run_test 56xb "lfs migration hard link support"
5916
5917 test_56xc() {
5918         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5919
5920         local dir="$DIR/$tdir"
5921
5922         test_mkdir "$dir" || error "cannot create dir $dir"
5923
5924         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5925         echo -n "Setting initial stripe for 20MB test file..."
5926         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5927         echo "done"
5928         echo -n "Sizing 20MB test file..."
5929         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5930         echo "done"
5931         echo -n "Verifying small file autostripe count is 1..."
5932         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5933                 error "cannot migrate 20MB file"
5934         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5935                 error "cannot get stripe for $dir/20mb"
5936         [ $stripe_count -eq 1 ] ||
5937                 error "unexpected stripe count $stripe_count for 20MB file"
5938         rm -f "$dir/20mb"
5939         echo "done"
5940
5941         # Test 2: File is small enough to fit within the available space on
5942         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5943         # have at least an additional 1KB for each desired stripe for test 3
5944         echo -n "Setting stripe for 1GB test file..."
5945         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5946         echo "done"
5947         echo -n "Sizing 1GB test file..."
5948         # File size is 1GB + 3KB
5949         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5950                 error "cannot create 1GB test file"
5951         echo "done"
5952         echo -n "Migrating 1GB file..."
5953         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5954                 error "cannot migrate file"
5955         echo "done"
5956         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5957         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5958                 error "cannot get stripe for $dir/1gb"
5959         [ $stripe_count -eq 2 ] ||
5960                 error "unexpected stripe count $stripe_count (expected 2)"
5961         echo "done"
5962
5963         # Test 3: File is too large to fit within the available space on
5964         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5965         if [ $OSTCOUNT -ge 3 ]; then
5966                 # The required available space is calculated as
5967                 # file size (1GB + 3KB) / OST count (3).
5968                 local kb_per_ost=349526
5969
5970                 echo -n "Migrating 1GB file..."
5971                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5972                         /dev/null || error "cannot migrate file"
5973                 echo "done"
5974
5975                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5976                 echo -n "Verifying autostripe count with limited space..."
5977                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5978                         error "unexpected stripe count $stripe_count (wanted 3)"
5979                 echo "done"
5980         fi
5981
5982         # clean up
5983         rm -rf $dir
5984 }
5985 run_test 56xc "lfs migration autostripe"
5986
5987 test_56y() {
5988         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5989                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5990
5991         local res=""
5992         local dir=$DIR/$tdir
5993         local f1=$dir/file1
5994         local f2=$dir/file2
5995
5996         test_mkdir -p $dir || error "creating dir $dir"
5997         touch $f1 || error "creating std file $f1"
5998         $MULTIOP $f2 H2c || error "creating released file $f2"
5999
6000         # a directory can be raid0, so ask only for files
6001         res=$($LFS find $dir -L raid0 -type f | wc -l)
6002         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6003
6004         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6005         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6006
6007         # only files can be released, so no need to force file search
6008         res=$($LFS find $dir -L released)
6009         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6010
6011         res=$($LFS find $dir -type f \! -L released)
6012         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6013 }
6014 run_test 56y "lfs find -L raid0|released"
6015
6016 test_56z() { # LU-4824
6017         # This checks to make sure 'lfs find' continues after errors
6018         # There are two classes of errors that should be caught:
6019         # - If multiple paths are provided, all should be searched even if one
6020         #   errors out
6021         # - If errors are encountered during the search, it should not terminate
6022         #   early
6023         local dir=$DIR/$tdir
6024         local i
6025
6026         test_mkdir $dir
6027         for i in d{0..9}; do
6028                 test_mkdir $dir/$i
6029         done
6030         touch $dir/d{0..9}/$tfile
6031         $LFS find $DIR/non_existent_dir $dir &&
6032                 error "$LFS find did not return an error"
6033         # Make a directory unsearchable. This should NOT be the last entry in
6034         # directory order.  Arbitrarily pick the 6th entry
6035         chmod 700 $($LFS find $dir -type d | sed '6!d')
6036
6037         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6038
6039         # The user should be able to see 10 directories and 9 files
6040         [ $count == 19 ] || error "$LFS find did not continue after error"
6041 }
6042 run_test 56z "lfs find should continue after an error"
6043
6044 test_56aa() { # LU-5937
6045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6046
6047         local dir=$DIR/$tdir
6048
6049         mkdir $dir
6050         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6051
6052         createmany -o $dir/striped_dir/${tfile}- 1024
6053         local dirs=$($LFS find --size +8k $dir/)
6054
6055         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6056 }
6057 run_test 56aa "lfs find --size under striped dir"
6058
6059 test_56ab() { # LU-10705
6060         test_mkdir $DIR/$tdir
6061         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6062         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6063         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6064         # Flush writes to ensure valid blocks.  Need to be more thorough for
6065         # ZFS, since blocks are not allocated/returned to client immediately.
6066         sync_all_data
6067         wait_zfs_commit ost1 2
6068         cancel_lru_locks osc
6069         ls -ls $DIR/$tdir
6070
6071         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6072
6073         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6074
6075         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6076         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6077
6078         rm -f $DIR/$tdir/$tfile.[123]
6079 }
6080 run_test 56ab "lfs find --blocks"
6081
6082 test_56ba() {
6083         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6084                 skip "Need MDS version at least 2.10.50"
6085
6086         # Create composite files with one component
6087         local dir=$DIR/$tdir
6088
6089         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6090         # Create composite files with three components
6091         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6092         # Create non-composite files
6093         createmany -o $dir/${tfile}- 10
6094
6095         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6096
6097         [[ $nfiles == 10 ]] ||
6098                 error "lfs find -E 1M found $nfiles != 10 files"
6099
6100         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6101         [[ $nfiles == 25 ]] ||
6102                 error "lfs find ! -E 1M found $nfiles != 25 files"
6103
6104         # All files have a component that starts at 0
6105         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6106         [[ $nfiles == 35 ]] ||
6107                 error "lfs find --component-start 0 - $nfiles != 35 files"
6108
6109         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6110         [[ $nfiles == 15 ]] ||
6111                 error "lfs find --component-start 2M - $nfiles != 15 files"
6112
6113         # All files created here have a componenet that does not starts at 2M
6114         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6115         [[ $nfiles == 35 ]] ||
6116                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6117
6118         # Find files with a specified number of components
6119         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6120         [[ $nfiles == 15 ]] ||
6121                 error "lfs find --component-count 3 - $nfiles != 15 files"
6122
6123         # Remember non-composite files have a component count of zero
6124         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6125         [[ $nfiles == 10 ]] ||
6126                 error "lfs find --component-count 0 - $nfiles != 10 files"
6127
6128         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6129         [[ $nfiles == 20 ]] ||
6130                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6131
6132         # All files have a flag called "init"
6133         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6134         [[ $nfiles == 35 ]] ||
6135                 error "lfs find --component-flags init - $nfiles != 35 files"
6136
6137         # Multi-component files will have a component not initialized
6138         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6139         [[ $nfiles == 15 ]] ||
6140                 error "lfs find !--component-flags init - $nfiles != 15 files"
6141
6142         rm -rf $dir
6143
6144 }
6145 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6146
6147 test_56ca() {
6148         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6149                 skip "Need MDS version at least 2.10.57"
6150
6151         local td=$DIR/$tdir
6152         local tf=$td/$tfile
6153         local dir
6154         local nfiles
6155         local cmd
6156         local i
6157         local j
6158
6159         # create mirrored directories and mirrored files
6160         mkdir $td || error "mkdir $td failed"
6161         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6162         createmany -o $tf- 10 || error "create $tf- failed"
6163
6164         for i in $(seq 2); do
6165                 dir=$td/dir$i
6166                 mkdir $dir || error "mkdir $dir failed"
6167                 $LFS mirror create -N$((3 + i)) $dir ||
6168                         error "create mirrored dir $dir failed"
6169                 createmany -o $dir/$tfile- 10 ||
6170                         error "create $dir/$tfile- failed"
6171         done
6172
6173         # change the states of some mirrored files
6174         echo foo > $tf-6
6175         for i in $(seq 2); do
6176                 dir=$td/dir$i
6177                 for j in $(seq 4 9); do
6178                         echo foo > $dir/$tfile-$j
6179                 done
6180         done
6181
6182         # find mirrored files with specific mirror count
6183         cmd="$LFS find --mirror-count 3 --type f $td"
6184         nfiles=$($cmd | wc -l)
6185         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6186
6187         cmd="$LFS find ! --mirror-count 3 --type f $td"
6188         nfiles=$($cmd | wc -l)
6189         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6190
6191         cmd="$LFS find --mirror-count +2 --type f $td"
6192         nfiles=$($cmd | wc -l)
6193         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6194
6195         cmd="$LFS find --mirror-count -6 --type f $td"
6196         nfiles=$($cmd | wc -l)
6197         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6198
6199         # find mirrored files with specific file state
6200         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6201         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6202
6203         cmd="$LFS find --mirror-state=ro --type f $td"
6204         nfiles=$($cmd | wc -l)
6205         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6206
6207         cmd="$LFS find ! --mirror-state=ro --type f $td"
6208         nfiles=$($cmd | wc -l)
6209         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6210
6211         cmd="$LFS find --mirror-state=wp --type f $td"
6212         nfiles=$($cmd | wc -l)
6213         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6214
6215         cmd="$LFS find ! --mirror-state=sp --type f $td"
6216         nfiles=$($cmd | wc -l)
6217         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6218 }
6219 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6220
6221 test_57a() {
6222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6223         # note test will not do anything if MDS is not local
6224         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6225                 skip_env "ldiskfs only test"
6226         fi
6227         remote_mds_nodsh && skip "remote MDS with nodsh"
6228
6229         local MNTDEV="osd*.*MDT*.mntdev"
6230         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6231         [ -z "$DEV" ] && error "can't access $MNTDEV"
6232         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6233                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6234                         error "can't access $DEV"
6235                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6236                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6237                 rm $TMP/t57a.dump
6238         done
6239 }
6240 run_test 57a "verify MDS filesystem created with large inodes =="
6241
6242 test_57b() {
6243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6244         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6245                 skip_env "ldiskfs only test"
6246         fi
6247         remote_mds_nodsh && skip "remote MDS with nodsh"
6248
6249         local dir=$DIR/$tdir
6250         local filecount=100
6251         local file1=$dir/f1
6252         local fileN=$dir/f$filecount
6253
6254         rm -rf $dir || error "removing $dir"
6255         test_mkdir -c1 $dir
6256         local mdtidx=$($LFS getstripe -m $dir)
6257         local mdtname=MDT$(printf %04x $mdtidx)
6258         local facet=mds$((mdtidx + 1))
6259
6260         echo "mcreating $filecount files"
6261         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6262
6263         # verify that files do not have EAs yet
6264         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6265                 error "$file1 has an EA"
6266         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6267                 error "$fileN has an EA"
6268
6269         sync
6270         sleep 1
6271         df $dir  #make sure we get new statfs data
6272         local mdsfree=$(do_facet $facet \
6273                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6274         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6275         local file
6276
6277         echo "opening files to create objects/EAs"
6278         for file in $(seq -f $dir/f%g 1 $filecount); do
6279                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6280                         error "opening $file"
6281         done
6282
6283         # verify that files have EAs now
6284         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6285         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6286
6287         sleep 1  #make sure we get new statfs data
6288         df $dir
6289         local mdsfree2=$(do_facet $facet \
6290                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6291         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6292
6293         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6294                 if [ "$mdsfree" != "$mdsfree2" ]; then
6295                         error "MDC before $mdcfree != after $mdcfree2"
6296                 else
6297                         echo "MDC before $mdcfree != after $mdcfree2"
6298                         echo "unable to confirm if MDS has large inodes"
6299                 fi
6300         fi
6301         rm -rf $dir
6302 }
6303 run_test 57b "default LOV EAs are stored inside large inodes ==="
6304
6305 test_58() {
6306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6307         [ -z "$(which wiretest 2>/dev/null)" ] &&
6308                         skip_env "could not find wiretest"
6309
6310         wiretest
6311 }
6312 run_test 58 "verify cross-platform wire constants =============="
6313
6314 test_59() {
6315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6316
6317         echo "touch 130 files"
6318         createmany -o $DIR/f59- 130
6319         echo "rm 130 files"
6320         unlinkmany $DIR/f59- 130
6321         sync
6322         # wait for commitment of removal
6323         wait_delete_completed
6324 }
6325 run_test 59 "verify cancellation of llog records async ========="
6326
6327 TEST60_HEAD="test_60 run $RANDOM"
6328 test_60a() {
6329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6330         remote_mgs_nodsh && skip "remote MGS with nodsh"
6331         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6332                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6333                         skip_env "missing subtest run-llog.sh"
6334
6335         log "$TEST60_HEAD - from kernel mode"
6336         do_facet mgs "$LCTL dk > /dev/null"
6337         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6338         do_facet mgs $LCTL dk > $TMP/$tfile
6339
6340         # LU-6388: test llog_reader
6341         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6342         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6343         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6344                         skip_env "missing llog_reader"
6345         local fstype=$(facet_fstype mgs)
6346         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6347                 skip_env "Only for ldiskfs or zfs type mgs"
6348
6349         local mntpt=$(facet_mntpt mgs)
6350         local mgsdev=$(mgsdevname 1)
6351         local fid_list
6352         local fid
6353         local rec_list
6354         local rec
6355         local rec_type
6356         local obj_file
6357         local path
6358         local seq
6359         local oid
6360         local pass=true
6361
6362         #get fid and record list
6363         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6364                 tail -n 4))
6365         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6366                 tail -n 4))
6367         #remount mgs as ldiskfs or zfs type
6368         stop mgs || error "stop mgs failed"
6369         mount_fstype mgs || error "remount mgs failed"
6370         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6371                 fid=${fid_list[i]}
6372                 rec=${rec_list[i]}
6373                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6374                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6375                 oid=$((16#$oid))
6376
6377                 case $fstype in
6378                         ldiskfs )
6379                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6380                         zfs )
6381                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6382                 esac
6383                 echo "obj_file is $obj_file"
6384                 do_facet mgs $llog_reader $obj_file
6385
6386                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6387                         awk '{ print $3 }' | sed -e "s/^type=//g")
6388                 if [ $rec_type != $rec ]; then
6389                         echo "FAILED test_60a wrong record type $rec_type," \
6390                               "should be $rec"
6391                         pass=false
6392                         break
6393                 fi
6394
6395                 #check obj path if record type is LLOG_LOGID_MAGIC
6396                 if [ "$rec" == "1064553b" ]; then
6397                         path=$(do_facet mgs $llog_reader $obj_file |
6398                                 grep "path=" | awk '{ print $NF }' |
6399                                 sed -e "s/^path=//g")
6400                         if [ $obj_file != $mntpt/$path ]; then
6401                                 echo "FAILED test_60a wrong obj path" \
6402                                       "$montpt/$path, should be $obj_file"
6403                                 pass=false
6404                                 break
6405                         fi
6406                 fi
6407         done
6408         rm -f $TMP/$tfile
6409         #restart mgs before "error", otherwise it will block the next test
6410         stop mgs || error "stop mgs failed"
6411         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6412         $pass || error "test failed, see FAILED test_60a messages for specifics"
6413 }
6414 run_test 60a "llog_test run from kernel module and test llog_reader"
6415
6416 test_60b() { # bug 6411
6417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6418
6419         dmesg > $DIR/$tfile
6420         LLOG_COUNT=$(do_facet mgs dmesg |
6421                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6422                           /llog_[a-z]*.c:[0-9]/ {
6423                                 if (marker)
6424                                         from_marker++
6425                                 from_begin++
6426                           }
6427                           END {
6428                                 if (marker)
6429                                         print from_marker
6430                                 else
6431                                         print from_begin
6432                           }")
6433
6434         [[ $LLOG_COUNT -gt 120 ]] &&
6435                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6436 }
6437 run_test 60b "limit repeated messages from CERROR/CWARN"
6438
6439 test_60c() {
6440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6441
6442         echo "create 5000 files"
6443         createmany -o $DIR/f60c- 5000
6444 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6445         lctl set_param fail_loc=0x80000137
6446         unlinkmany $DIR/f60c- 5000
6447         lctl set_param fail_loc=0
6448 }
6449 run_test 60c "unlink file when mds full"
6450
6451 test_60d() {
6452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6453
6454         SAVEPRINTK=$(lctl get_param -n printk)
6455         # verify "lctl mark" is even working"
6456         MESSAGE="test message ID $RANDOM $$"
6457         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6458         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6459
6460         lctl set_param printk=0 || error "set lnet.printk failed"
6461         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6462         MESSAGE="new test message ID $RANDOM $$"
6463         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6464         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6465         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6466
6467         lctl set_param -n printk="$SAVEPRINTK"
6468 }
6469 run_test 60d "test printk console message masking"
6470
6471 test_60e() {
6472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6473         remote_mds_nodsh && skip "remote MDS with nodsh"
6474
6475         touch $DIR/$tfile
6476 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6477         do_facet mds1 lctl set_param fail_loc=0x15b
6478         rm $DIR/$tfile
6479 }
6480 run_test 60e "no space while new llog is being created"
6481
6482 test_60g() {
6483         local pid
6484
6485         test_mkdir -c $MDSCOUNT $DIR/$tdir
6486         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6487
6488         (
6489                 local index=0
6490                 while true; do
6491                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6492                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6493                         index=$((index + 1))
6494                 done
6495         ) &
6496
6497         pid=$!
6498
6499         for i in $(seq 100); do 
6500                 # define OBD_FAIL_OSD_TXN_START    0x19a
6501                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6502                 usleep 100
6503         done
6504
6505         kill -9 $pid
6506
6507         mkdir $DIR/$tdir/new || error "mkdir failed"
6508         rmdir $DIR/$tdir/new || error "rmdir failed"
6509 }
6510 run_test 60g "transaction abort won't cause MDT hung"
6511
6512 test_61a() {
6513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6514
6515         f="$DIR/f61"
6516         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6517         cancel_lru_locks osc
6518         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6519         sync
6520 }
6521 run_test 61a "mmap() writes don't make sync hang ================"
6522
6523 test_61b() {
6524         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6525 }
6526 run_test 61b "mmap() of unstriped file is successful"
6527
6528 # bug 2330 - insufficient obd_match error checking causes LBUG
6529 test_62() {
6530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6531
6532         f="$DIR/f62"
6533         echo foo > $f
6534         cancel_lru_locks osc
6535         lctl set_param fail_loc=0x405
6536         cat $f && error "cat succeeded, expect -EIO"
6537         lctl set_param fail_loc=0
6538 }
6539 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6540 # match every page all of the time.
6541 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6542
6543 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6544 # Though this test is irrelevant anymore, it helped to reveal some
6545 # other grant bugs (LU-4482), let's keep it.
6546 test_63a() {   # was test_63
6547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6548
6549         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6550
6551         for i in `seq 10` ; do
6552                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6553                 sleep 5
6554                 kill $!
6555                 sleep 1
6556         done
6557
6558         rm -f $DIR/f63 || true
6559 }
6560 run_test 63a "Verify oig_wait interruption does not crash ======="
6561
6562 # bug 2248 - async write errors didn't return to application on sync
6563 # bug 3677 - async write errors left page locked
6564 test_63b() {
6565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6566
6567         debugsave
6568         lctl set_param debug=-1
6569
6570         # ensure we have a grant to do async writes
6571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6572         rm $DIR/$tfile
6573
6574         sync    # sync lest earlier test intercept the fail_loc
6575
6576         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6577         lctl set_param fail_loc=0x80000406
6578         $MULTIOP $DIR/$tfile Owy && \
6579                 error "sync didn't return ENOMEM"
6580         sync; sleep 2; sync     # do a real sync this time to flush page
6581         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6582                 error "locked page left in cache after async error" || true
6583         debugrestore
6584 }
6585 run_test 63b "async write errors should be returned to fsync ==="
6586
6587 test_64a () {
6588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6589
6590         df $DIR
6591         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6592 }
6593 run_test 64a "verify filter grant calculations (in kernel) ====="
6594
6595 test_64b () {
6596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6597
6598         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6599 }
6600 run_test 64b "check out-of-space detection on client"
6601
6602 test_64c() {
6603         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6604 }
6605 run_test 64c "verify grant shrink"
6606
6607 # this does exactly what osc_request.c:osc_announce_cached() does in
6608 # order to calculate max amount of grants to ask from server
6609 want_grant() {
6610         local tgt=$1
6611
6612         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6613         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6614
6615         ((rpc_in_flight ++));
6616         nrpages=$((nrpages * rpc_in_flight))
6617
6618         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6619
6620         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6621
6622         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6623         local undirty=$((nrpages * PAGE_SIZE))
6624
6625         local max_extent_pages
6626         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6627             grep grant_max_extent_size | awk '{print $2}')
6628         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6629         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6630         local grant_extent_tax
6631         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6632             grep grant_extent_tax | awk '{print $2}')
6633
6634         undirty=$((undirty + nrextents * grant_extent_tax))
6635
6636         echo $undirty
6637 }
6638
6639 # this is size of unit for grant allocation. It should be equal to
6640 # what tgt_grant.c:tgt_grant_chunk() calculates
6641 grant_chunk() {
6642         local tgt=$1
6643         local max_brw_size
6644         local grant_extent_tax
6645
6646         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6647             grep max_brw_size | awk '{print $2}')
6648
6649         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6650             grep grant_extent_tax | awk '{print $2}')
6651
6652         echo $(((max_brw_size + grant_extent_tax) * 2))
6653 }
6654
6655 test_64d() {
6656         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6657                 skip "OST < 2.10.55 doesn't limit grants enough"
6658
6659         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6660         local file=$DIR/$tfile
6661
6662         [[ $($LCTL get_param osc.${tgt}.import |
6663              grep "connect_flags:.*grant_param") ]] ||
6664                 skip "no grant_param connect flag"
6665
6666         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6667
6668         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6669
6670         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6671         stack_trap "rm -f $file" EXIT
6672
6673         $LFS setstripe $file -i 0 -c 1
6674         dd if=/dev/zero of=$file bs=1M count=1000 &
6675         ddpid=$!
6676
6677         while true
6678         do
6679                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6680                 if [[ $cur_grant -gt $max_cur_granted ]]
6681                 then
6682                         kill $ddpid
6683                         error "cur_grant $cur_grant > $max_cur_granted"
6684                 fi
6685                 kill -0 $ddpid
6686                 [[ $? -ne 0 ]] && break;
6687                 sleep 2
6688         done
6689
6690         rm -f $DIR/$tfile
6691         wait_delete_completed
6692         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6693 }
6694 run_test 64d "check grant limit exceed"
6695
6696 # bug 1414 - set/get directories' stripe info
6697 test_65a() {
6698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6699
6700         test_mkdir $DIR/$tdir
6701         touch $DIR/$tdir/f1
6702         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6703 }
6704 run_test 65a "directory with no stripe info"
6705
6706 test_65b() {
6707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6708
6709         test_mkdir $DIR/$tdir
6710         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6711
6712         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6713                                                 error "setstripe"
6714         touch $DIR/$tdir/f2
6715         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6716 }
6717 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6718
6719 test_65c() {
6720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6721         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6722
6723         test_mkdir $DIR/$tdir
6724         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6725
6726         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6727                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6728         touch $DIR/$tdir/f3
6729         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6730 }
6731 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6732
6733 test_65d() {
6734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6735
6736         test_mkdir $DIR/$tdir
6737         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6738         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6739
6740         if [[ $STRIPECOUNT -le 0 ]]; then
6741                 sc=1
6742         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6743 #LOV_MAX_STRIPE_COUNT is 2000
6744                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6745         else
6746                 sc=$(($STRIPECOUNT - 1))
6747         fi
6748         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6749         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6750         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6751                 error "lverify failed"
6752 }
6753 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6754
6755 test_65e() {
6756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6757
6758         test_mkdir $DIR/$tdir
6759
6760         $LFS setstripe $DIR/$tdir || error "setstripe"
6761         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6762                                         error "no stripe info failed"
6763         touch $DIR/$tdir/f6
6764         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6765 }
6766 run_test 65e "directory setstripe defaults"
6767
6768 test_65f() {
6769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6770
6771         test_mkdir $DIR/${tdir}f
6772         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6773                 error "setstripe succeeded" || true
6774 }
6775 run_test 65f "dir setstripe permission (should return error) ==="
6776
6777 test_65g() {
6778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6779
6780         test_mkdir $DIR/$tdir
6781         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6782
6783         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6784                 error "setstripe -S failed"
6785         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6786         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6787                 error "delete default stripe failed"
6788 }
6789 run_test 65g "directory setstripe -d"
6790
6791 test_65h() {
6792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6793
6794         test_mkdir $DIR/$tdir
6795         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6796
6797         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6798                 error "setstripe -S failed"
6799         test_mkdir $DIR/$tdir/dd1
6800         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6801                 error "stripe info inherit failed"
6802 }
6803 run_test 65h "directory stripe info inherit ===================="
6804
6805 test_65i() {
6806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6807
6808         save_layout_restore_at_exit $MOUNT
6809
6810         # bug6367: set non-default striping on root directory
6811         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6812
6813         # bug12836: getstripe on -1 default directory striping
6814         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6815
6816         # bug12836: getstripe -v on -1 default directory striping
6817         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6818
6819         # bug12836: new find on -1 default directory striping
6820         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6821 }
6822 run_test 65i "various tests to set root directory striping"
6823
6824 test_65j() { # bug6367
6825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6826
6827         sync; sleep 1
6828
6829         # if we aren't already remounting for each test, do so for this test
6830         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6831                 cleanup || error "failed to unmount"
6832                 setup
6833         fi
6834
6835         save_layout_restore_at_exit $MOUNT
6836
6837         $LFS setstripe -d $MOUNT || error "setstripe failed"
6838 }
6839 run_test 65j "set default striping on root directory (bug 6367)="
6840
6841 cleanup_65k() {
6842         rm -rf $DIR/$tdir
6843         wait_delete_completed
6844         do_facet $SINGLEMDS "lctl set_param -n \
6845                 osp.$ost*MDT0000.max_create_count=$max_count"
6846         do_facet $SINGLEMDS "lctl set_param -n \
6847                 osp.$ost*MDT0000.create_count=$count"
6848         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6849         echo $INACTIVE_OSC "is Activate"
6850
6851         wait_osc_import_state mds ost$ostnum FULL
6852 }
6853
6854 test_65k() { # bug11679
6855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6857         remote_mds_nodsh && skip "remote MDS with nodsh"
6858
6859         local disable_precreate=true
6860         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6861                 disable_precreate=false
6862
6863         echo "Check OST status: "
6864         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6865                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6866
6867         for OSC in $MDS_OSCS; do
6868                 echo $OSC "is active"
6869                 do_facet $SINGLEMDS lctl --device %$OSC activate
6870         done
6871
6872         for INACTIVE_OSC in $MDS_OSCS; do
6873                 local ost=$(osc_to_ost $INACTIVE_OSC)
6874                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6875                                lov.*md*.target_obd |
6876                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6877
6878                 mkdir -p $DIR/$tdir
6879                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6880                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6881
6882                 echo "Deactivate: " $INACTIVE_OSC
6883                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6884
6885                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6886                               osp.$ost*MDT0000.create_count")
6887                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6888                                   osp.$ost*MDT0000.max_create_count")
6889                 $disable_precreate &&
6890                         do_facet $SINGLEMDS "lctl set_param -n \
6891                                 osp.$ost*MDT0000.max_create_count=0"
6892
6893                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6894                         [ -f $DIR/$tdir/$idx ] && continue
6895                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6896                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6897                                 { cleanup_65k;
6898                                   error "setstripe $idx should succeed"; }
6899                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6900                 done
6901                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6902                 rmdir $DIR/$tdir
6903
6904                 do_facet $SINGLEMDS "lctl set_param -n \
6905                         osp.$ost*MDT0000.max_create_count=$max_count"
6906                 do_facet $SINGLEMDS "lctl set_param -n \
6907                         osp.$ost*MDT0000.create_count=$count"
6908                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6909                 echo $INACTIVE_OSC "is Activate"
6910
6911                 wait_osc_import_state mds ost$ostnum FULL
6912         done
6913 }
6914 run_test 65k "validate manual striping works properly with deactivated OSCs"
6915
6916 test_65l() { # bug 12836
6917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6918
6919         test_mkdir -p $DIR/$tdir/test_dir
6920         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6921         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6922 }
6923 run_test 65l "lfs find on -1 stripe dir ========================"
6924
6925 test_65m() {
6926         local layout=$(save_layout $MOUNT)
6927         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6928                 restore_layout $MOUNT $layout
6929                 error "setstripe should fail by non-root users"
6930         }
6931         true
6932 }
6933 run_test 65m "normal user can't set filesystem default stripe"
6934
6935 test_65n() {
6936         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6937         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6938                 skip "Need MDS version at least 2.12.50"
6939         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6940
6941         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6942         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6943         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6944
6945         local root_layout=$(save_layout $MOUNT)
6946         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6947
6948         # new subdirectory under root directory should not inherit
6949         # the default layout from root
6950         local dir1=$MOUNT/$tdir-1
6951         mkdir $dir1 || error "mkdir $dir1 failed"
6952         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6953                 error "$dir1 shouldn't have LOV EA"
6954
6955         # delete the default layout on root directory
6956         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6957
6958         local dir2=$MOUNT/$tdir-2
6959         mkdir $dir2 || error "mkdir $dir2 failed"
6960         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6961                 error "$dir2 shouldn't have LOV EA"
6962
6963         # set a new striping pattern on root directory
6964         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6965         local new_def_stripe_size=$((def_stripe_size * 2))
6966         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6967                 error "set stripe size on $MOUNT failed"
6968
6969         # new file created in $dir2 should inherit the new stripe size from
6970         # the filesystem default
6971         local file2=$dir2/$tfile-2
6972         touch $file2 || error "touch $file2 failed"
6973
6974         local file2_stripe_size=$($LFS getstripe -S $file2)
6975         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6976                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6977
6978         local dir3=$MOUNT/$tdir-3
6979         mkdir $dir3 || error "mkdir $dir3 failed"
6980         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6981                 error "$dir3 shouldn't have LOV EA"
6982
6983         # set OST pool on root directory
6984         local pool=$TESTNAME
6985         pool_add $pool || error "add $pool failed"
6986         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6987                 error "add targets to $pool failed"
6988
6989         $LFS setstripe -p $pool $MOUNT ||
6990                 error "set OST pool on $MOUNT failed"
6991
6992         # new file created in $dir3 should inherit the pool from
6993         # the filesystem default
6994         local file3=$dir3/$tfile-3
6995         touch $file3 || error "touch $file3 failed"
6996
6997         local file3_pool=$($LFS getstripe -p $file3)
6998         [[ "$file3_pool" = "$pool" ]] ||
6999                 error "$file3 didn't inherit OST pool $pool"
7000
7001         local dir4=$MOUNT/$tdir-4
7002         mkdir $dir4 || error "mkdir $dir4 failed"
7003         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7004                 error "$dir4 shouldn't have LOV EA"
7005
7006         # new file created in $dir4 should inherit the pool from
7007         # the filesystem default
7008         local file4=$dir4/$tfile-4
7009         touch $file4 || error "touch $file4 failed"
7010
7011         local file4_pool=$($LFS getstripe -p $file4)
7012         [[ "$file4_pool" = "$pool" ]] ||
7013                 error "$file4 didn't inherit OST pool $pool"
7014
7015         # new subdirectory under non-root directory should inherit
7016         # the default layout from its parent directory
7017         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7018                 error "set directory layout on $dir4 failed"
7019
7020         local dir5=$dir4/$tdir-5
7021         mkdir $dir5 || error "mkdir $dir5 failed"
7022
7023         local dir4_layout=$(get_layout_param $dir4)
7024         local dir5_layout=$(get_layout_param $dir5)
7025         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7026                 error "$dir5 should inherit the default layout from $dir4"
7027 }
7028 run_test 65n "don't inherit default layout from root for new subdirectories"
7029
7030 # bug 2543 - update blocks count on client
7031 test_66() {
7032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7033
7034         COUNT=${COUNT:-8}
7035         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7036         sync; sync_all_data; sync; sync_all_data
7037         cancel_lru_locks osc
7038         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7039         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7040 }
7041 run_test 66 "update inode blocks count on client ==============="
7042
7043 meminfo() {
7044         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7045 }
7046
7047 swap_used() {
7048         swapon -s | awk '($1 == "'$1'") { print $4 }'
7049 }
7050
7051 # bug5265, obdfilter oa2dentry return -ENOENT
7052 # #define OBD_FAIL_SRV_ENOENT 0x217
7053 test_69() {
7054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7055         remote_ost_nodsh && skip "remote OST with nodsh"
7056
7057         f="$DIR/$tfile"
7058         $LFS setstripe -c 1 -i 0 $f
7059
7060         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7061
7062         do_facet ost1 lctl set_param fail_loc=0x217
7063         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7064         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7065
7066         do_facet ost1 lctl set_param fail_loc=0
7067         $DIRECTIO write $f 0 2 || error "write error"
7068
7069         cancel_lru_locks osc
7070         $DIRECTIO read $f 0 1 || error "read error"
7071
7072         do_facet ost1 lctl set_param fail_loc=0x217
7073         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7074
7075         do_facet ost1 lctl set_param fail_loc=0
7076         rm -f $f
7077 }
7078 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7079
7080 test_71() {
7081         test_mkdir $DIR/$tdir
7082         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7083         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7084 }
7085 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7086
7087 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7089         [ "$RUNAS_ID" = "$UID" ] &&
7090                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7091         # Check that testing environment is properly set up. Skip if not
7092         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7093                 skip_env "User $RUNAS_ID does not exist - skipping"
7094
7095         touch $DIR/$tfile
7096         chmod 777 $DIR/$tfile
7097         chmod ug+s $DIR/$tfile
7098         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7099                 error "$RUNAS dd $DIR/$tfile failed"
7100         # See if we are still setuid/sgid
7101         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7102                 error "S/gid is not dropped on write"
7103         # Now test that MDS is updated too
7104         cancel_lru_locks mdc
7105         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7106                 error "S/gid is not dropped on MDS"
7107         rm -f $DIR/$tfile
7108 }
7109 run_test 72a "Test that remove suid works properly (bug5695) ===="
7110
7111 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7112         local perm
7113
7114         [ "$RUNAS_ID" = "$UID" ] &&
7115                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7116         [ "$RUNAS_ID" -eq 0 ] &&
7117                 skip_env "RUNAS_ID = 0 -- skipping"
7118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7119         # Check that testing environment is properly set up. Skip if not
7120         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7121                 skip_env "User $RUNAS_ID does not exist - skipping"
7122
7123         touch $DIR/${tfile}-f{g,u}
7124         test_mkdir $DIR/${tfile}-dg
7125         test_mkdir $DIR/${tfile}-du
7126         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7127         chmod g+s $DIR/${tfile}-{f,d}g
7128         chmod u+s $DIR/${tfile}-{f,d}u
7129         for perm in 777 2777 4777; do
7130                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7131                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7132                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7133                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7134         done
7135         true
7136 }
7137 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7138
7139 # bug 3462 - multiple simultaneous MDC requests
7140 test_73() {
7141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7142
7143         test_mkdir $DIR/d73-1
7144         test_mkdir $DIR/d73-2
7145         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7146         pid1=$!
7147
7148         lctl set_param fail_loc=0x80000129
7149         $MULTIOP $DIR/d73-1/f73-2 Oc &
7150         sleep 1
7151         lctl set_param fail_loc=0
7152
7153         $MULTIOP $DIR/d73-2/f73-3 Oc &
7154         pid3=$!
7155
7156         kill -USR1 $pid1
7157         wait $pid1 || return 1
7158
7159         sleep 25
7160
7161         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7162         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7163         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7164
7165         rm -rf $DIR/d73-*
7166 }
7167 run_test 73 "multiple MDC requests (should not deadlock)"
7168
7169 test_74a() { # bug 6149, 6184
7170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7171
7172         touch $DIR/f74a
7173         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7174         #
7175         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7176         # will spin in a tight reconnection loop
7177         $LCTL set_param fail_loc=0x8000030e
7178         # get any lock that won't be difficult - lookup works.
7179         ls $DIR/f74a
7180         $LCTL set_param fail_loc=0
7181         rm -f $DIR/f74a
7182         true
7183 }
7184 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7185
7186 test_74b() { # bug 13310
7187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7188
7189         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7190         #
7191         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7192         # will spin in a tight reconnection loop
7193         $LCTL set_param fail_loc=0x8000030e
7194         # get a "difficult" lock
7195         touch $DIR/f74b
7196         $LCTL set_param fail_loc=0
7197         rm -f $DIR/f74b
7198         true
7199 }
7200 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7201
7202 test_74c() {
7203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7204
7205         #define OBD_FAIL_LDLM_NEW_LOCK
7206         $LCTL set_param fail_loc=0x319
7207         touch $DIR/$tfile && error "touch successful"
7208         $LCTL set_param fail_loc=0
7209         true
7210 }
7211 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7212
7213 num_inodes() {
7214         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7215 }
7216
7217 test_76() { # Now for bug 20433, added originally in bug 1443
7218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7219
7220         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7221
7222         cancel_lru_locks osc
7223         BEFORE_INODES=$(num_inodes)
7224         echo "before inodes: $BEFORE_INODES"
7225         local COUNT=1000
7226         [ "$SLOW" = "no" ] && COUNT=100
7227         for i in $(seq $COUNT); do
7228                 touch $DIR/$tfile
7229                 rm -f $DIR/$tfile
7230         done
7231         cancel_lru_locks osc
7232         AFTER_INODES=$(num_inodes)
7233         echo "after inodes: $AFTER_INODES"
7234         local wait=0
7235         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7236                 sleep 2
7237                 AFTER_INODES=$(num_inodes)
7238                 wait=$((wait+2))
7239                 echo "wait $wait seconds inodes: $AFTER_INODES"
7240                 if [ $wait -gt 30 ]; then
7241                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7242                 fi
7243         done
7244 }
7245 run_test 76 "confirm clients recycle inodes properly ===="
7246
7247
7248 export ORIG_CSUM=""
7249 set_checksums()
7250 {
7251         # Note: in sptlrpc modes which enable its own bulk checksum, the
7252         # original crc32_le bulk checksum will be automatically disabled,
7253         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7254         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7255         # In this case set_checksums() will not be no-op, because sptlrpc
7256         # bulk checksum will be enabled all through the test.
7257
7258         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7259         lctl set_param -n osc.*.checksums $1
7260         return 0
7261 }
7262
7263 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7264                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7265 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7266                              tr -d [] | head -n1)}
7267 set_checksum_type()
7268 {
7269         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7270         log "set checksum type to $1"
7271         return 0
7272 }
7273 F77_TMP=$TMP/f77-temp
7274 F77SZ=8
7275 setup_f77() {
7276         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7277                 error "error writing to $F77_TMP"
7278 }
7279
7280 test_77a() { # bug 10889
7281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7282         $GSS && skip_env "could not run with gss"
7283
7284         [ ! -f $F77_TMP ] && setup_f77
7285         set_checksums 1
7286         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7287         set_checksums 0
7288         rm -f $DIR/$tfile
7289 }
7290 run_test 77a "normal checksum read/write operation"
7291
7292 test_77b() { # bug 10889
7293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7294         $GSS && skip_env "could not run with gss"
7295
7296         [ ! -f $F77_TMP ] && setup_f77
7297         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7298         $LCTL set_param fail_loc=0x80000409
7299         set_checksums 1
7300
7301         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7302                 error "dd error: $?"
7303         $LCTL set_param fail_loc=0
7304
7305         for algo in $CKSUM_TYPES; do
7306                 cancel_lru_locks osc
7307                 set_checksum_type $algo
7308                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7309                 $LCTL set_param fail_loc=0x80000408
7310                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7311                 $LCTL set_param fail_loc=0
7312         done
7313         set_checksums 0
7314         set_checksum_type $ORIG_CSUM_TYPE
7315         rm -f $DIR/$tfile
7316 }
7317 run_test 77b "checksum error on client write, read"
7318
7319 cleanup_77c() {
7320         trap 0
7321         set_checksums 0
7322         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7323         $check_ost &&
7324                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7325         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7326         $check_ost && [ -n "$ost_file_prefix" ] &&
7327                 do_facet ost1 rm -f ${ost_file_prefix}\*
7328 }
7329
7330 test_77c() {
7331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7332         $GSS && skip_env "could not run with gss"
7333         remote_ost_nodsh && skip "remote OST with nodsh"
7334
7335         local bad1
7336         local osc_file_prefix
7337         local osc_file
7338         local check_ost=false
7339         local ost_file_prefix
7340         local ost_file
7341         local orig_cksum
7342         local dump_cksum
7343         local fid
7344
7345         # ensure corruption will occur on first OSS/OST
7346         $LFS setstripe -i 0 $DIR/$tfile
7347
7348         [ ! -f $F77_TMP ] && setup_f77
7349         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7350                 error "dd write error: $?"
7351         fid=$($LFS path2fid $DIR/$tfile)
7352
7353         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7354         then
7355                 check_ost=true
7356                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7357                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7358         else
7359                 echo "OSS do not support bulk pages dump upon error"
7360         fi
7361
7362         osc_file_prefix=$($LCTL get_param -n debug_path)
7363         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7364
7365         trap cleanup_77c EXIT
7366
7367         set_checksums 1
7368         # enable bulk pages dump upon error on Client
7369         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7370         # enable bulk pages dump upon error on OSS
7371         $check_ost &&
7372                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7373
7374         # flush Client cache to allow next read to reach OSS
7375         cancel_lru_locks osc
7376
7377         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7378         $LCTL set_param fail_loc=0x80000408
7379         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7380         $LCTL set_param fail_loc=0
7381
7382         rm -f $DIR/$tfile
7383
7384         # check cksum dump on Client
7385         osc_file=$(ls ${osc_file_prefix}*)
7386         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7387         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7388         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7389         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7390         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7391                      cksum)
7392         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7393         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7394                 error "dump content does not match on Client"
7395
7396         $check_ost || skip "No need to check cksum dump on OSS"
7397
7398         # check cksum dump on OSS
7399         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7400         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7401         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7402         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7403         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7404                 error "dump content does not match on OSS"
7405
7406         cleanup_77c
7407 }
7408 run_test 77c "checksum error on client read with debug"
7409
7410 test_77d() { # bug 10889
7411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7412         $GSS && skip_env "could not run with gss"
7413
7414         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7415         $LCTL set_param fail_loc=0x80000409
7416         set_checksums 1
7417         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7418                 error "direct write: rc=$?"
7419         $LCTL set_param fail_loc=0
7420         set_checksums 0
7421
7422         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7423         $LCTL set_param fail_loc=0x80000408
7424         set_checksums 1
7425         cancel_lru_locks osc
7426         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7427                 error "direct read: rc=$?"
7428         $LCTL set_param fail_loc=0
7429         set_checksums 0
7430 }
7431 run_test 77d "checksum error on OST direct write, read"
7432
7433 test_77f() { # bug 10889
7434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7435         $GSS && skip_env "could not run with gss"
7436
7437         set_checksums 1
7438         for algo in $CKSUM_TYPES; do
7439                 cancel_lru_locks osc
7440                 set_checksum_type $algo
7441                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7442                 $LCTL set_param fail_loc=0x409
7443                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7444                         error "direct write succeeded"
7445                 $LCTL set_param fail_loc=0
7446         done
7447         set_checksum_type $ORIG_CSUM_TYPE
7448         set_checksums 0
7449 }
7450 run_test 77f "repeat checksum error on write (expect error)"
7451
7452 test_77g() { # bug 10889
7453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7454         $GSS && skip_env "could not run with gss"
7455         remote_ost_nodsh && skip "remote OST with nodsh"
7456
7457         [ ! -f $F77_TMP ] && setup_f77
7458
7459         local file=$DIR/$tfile
7460         stack_trap "rm -f $file" EXIT
7461
7462         $LFS setstripe -c 1 -i 0 $file
7463         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7464         do_facet ost1 lctl set_param fail_loc=0x8000021a
7465         set_checksums 1
7466         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7467                 error "write error: rc=$?"
7468         do_facet ost1 lctl set_param fail_loc=0
7469         set_checksums 0
7470
7471         cancel_lru_locks osc
7472         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7473         do_facet ost1 lctl set_param fail_loc=0x8000021b
7474         set_checksums 1
7475         cmp $F77_TMP $file || error "file compare failed"
7476         do_facet ost1 lctl set_param fail_loc=0
7477         set_checksums 0
7478 }
7479 run_test 77g "checksum error on OST write, read"
7480
7481 test_77k() { # LU-10906
7482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7483         $GSS && skip_env "could not run with gss"
7484
7485         local cksum_param="osc.$FSNAME*.checksums"
7486         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7487         local checksum
7488         local i
7489
7490         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7491         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7492         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7493                 EXIT
7494
7495         for i in 0 1; do
7496                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7497                         error "failed to set checksum=$i on MGS"
7498                 wait_update $HOSTNAME "$get_checksum" $i
7499                 #remount
7500                 echo "remount client, checksum should be $i"
7501                 remount_client $MOUNT || "failed to remount client"
7502                 checksum=$(eval $get_checksum)
7503                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7504         done
7505         # remove persistent param to avoid races with checksum mountopt below
7506         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7507                 error "failed to delete checksum on MGS"
7508
7509         for opt in "checksum" "nochecksum"; do
7510                 #remount with mount option
7511                 echo "remount client with option $opt, checksum should be $i"
7512                 umount_client $MOUNT || "failed to umount client"
7513                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7514                         "failed to mount client with option '$opt'"
7515                 checksum=$(eval $get_checksum)
7516                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7517                 i=$((i - 1))
7518         done
7519
7520         remount_client $MOUNT || "failed to remount client"
7521 }
7522 run_test 77k "enable/disable checksum correctly"
7523
7524 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7525 rm -f $F77_TMP
7526 unset F77_TMP
7527
7528 cleanup_test_78() {
7529         trap 0
7530         rm -f $DIR/$tfile
7531 }
7532
7533 test_78() { # bug 10901
7534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7535         remote_ost || skip_env "local OST"
7536
7537         NSEQ=5
7538         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7539         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7540         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7541         echo "MemTotal: $MEMTOTAL"
7542
7543         # reserve 256MB of memory for the kernel and other running processes,
7544         # and then take 1/2 of the remaining memory for the read/write buffers.
7545         if [ $MEMTOTAL -gt 512 ] ;then
7546                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7547         else
7548                 # for those poor memory-starved high-end clusters...
7549                 MEMTOTAL=$((MEMTOTAL / 2))
7550         fi
7551         echo "Mem to use for directio: $MEMTOTAL"
7552
7553         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7554         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7555         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7556         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7557                 head -n1)
7558         echo "Smallest OST: $SMALLESTOST"
7559         [[ $SMALLESTOST -lt 10240 ]] &&
7560                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7561
7562         trap cleanup_test_78 EXIT
7563
7564         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7565                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7566
7567         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7568         echo "File size: $F78SIZE"
7569         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7570         for i in $(seq 1 $NSEQ); do
7571                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7572                 echo directIO rdwr round $i of $NSEQ
7573                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7574         done
7575
7576         cleanup_test_78
7577 }
7578 run_test 78 "handle large O_DIRECT writes correctly ============"
7579
7580 test_79() { # bug 12743
7581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7582
7583         wait_delete_completed
7584
7585         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7586         BKFREE=$(calc_osc_kbytes kbytesfree)
7587         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7588
7589         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7590         DFTOTAL=`echo $STRING | cut -d, -f1`
7591         DFUSED=`echo $STRING  | cut -d, -f2`
7592         DFAVAIL=`echo $STRING | cut -d, -f3`
7593         DFFREE=$(($DFTOTAL - $DFUSED))
7594
7595         ALLOWANCE=$((64 * $OSTCOUNT))
7596
7597         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7598            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7599                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7600         fi
7601         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7602            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7603                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7604         fi
7605         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7606            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7607                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7608         fi
7609 }
7610 run_test 79 "df report consistency check ======================="
7611
7612 test_80() { # bug 10718
7613         remote_ost_nodsh && skip "remote OST with nodsh"
7614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7615
7616         # relax strong synchronous semantics for slow backends like ZFS
7617         local soc="obdfilter.*.sync_on_lock_cancel"
7618         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7619         local hosts=
7620         if [ "$soc_old" != "never" ] &&
7621                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7622                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7623                                 facet_active_host $host; done | sort -u)
7624                         do_nodes $hosts lctl set_param $soc=never
7625         fi
7626
7627         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7628         sync; sleep 1; sync
7629         local BEFORE=`date +%s`
7630         cancel_lru_locks osc
7631         local AFTER=`date +%s`
7632         local DIFF=$((AFTER-BEFORE))
7633         if [ $DIFF -gt 1 ] ; then
7634                 error "elapsed for 1M@1T = $DIFF"
7635         fi
7636
7637         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7638
7639         rm -f $DIR/$tfile
7640 }
7641 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7642
7643 test_81a() { # LU-456
7644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7645         remote_ost_nodsh && skip "remote OST with nodsh"
7646
7647         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7648         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7649         do_facet ost1 lctl set_param fail_loc=0x80000228
7650
7651         # write should trigger a retry and success
7652         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7653         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7654         RC=$?
7655         if [ $RC -ne 0 ] ; then
7656                 error "write should success, but failed for $RC"
7657         fi
7658 }
7659 run_test 81a "OST should retry write when get -ENOSPC ==============="
7660
7661 test_81b() { # LU-456
7662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7663         remote_ost_nodsh && skip "remote OST with nodsh"
7664
7665         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7666         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7667         do_facet ost1 lctl set_param fail_loc=0x228
7668
7669         # write should retry several times and return -ENOSPC finally
7670         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7671         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7672         RC=$?
7673         ENOSPC=28
7674         if [ $RC -ne $ENOSPC ] ; then
7675                 error "dd should fail for -ENOSPC, but succeed."
7676         fi
7677 }
7678 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7679
7680 test_82() { # LU-1031
7681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7682         local gid1=14091995
7683         local gid2=16022000
7684
7685         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7686         local MULTIPID1=$!
7687         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7688         local MULTIPID2=$!
7689         kill -USR1 $MULTIPID2
7690         sleep 2
7691         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7692                 error "First grouplock does not block second one"
7693         else
7694                 echo "Second grouplock blocks first one"
7695         fi
7696         kill -USR1 $MULTIPID1
7697         wait $MULTIPID1
7698         wait $MULTIPID2
7699 }
7700 run_test 82 "Basic grouplock test"
7701
7702 test_99() {
7703         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7704
7705         test_mkdir $DIR/$tdir.cvsroot
7706         chown $RUNAS_ID $DIR/$tdir.cvsroot
7707
7708         cd $TMP
7709         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7710
7711         cd /etc/init.d
7712         # some versions of cvs import exit(1) when asked to import links or
7713         # files they can't read.  ignore those files.
7714         local toignore=$(find . -type l -printf '-I %f\n' -o \
7715                          ! -perm /4 -printf '-I %f\n')
7716         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7717                 $tdir.reposname vtag rtag
7718
7719         cd $DIR
7720         test_mkdir $DIR/$tdir.reposname
7721         chown $RUNAS_ID $DIR/$tdir.reposname
7722         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7723
7724         cd $DIR/$tdir.reposname
7725         $RUNAS touch foo99
7726         $RUNAS cvs add -m 'addmsg' foo99
7727         $RUNAS cvs update
7728         $RUNAS cvs commit -m 'nomsg' foo99
7729         rm -fr $DIR/$tdir.cvsroot
7730 }
7731 run_test 99 "cvs strange file/directory operations"
7732
7733 test_100() {
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735         [[ "$NETTYPE" =~ tcp ]] ||
7736                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7737         remote_ost_nodsh && skip "remote OST with nodsh"
7738         remote_mds_nodsh && skip "remote MDS with nodsh"
7739         remote_servers ||
7740                 skip "useless for local single node setup"
7741
7742         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7743                 [ "$PROT" != "tcp" ] && continue
7744                 RPORT=$(echo $REMOTE | cut -d: -f2)
7745                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7746
7747                 rc=0
7748                 LPORT=`echo $LOCAL | cut -d: -f2`
7749                 if [ $LPORT -ge 1024 ]; then
7750                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7751                         netstat -tna
7752                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7753                 fi
7754         done
7755         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7756 }
7757 run_test 100 "check local port using privileged port ==========="
7758
7759 function get_named_value()
7760 {
7761     local tag
7762
7763     tag=$1
7764     while read ;do
7765         line=$REPLY
7766         case $line in
7767         $tag*)
7768             echo $line | sed "s/^$tag[ ]*//"
7769             break
7770             ;;
7771         esac
7772     done
7773 }
7774
7775 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7776                    awk '/^max_cached_mb/ { print $2 }')
7777
7778 cleanup_101a() {
7779         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7780         trap 0
7781 }
7782
7783 test_101a() {
7784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7785         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7786
7787         local s
7788         local discard
7789         local nreads=10000
7790         local cache_limit=32
7791
7792         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7793         trap cleanup_101a EXIT
7794         $LCTL set_param -n llite.*.read_ahead_stats 0
7795         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7796
7797         #
7798         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7799         #
7800         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7801         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7802
7803         discard=0
7804         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7805                 get_named_value 'read but discarded' | cut -d" " -f1); do
7806                         discard=$(($discard + $s))
7807         done
7808         cleanup_101a
7809
7810         if [[ $(($discard * 10)) -gt $nreads ]]; then
7811                 $LCTL get_param osc.*-osc*.rpc_stats
7812                 $LCTL get_param llite.*.read_ahead_stats
7813                 error "too many ($discard) discarded pages"
7814         fi
7815         rm -f $DIR/$tfile || true
7816 }
7817 run_test 101a "check read-ahead for random reads"
7818
7819 setup_test101bc() {
7820         test_mkdir $DIR/$tdir
7821         local ssize=$1
7822         local FILE_LENGTH=$2
7823         STRIPE_OFFSET=0
7824
7825         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7826
7827         local list=$(comma_list $(osts_nodes))
7828         set_osd_param $list '' read_cache_enable 0
7829         set_osd_param $list '' writethrough_cache_enable 0
7830
7831         trap cleanup_test101bc EXIT
7832         # prepare the read-ahead file
7833         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7834
7835         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7836                                 count=$FILE_SIZE_MB 2> /dev/null
7837
7838 }
7839
7840 cleanup_test101bc() {
7841         trap 0
7842         rm -rf $DIR/$tdir
7843         rm -f $DIR/$tfile
7844
7845         local list=$(comma_list $(osts_nodes))
7846         set_osd_param $list '' read_cache_enable 1
7847         set_osd_param $list '' writethrough_cache_enable 1
7848 }
7849
7850 calc_total() {
7851         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7852 }
7853
7854 ra_check_101() {
7855         local READ_SIZE=$1
7856         local STRIPE_SIZE=$2
7857         local FILE_LENGTH=$3
7858         local RA_INC=1048576
7859         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7860         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7861                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7862         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7863                         get_named_value 'read but discarded' |
7864                         cut -d" " -f1 | calc_total)
7865         if [[ $DISCARD -gt $discard_limit ]]; then
7866                 $LCTL get_param llite.*.read_ahead_stats
7867                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7868         else
7869                 echo "Read-ahead success for size ${READ_SIZE}"
7870         fi
7871 }
7872
7873 test_101b() {
7874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7876
7877         local STRIPE_SIZE=1048576
7878         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7879
7880         if [ $SLOW == "yes" ]; then
7881                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7882         else
7883                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7884         fi
7885
7886         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7887
7888         # prepare the read-ahead file
7889         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7890         cancel_lru_locks osc
7891         for BIDX in 2 4 8 16 32 64 128 256
7892         do
7893                 local BSIZE=$((BIDX*4096))
7894                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7895                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7896                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7897                 $LCTL set_param -n llite.*.read_ahead_stats 0
7898                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7899                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7900                 cancel_lru_locks osc
7901                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7902         done
7903         cleanup_test101bc
7904         true
7905 }
7906 run_test 101b "check stride-io mode read-ahead ================="
7907
7908 test_101c() {
7909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7910
7911         local STRIPE_SIZE=1048576
7912         local FILE_LENGTH=$((STRIPE_SIZE*100))
7913         local nreads=10000
7914         local rsize=65536
7915         local osc_rpc_stats
7916
7917         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7918
7919         cancel_lru_locks osc
7920         $LCTL set_param osc.*.rpc_stats 0
7921         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7922         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7923                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7924                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7925                 local size
7926
7927                 if [ $lines -le 20 ]; then
7928                         continue
7929                 fi
7930                 for size in 1 2 4 8; do
7931                         local rpc=$(echo "$stats" |
7932                                     awk '($1 == "'$size':") {print $2; exit; }')
7933                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7934                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7935                 done
7936                 echo "$osc_rpc_stats check passed!"
7937         done
7938         cleanup_test101bc
7939         true
7940 }
7941 run_test 101c "check stripe_size aligned read-ahead ================="
7942
7943 set_read_ahead() {
7944         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7945         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7946 }
7947
7948 test_101d() {
7949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7950
7951         local file=$DIR/$tfile
7952         local sz_MB=${FILESIZE_101d:-500}
7953         local ra_MB=${READAHEAD_MB:-40}
7954
7955         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7956         [ $free_MB -lt $sz_MB ] &&
7957                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7958
7959         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7960         $LFS setstripe -c -1 $file || error "setstripe failed"
7961
7962         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7963         echo Cancel LRU locks on lustre client to flush the client cache
7964         cancel_lru_locks osc
7965
7966         echo Disable read-ahead
7967         local old_READAHEAD=$(set_read_ahead 0)
7968
7969         echo Reading the test file $file with read-ahead disabled
7970         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7971
7972         echo Cancel LRU locks on lustre client to flush the client cache
7973         cancel_lru_locks osc
7974         echo Enable read-ahead with ${ra_MB}MB
7975         set_read_ahead $ra_MB
7976
7977         echo Reading the test file $file with read-ahead enabled
7978         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7979
7980         echo "read-ahead disabled time read $raOFF"
7981         echo "read-ahead enabled  time read $raON"
7982
7983         set_read_ahead $old_READAHEAD
7984         rm -f $file
7985         wait_delete_completed
7986
7987         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
7988                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7989 }
7990 run_test 101d "file read with and without read-ahead enabled"
7991
7992 test_101e() {
7993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7994
7995         local file=$DIR/$tfile
7996         local size_KB=500  #KB
7997         local count=100
7998         local bsize=1024
7999
8000         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8001         local need_KB=$((count * size_KB))
8002         [[ $free_KB -le $need_KB ]] &&
8003                 skip_env "Need free space $need_KB, have $free_KB"
8004
8005         echo "Creating $count ${size_KB}K test files"
8006         for ((i = 0; i < $count; i++)); do
8007                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8008         done
8009
8010         echo "Cancel LRU locks on lustre client to flush the client cache"
8011         cancel_lru_locks $OSC
8012
8013         echo "Reset readahead stats"
8014         $LCTL set_param -n llite.*.read_ahead_stats 0
8015
8016         for ((i = 0; i < $count; i++)); do
8017                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8018         done
8019
8020         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8021                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8022
8023         for ((i = 0; i < $count; i++)); do
8024                 rm -rf $file.$i 2>/dev/null
8025         done
8026
8027         #10000 means 20% reads are missing in readahead
8028         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8029 }
8030 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8031
8032 test_101f() {
8033         which iozone || skip_env "no iozone installed"
8034
8035         local old_debug=$($LCTL get_param debug)
8036         old_debug=${old_debug#*=}
8037         $LCTL set_param debug="reada mmap"
8038
8039         # create a test file
8040         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8041
8042         echo Cancel LRU locks on lustre client to flush the client cache
8043         cancel_lru_locks osc
8044
8045         echo Reset readahead stats
8046         $LCTL set_param -n llite.*.read_ahead_stats 0
8047
8048         echo mmap read the file with small block size
8049         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8050                 > /dev/null 2>&1
8051
8052         echo checking missing pages
8053         $LCTL get_param llite.*.read_ahead_stats
8054         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8055                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8056
8057         $LCTL set_param debug="$old_debug"
8058         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8059         rm -f $DIR/$tfile
8060 }
8061 run_test 101f "check mmap read performance"
8062
8063 test_101g_brw_size_test() {
8064         local mb=$1
8065         local pages=$((mb * 1048576 / PAGE_SIZE))
8066         local file=$DIR/$tfile
8067
8068         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8069                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8070         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8071                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8072                         return 2
8073         done
8074
8075         stack_trap "rm -f $file" EXIT
8076         $LCTL set_param -n osc.*.rpc_stats=0
8077
8078         # 10 RPCs should be enough for the test
8079         local count=10
8080         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8081                 { error "dd write ${mb} MB blocks failed"; return 3; }
8082         cancel_lru_locks osc
8083         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8084                 { error "dd write ${mb} MB blocks failed"; return 4; }
8085
8086         # calculate number of full-sized read and write RPCs
8087         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8088                 sed -n '/pages per rpc/,/^$/p' |
8089                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8090                 END { print reads,writes }'))
8091         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8092                 return 5
8093         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8094                 return 6
8095
8096         return 0
8097 }
8098
8099 test_101g() {
8100         remote_ost_nodsh && skip "remote OST with nodsh"
8101
8102         local rpcs
8103         local osts=$(get_facets OST)
8104         local list=$(comma_list $(osts_nodes))
8105         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8106         local brw_size="obdfilter.*.brw_size"
8107
8108         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8109
8110         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8111
8112         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8113                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8114                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8115            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8116                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8117                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8118
8119                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8120                         suffix="M"
8121
8122                 if [[ $orig_mb -lt 16 ]]; then
8123                         save_lustre_params $osts "$brw_size" > $p
8124                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8125                                 error "set 16MB RPC size failed"
8126
8127                         echo "remount client to enable new RPC size"
8128                         remount_client $MOUNT || error "remount_client failed"
8129                 fi
8130
8131                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8132                 # should be able to set brw_size=12, but no rpc_stats for that
8133                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8134         fi
8135
8136         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8137
8138         if [[ $orig_mb -lt 16 ]]; then
8139                 restore_lustre_params < $p
8140                 remount_client $MOUNT || error "remount_client restore failed"
8141         fi
8142
8143         rm -f $p $DIR/$tfile
8144 }
8145 run_test 101g "Big bulk(4/16 MiB) readahead"
8146
8147 setup_test102() {
8148         test_mkdir $DIR/$tdir
8149         chown $RUNAS_ID $DIR/$tdir
8150         STRIPE_SIZE=65536
8151         STRIPE_OFFSET=1
8152         STRIPE_COUNT=$OSTCOUNT
8153         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8154
8155         trap cleanup_test102 EXIT
8156         cd $DIR
8157         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8158         cd $DIR/$tdir
8159         for num in 1 2 3 4; do
8160                 for count in $(seq 1 $STRIPE_COUNT); do
8161                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8162                                 local size=`expr $STRIPE_SIZE \* $num`
8163                                 local file=file"$num-$idx-$count"
8164                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8165                         done
8166                 done
8167         done
8168
8169         cd $DIR
8170         $1 tar cf $TMP/f102.tar $tdir --xattrs
8171 }
8172
8173 cleanup_test102() {
8174         trap 0
8175         rm -f $TMP/f102.tar
8176         rm -rf $DIR/d0.sanity/d102
8177 }
8178
8179 test_102a() {
8180         [ "$UID" != 0 ] && skip "must run as root"
8181         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8182                 skip_env "must have user_xattr"
8183
8184         [ -z "$(which setfattr 2>/dev/null)" ] &&
8185                 skip_env "could not find setfattr"
8186
8187         local testfile=$DIR/$tfile
8188
8189         touch $testfile
8190         echo "set/get xattr..."
8191         setfattr -n trusted.name1 -v value1 $testfile ||
8192                 error "setfattr -n trusted.name1=value1 $testfile failed"
8193         getfattr -n trusted.name1 $testfile 2> /dev/null |
8194           grep "trusted.name1=.value1" ||
8195                 error "$testfile missing trusted.name1=value1"
8196
8197         setfattr -n user.author1 -v author1 $testfile ||
8198                 error "setfattr -n user.author1=author1 $testfile failed"
8199         getfattr -n user.author1 $testfile 2> /dev/null |
8200           grep "user.author1=.author1" ||
8201                 error "$testfile missing trusted.author1=author1"
8202
8203         echo "listxattr..."
8204         setfattr -n trusted.name2 -v value2 $testfile ||
8205                 error "$testfile unable to set trusted.name2"
8206         setfattr -n trusted.name3 -v value3 $testfile ||
8207                 error "$testfile unable to set trusted.name3"
8208         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8209             grep "trusted.name" | wc -l) -eq 3 ] ||
8210                 error "$testfile missing 3 trusted.name xattrs"
8211
8212         setfattr -n user.author2 -v author2 $testfile ||
8213                 error "$testfile unable to set user.author2"
8214         setfattr -n user.author3 -v author3 $testfile ||
8215                 error "$testfile unable to set user.author3"
8216         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8217             grep "user.author" | wc -l) -eq 3 ] ||
8218                 error "$testfile missing 3 user.author xattrs"
8219
8220         echo "remove xattr..."
8221         setfattr -x trusted.name1 $testfile ||
8222                 error "$testfile error deleting trusted.name1"
8223         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8224                 error "$testfile did not delete trusted.name1 xattr"
8225
8226         setfattr -x user.author1 $testfile ||
8227                 error "$testfile error deleting user.author1"
8228         echo "set lustre special xattr ..."
8229         $LFS setstripe -c1 $testfile
8230         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8231                 awk -F "=" '/trusted.lov/ { print $2 }' )
8232         setfattr -n "trusted.lov" -v $lovea $testfile ||
8233                 error "$testfile doesn't ignore setting trusted.lov again"
8234         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8235                 error "$testfile allow setting invalid trusted.lov"
8236         rm -f $testfile
8237 }
8238 run_test 102a "user xattr test =================================="
8239
8240 test_102b() {
8241         [ -z "$(which setfattr 2>/dev/null)" ] &&
8242                 skip_env "could not find setfattr"
8243         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8244
8245         # b10930: get/set/list trusted.lov xattr
8246         echo "get/set/list trusted.lov xattr ..."
8247         local testfile=$DIR/$tfile
8248         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8249                 error "setstripe failed"
8250         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8251                 error "getstripe failed"
8252         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8253                 error "can't get trusted.lov from $testfile"
8254
8255         local testfile2=${testfile}2
8256         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8257                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8258
8259         $MCREATE $testfile2
8260         setfattr -n trusted.lov -v $value $testfile2
8261         local stripe_size=$($LFS getstripe -S $testfile2)
8262         local stripe_count=$($LFS getstripe -c $testfile2)
8263         [[ $stripe_size -eq 65536 ]] ||
8264                 error "stripe size $stripe_size != 65536"
8265         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8266                 error "stripe count $stripe_count != $STRIPECOUNT"
8267         rm -f $DIR/$tfile
8268 }
8269 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8270
8271 test_102c() {
8272         [ -z "$(which setfattr 2>/dev/null)" ] &&
8273                 skip_env "could not find setfattr"
8274         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8275
8276         # b10930: get/set/list lustre.lov xattr
8277         echo "get/set/list lustre.lov xattr ..."
8278         test_mkdir $DIR/$tdir
8279         chown $RUNAS_ID $DIR/$tdir
8280         local testfile=$DIR/$tdir/$tfile
8281         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8282                 error "setstripe failed"
8283         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8284                 error "getstripe failed"
8285         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8286         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8287
8288         local testfile2=${testfile}2
8289         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8290                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8291
8292         $RUNAS $MCREATE $testfile2
8293         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8294         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8295         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8296         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8297         [ $stripe_count -eq $STRIPECOUNT ] ||
8298                 error "stripe count $stripe_count != $STRIPECOUNT"
8299 }
8300 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8301
8302 compare_stripe_info1() {
8303         local stripe_index_all_zero=true
8304
8305         for num in 1 2 3 4; do
8306                 for count in $(seq 1 $STRIPE_COUNT); do
8307                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8308                                 local size=$((STRIPE_SIZE * num))
8309                                 local file=file"$num-$offset-$count"
8310                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8311                                 [[ $stripe_size -ne $size ]] &&
8312                                     error "$file: size $stripe_size != $size"
8313                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8314                                 # allow fewer stripes to be created, ORI-601
8315                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8316                                     error "$file: count $stripe_count != $count"
8317                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8318                                 [[ $stripe_index -ne 0 ]] &&
8319                                         stripe_index_all_zero=false
8320                         done
8321                 done
8322         done
8323         $stripe_index_all_zero &&
8324                 error "all files are being extracted starting from OST index 0"
8325         return 0
8326 }
8327
8328 have_xattrs_include() {
8329         tar --help | grep -q xattrs-include &&
8330                 echo --xattrs-include="lustre.*"
8331 }
8332
8333 test_102d() {
8334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8335         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8336
8337         XINC=$(have_xattrs_include)
8338         setup_test102
8339         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8340         cd $DIR/$tdir/$tdir
8341         compare_stripe_info1
8342 }
8343 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8344
8345 test_102f() {
8346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8347         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8348
8349         XINC=$(have_xattrs_include)
8350         setup_test102
8351         test_mkdir $DIR/$tdir.restore
8352         cd $DIR
8353         tar cf - --xattrs $tdir | tar xf - \
8354                 -C $DIR/$tdir.restore --xattrs $XINC
8355         cd $DIR/$tdir.restore/$tdir
8356         compare_stripe_info1
8357 }
8358 run_test 102f "tar copy files, not keep osts"
8359
8360 grow_xattr() {
8361         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8362                 skip "must have user_xattr"
8363         [ -z "$(which setfattr 2>/dev/null)" ] &&
8364                 skip_env "could not find setfattr"
8365         [ -z "$(which getfattr 2>/dev/null)" ] &&
8366                 skip_env "could not find getfattr"
8367
8368         local xsize=${1:-1024}  # in bytes
8369         local file=$DIR/$tfile
8370         local value="$(generate_string $xsize)"
8371         local xbig=trusted.big
8372         local toobig=$2
8373
8374         touch $file
8375         log "save $xbig on $file"
8376         if [ -z "$toobig" ]
8377         then
8378                 setfattr -n $xbig -v $value $file ||
8379                         error "saving $xbig on $file failed"
8380         else
8381                 setfattr -n $xbig -v $value $file &&
8382                         error "saving $xbig on $file succeeded"
8383                 return 0
8384         fi
8385
8386         local orig=$(get_xattr_value $xbig $file)
8387         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8388
8389         local xsml=trusted.sml
8390         log "save $xsml on $file"
8391         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8392
8393         local new=$(get_xattr_value $xbig $file)
8394         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8395
8396         log "grow $xsml on $file"
8397         setfattr -n $xsml -v "$value" $file ||
8398                 error "growing $xsml on $file failed"
8399
8400         new=$(get_xattr_value $xbig $file)
8401         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8402         log "$xbig still valid after growing $xsml"
8403
8404         rm -f $file
8405 }
8406
8407 test_102h() { # bug 15777
8408         grow_xattr 1024
8409 }
8410 run_test 102h "grow xattr from inside inode to external block"
8411
8412 test_102ha() {
8413         large_xattr_enabled || skip_env "ea_inode feature disabled"
8414
8415         echo "setting xattr of max xattr size: $(max_xattr_size)"
8416         grow_xattr $(max_xattr_size)
8417
8418         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8419         echo "This should fail:"
8420         grow_xattr $(($(max_xattr_size) + 10)) 1
8421 }
8422 run_test 102ha "grow xattr from inside inode to external inode"
8423
8424 test_102i() { # bug 17038
8425         [ -z "$(which getfattr 2>/dev/null)" ] &&
8426                 skip "could not find getfattr"
8427
8428         touch $DIR/$tfile
8429         ln -s $DIR/$tfile $DIR/${tfile}link
8430         getfattr -n trusted.lov $DIR/$tfile ||
8431                 error "lgetxattr on $DIR/$tfile failed"
8432         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8433                 grep -i "no such attr" ||
8434                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8435         rm -f $DIR/$tfile $DIR/${tfile}link
8436 }
8437 run_test 102i "lgetxattr test on symbolic link ============"
8438
8439 test_102j() {
8440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8441         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8442
8443         XINC=$(have_xattrs_include)
8444         setup_test102 "$RUNAS"
8445         chown $RUNAS_ID $DIR/$tdir
8446         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8447         cd $DIR/$tdir/$tdir
8448         compare_stripe_info1 "$RUNAS"
8449 }
8450 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8451
8452 test_102k() {
8453         [ -z "$(which setfattr 2>/dev/null)" ] &&
8454                 skip "could not find setfattr"
8455
8456         touch $DIR/$tfile
8457         # b22187 just check that does not crash for regular file.
8458         setfattr -n trusted.lov $DIR/$tfile
8459         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8460         local test_kdir=$DIR/$tdir
8461         test_mkdir $test_kdir
8462         local default_size=$($LFS getstripe -S $test_kdir)
8463         local default_count=$($LFS getstripe -c $test_kdir)
8464         local default_offset=$($LFS getstripe -i $test_kdir)
8465         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8466                 error 'dir setstripe failed'
8467         setfattr -n trusted.lov $test_kdir
8468         local stripe_size=$($LFS getstripe -S $test_kdir)
8469         local stripe_count=$($LFS getstripe -c $test_kdir)
8470         local stripe_offset=$($LFS getstripe -i $test_kdir)
8471         [ $stripe_size -eq $default_size ] ||
8472                 error "stripe size $stripe_size != $default_size"
8473         [ $stripe_count -eq $default_count ] ||
8474                 error "stripe count $stripe_count != $default_count"
8475         [ $stripe_offset -eq $default_offset ] ||
8476                 error "stripe offset $stripe_offset != $default_offset"
8477         rm -rf $DIR/$tfile $test_kdir
8478 }
8479 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8480
8481 test_102l() {
8482         [ -z "$(which getfattr 2>/dev/null)" ] &&
8483                 skip "could not find getfattr"
8484
8485         # LU-532 trusted. xattr is invisible to non-root
8486         local testfile=$DIR/$tfile
8487
8488         touch $testfile
8489
8490         echo "listxattr as user..."
8491         chown $RUNAS_ID $testfile
8492         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8493             grep -q "trusted" &&
8494                 error "$testfile trusted xattrs are user visible"
8495
8496         return 0;
8497 }
8498 run_test 102l "listxattr size test =================================="
8499
8500 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8501         local path=$DIR/$tfile
8502         touch $path
8503
8504         listxattr_size_check $path || error "listattr_size_check $path failed"
8505 }
8506 run_test 102m "Ensure listxattr fails on small bufffer ========"
8507
8508 cleanup_test102
8509
8510 getxattr() { # getxattr path name
8511         # Return the base64 encoding of the value of xattr name on path.
8512         local path=$1
8513         local name=$2
8514
8515         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8516         # file: $path
8517         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8518         #
8519         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8520
8521         getfattr --absolute-names --encoding=base64 --name=$name $path |
8522                 awk -F= -v name=$name '$1 == name {
8523                         print substr($0, index($0, "=") + 1);
8524         }'
8525 }
8526
8527 test_102n() { # LU-4101 mdt: protect internal xattrs
8528         [ -z "$(which setfattr 2>/dev/null)" ] &&
8529                 skip "could not find setfattr"
8530         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8531         then
8532                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8533         fi
8534
8535         local file0=$DIR/$tfile.0
8536         local file1=$DIR/$tfile.1
8537         local xattr0=$TMP/$tfile.0
8538         local xattr1=$TMP/$tfile.1
8539         local namelist="lov lma lmv link fid version som hsm"
8540         local name
8541         local value
8542
8543         rm -rf $file0 $file1 $xattr0 $xattr1
8544         touch $file0 $file1
8545
8546         # Get 'before' xattrs of $file1.
8547         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8548
8549         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8550                 namelist+=" lfsck_namespace"
8551         for name in $namelist; do
8552                 # Try to copy xattr from $file0 to $file1.
8553                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8554
8555                 setfattr --name=trusted.$name --value="$value" $file1 ||
8556                         error "setxattr 'trusted.$name' failed"
8557
8558                 # Try to set a garbage xattr.
8559                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8560
8561                 if [[ x$name == "xlov" ]]; then
8562                         setfattr --name=trusted.lov --value="$value" $file1 &&
8563                         error "setxattr invalid 'trusted.lov' success"
8564                 else
8565                         setfattr --name=trusted.$name --value="$value" $file1 ||
8566                                 error "setxattr invalid 'trusted.$name' failed"
8567                 fi
8568
8569                 # Try to remove the xattr from $file1. We don't care if this
8570                 # appears to succeed or fail, we just don't want there to be
8571                 # any changes or crashes.
8572                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8573         done
8574
8575         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8576         then
8577                 name="lfsck_ns"
8578                 # Try to copy xattr from $file0 to $file1.
8579                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8580
8581                 setfattr --name=trusted.$name --value="$value" $file1 ||
8582                         error "setxattr 'trusted.$name' failed"
8583
8584                 # Try to set a garbage xattr.
8585                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8586
8587                 setfattr --name=trusted.$name --value="$value" $file1 ||
8588                         error "setxattr 'trusted.$name' failed"
8589
8590                 # Try to remove the xattr from $file1. We don't care if this
8591                 # appears to succeed or fail, we just don't want there to be
8592                 # any changes or crashes.
8593                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8594         fi
8595
8596         # Get 'after' xattrs of file1.
8597         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8598
8599         if ! diff $xattr0 $xattr1; then
8600                 error "before and after xattrs of '$file1' differ"
8601         fi
8602
8603         rm -rf $file0 $file1 $xattr0 $xattr1
8604
8605         return 0
8606 }
8607 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8608
8609 test_102p() { # LU-4703 setxattr did not check ownership
8610         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8611                 skip "MDS needs to be at least 2.5.56"
8612
8613         local testfile=$DIR/$tfile
8614
8615         touch $testfile
8616
8617         echo "setfacl as user..."
8618         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8619         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8620
8621         echo "setfattr as user..."
8622         setfacl -m "u:$RUNAS_ID:---" $testfile
8623         $RUNAS setfattr -x system.posix_acl_access $testfile
8624         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8625 }
8626 run_test 102p "check setxattr(2) correctly fails without permission"
8627
8628 test_102q() {
8629         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8630                 skip "MDS needs to be at least 2.6.92"
8631
8632         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8633 }
8634 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8635
8636 test_102r() {
8637         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8638                 skip "MDS needs to be at least 2.6.93"
8639
8640         touch $DIR/$tfile || error "touch"
8641         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8642         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8643         rm $DIR/$tfile || error "rm"
8644
8645         #normal directory
8646         mkdir -p $DIR/$tdir || error "mkdir"
8647         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8648         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8649         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8650                 error "$testfile error deleting user.author1"
8651         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8652                 grep "user.$(basename $tdir)" &&
8653                 error "$tdir did not delete user.$(basename $tdir)"
8654         rmdir $DIR/$tdir || error "rmdir"
8655
8656         #striped directory
8657         test_mkdir $DIR/$tdir
8658         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8659         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8660         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8661                 error "$testfile error deleting user.author1"
8662         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8663                 grep "user.$(basename $tdir)" &&
8664                 error "$tdir did not delete user.$(basename $tdir)"
8665         rmdir $DIR/$tdir || error "rm striped dir"
8666 }
8667 run_test 102r "set EAs with empty values"
8668
8669 test_102s() {
8670         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8671                 skip "MDS needs to be at least 2.11.52"
8672
8673         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8674
8675         save_lustre_params client "llite.*.xattr_cache" > $save
8676
8677         for cache in 0 1; do
8678                 lctl set_param llite.*.xattr_cache=$cache
8679
8680                 rm -f $DIR/$tfile
8681                 touch $DIR/$tfile || error "touch"
8682                 for prefix in lustre security system trusted user; do
8683                         # Note getxattr() may fail with 'Operation not
8684                         # supported' or 'No such attribute' depending
8685                         # on prefix and cache.
8686                         getfattr -n $prefix.n102s $DIR/$tfile &&
8687                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8688                 done
8689         done
8690
8691         restore_lustre_params < $save
8692 }
8693 run_test 102s "getting nonexistent xattrs should fail"
8694
8695 test_102t() {
8696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8697                 skip "MDS needs to be at least 2.11.52"
8698
8699         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8700
8701         save_lustre_params client "llite.*.xattr_cache" > $save
8702
8703         for cache in 0 1; do
8704                 lctl set_param llite.*.xattr_cache=$cache
8705
8706                 for buf_size in 0 256; do
8707                         rm -f $DIR/$tfile
8708                         touch $DIR/$tfile || error "touch"
8709                         setfattr -n user.multiop $DIR/$tfile
8710                         $MULTIOP $DIR/$tfile oa$buf_size ||
8711                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8712                 done
8713         done
8714
8715         restore_lustre_params < $save
8716 }
8717 run_test 102t "zero length xattr values handled correctly"
8718
8719 run_acl_subtest()
8720 {
8721     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8722     return $?
8723 }
8724
8725 test_103a() {
8726         [ "$UID" != 0 ] && skip "must run as root"
8727         $GSS && skip_env "could not run under gss"
8728         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8729                 skip_env "must have acl enabled"
8730         [ -z "$(which setfacl 2>/dev/null)" ] &&
8731                 skip_env "could not find setfacl"
8732         remote_mds_nodsh && skip "remote MDS with nodsh"
8733
8734         gpasswd -a daemon bin                           # LU-5641
8735         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8736
8737         declare -a identity_old
8738
8739         for num in $(seq $MDSCOUNT); do
8740                 switch_identity $num true || identity_old[$num]=$?
8741         done
8742
8743         SAVE_UMASK=$(umask)
8744         umask 0022
8745         mkdir -p $DIR/$tdir
8746         cd $DIR/$tdir
8747
8748         echo "performing cp ..."
8749         run_acl_subtest cp || error "run_acl_subtest cp failed"
8750         echo "performing getfacl-noacl..."
8751         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8752         echo "performing misc..."
8753         run_acl_subtest misc || error  "misc test failed"
8754         echo "performing permissions..."
8755         run_acl_subtest permissions || error "permissions failed"
8756         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8757         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
8758                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
8759                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
8760         then
8761                 echo "performing permissions xattr..."
8762                 run_acl_subtest permissions_xattr ||
8763                         error "permissions_xattr failed"
8764         fi
8765         echo "performing setfacl..."
8766         run_acl_subtest setfacl || error  "setfacl test failed"
8767
8768         # inheritance test got from HP
8769         echo "performing inheritance..."
8770         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8771         chmod +x make-tree || error "chmod +x failed"
8772         run_acl_subtest inheritance || error "inheritance test failed"
8773         rm -f make-tree
8774
8775         echo "LU-974 ignore umask when acl is enabled..."
8776         run_acl_subtest 974 || error "LU-974 umask test failed"
8777         if [ $MDSCOUNT -ge 2 ]; then
8778                 run_acl_subtest 974_remote ||
8779                         error "LU-974 umask test failed under remote dir"
8780         fi
8781
8782         echo "LU-2561 newly created file is same size as directory..."
8783         if [ "$mds1_FSTYPE" != "zfs" ]; then
8784                 run_acl_subtest 2561 || error "LU-2561 test failed"
8785         else
8786                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8787         fi
8788
8789         run_acl_subtest 4924 || error "LU-4924 test failed"
8790
8791         cd $SAVE_PWD
8792         umask $SAVE_UMASK
8793
8794         for num in $(seq $MDSCOUNT); do
8795                 if [ "${identity_old[$num]}" = 1 ]; then
8796                         switch_identity $num false || identity_old[$num]=$?
8797                 fi
8798         done
8799 }
8800 run_test 103a "acl test"
8801
8802 test_103b() {
8803         declare -a pids
8804         local U
8805
8806         for U in {0..511}; do
8807                 {
8808                 local O=$(printf "%04o" $U)
8809
8810                 umask $(printf "%04o" $((511 ^ $O)))
8811                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8812                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8813
8814                 (( $S == ($O & 0666) )) ||
8815                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8816
8817                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8818                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8819                 (( $S == ($O & 0666) )) ||
8820                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8821
8822                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8823                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8824                 (( $S == ($O & 0666) )) ||
8825                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8826                 rm -f $DIR/$tfile.[smp]$0
8827                 } &
8828                 local pid=$!
8829
8830                 # limit the concurrently running threads to 64. LU-11878
8831                 local idx=$((U % 64))
8832                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8833                 pids[idx]=$pid
8834         done
8835         wait
8836 }
8837 run_test 103b "umask lfs setstripe"
8838
8839 test_103c() {
8840         mkdir -p $DIR/$tdir
8841         cp -rp $DIR/$tdir $DIR/$tdir.bak
8842
8843         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8844                 error "$DIR/$tdir shouldn't contain default ACL"
8845         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8846                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8847         true
8848 }
8849 run_test 103c "'cp -rp' won't set empty acl"
8850
8851 test_104a() {
8852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8853
8854         touch $DIR/$tfile
8855         lfs df || error "lfs df failed"
8856         lfs df -ih || error "lfs df -ih failed"
8857         lfs df -h $DIR || error "lfs df -h $DIR failed"
8858         lfs df -i $DIR || error "lfs df -i $DIR failed"
8859         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8860         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8861
8862         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8863         lctl --device %$OSC deactivate
8864         lfs df || error "lfs df with deactivated OSC failed"
8865         lctl --device %$OSC activate
8866         # wait the osc back to normal
8867         wait_osc_import_ready client ost
8868
8869         lfs df || error "lfs df with reactivated OSC failed"
8870         rm -f $DIR/$tfile
8871 }
8872 run_test 104a "lfs df [-ih] [path] test ========================="
8873
8874 test_104b() {
8875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8876         [ $RUNAS_ID -eq $UID ] &&
8877                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8878
8879         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8880                         grep "Permission denied" | wc -l)))
8881         if [ $denied_cnt -ne 0 ]; then
8882                 error "lfs check servers test failed"
8883         fi
8884 }
8885 run_test 104b "$RUNAS lfs check servers test ===================="
8886
8887 test_105a() {
8888         # doesn't work on 2.4 kernels
8889         touch $DIR/$tfile
8890         if $(flock_is_enabled); then
8891                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8892         else
8893                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8894         fi
8895         rm -f $DIR/$tfile
8896 }
8897 run_test 105a "flock when mounted without -o flock test ========"
8898
8899 test_105b() {
8900         touch $DIR/$tfile
8901         if $(flock_is_enabled); then
8902                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8903         else
8904                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8905         fi
8906         rm -f $DIR/$tfile
8907 }
8908 run_test 105b "fcntl when mounted without -o flock test ========"
8909
8910 test_105c() {
8911         touch $DIR/$tfile
8912         if $(flock_is_enabled); then
8913                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8914         else
8915                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8916         fi
8917         rm -f $DIR/$tfile
8918 }
8919 run_test 105c "lockf when mounted without -o flock test"
8920
8921 test_105d() { # bug 15924
8922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8923
8924         test_mkdir $DIR/$tdir
8925         flock_is_enabled || skip_env "mount w/o flock enabled"
8926         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8927         $LCTL set_param fail_loc=0x80000315
8928         flocks_test 2 $DIR/$tdir
8929 }
8930 run_test 105d "flock race (should not freeze) ========"
8931
8932 test_105e() { # bug 22660 && 22040
8933         flock_is_enabled || skip_env "mount w/o flock enabled"
8934
8935         touch $DIR/$tfile
8936         flocks_test 3 $DIR/$tfile
8937 }
8938 run_test 105e "Two conflicting flocks from same process"
8939
8940 test_106() { #bug 10921
8941         test_mkdir $DIR/$tdir
8942         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8943         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8944 }
8945 run_test 106 "attempt exec of dir followed by chown of that dir"
8946
8947 test_107() {
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949
8950         CDIR=`pwd`
8951         local file=core
8952
8953         cd $DIR
8954         rm -f $file
8955
8956         local save_pattern=$(sysctl -n kernel.core_pattern)
8957         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8958         sysctl -w kernel.core_pattern=$file
8959         sysctl -w kernel.core_uses_pid=0
8960
8961         ulimit -c unlimited
8962         sleep 60 &
8963         SLEEPPID=$!
8964
8965         sleep 1
8966
8967         kill -s 11 $SLEEPPID
8968         wait $SLEEPPID
8969         if [ -e $file ]; then
8970                 size=`stat -c%s $file`
8971                 [ $size -eq 0 ] && error "Fail to create core file $file"
8972         else
8973                 error "Fail to create core file $file"
8974         fi
8975         rm -f $file
8976         sysctl -w kernel.core_pattern=$save_pattern
8977         sysctl -w kernel.core_uses_pid=$save_uses_pid
8978         cd $CDIR
8979 }
8980 run_test 107 "Coredump on SIG"
8981
8982 test_110() {
8983         test_mkdir $DIR/$tdir
8984         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8985         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8986                 error "mkdir with 256 char should fail, but did not"
8987         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8988                 error "create with 255 char failed"
8989         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8990                 error "create with 256 char should fail, but did not"
8991
8992         ls -l $DIR/$tdir
8993         rm -rf $DIR/$tdir
8994 }
8995 run_test 110 "filename length checking"
8996
8997 #
8998 # Purpose: To verify dynamic thread (OSS) creation.
8999 #
9000 test_115() {
9001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9002         remote_ost_nodsh && skip "remote OST with nodsh"
9003
9004         # Lustre does not stop service threads once they are started.
9005         # Reset number of running threads to default.
9006         stopall
9007         setupall
9008
9009         local OSTIO_pre
9010         local save_params="$TMP/sanity-$TESTNAME.parameters"
9011
9012         # Get ll_ost_io count before I/O
9013         OSTIO_pre=$(do_facet ost1 \
9014                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9015         # Exit if lustre is not running (ll_ost_io not running).
9016         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9017
9018         echo "Starting with $OSTIO_pre threads"
9019         local thread_max=$((OSTIO_pre * 2))
9020         local rpc_in_flight=$((thread_max * 2))
9021         # Number of I/O Process proposed to be started.
9022         local nfiles
9023         local facets=$(get_facets OST)
9024
9025         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9026         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9027
9028         # Set in_flight to $rpc_in_flight
9029         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9030                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9031         nfiles=${rpc_in_flight}
9032         # Set ost thread_max to $thread_max
9033         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9034
9035         # 5 Minutes should be sufficient for max number of OSS
9036         # threads(thread_max) to be created.
9037         local timeout=300
9038
9039         # Start I/O.
9040         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9041         test_mkdir $DIR/$tdir
9042         for i in $(seq $nfiles); do
9043                 local file=$DIR/$tdir/${tfile}-$i
9044                 $LFS setstripe -c -1 -i 0 $file
9045                 ($WTL $file $timeout)&
9046         done
9047
9048         # I/O Started - Wait for thread_started to reach thread_max or report
9049         # error if thread_started is more than thread_max.
9050         echo "Waiting for thread_started to reach thread_max"
9051         local thread_started=0
9052         local end_time=$((SECONDS + timeout))
9053
9054         while [ $SECONDS -le $end_time ] ; do
9055                 echo -n "."
9056                 # Get ost i/o thread_started count.
9057                 thread_started=$(do_facet ost1 \
9058                         "$LCTL get_param \
9059                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9060                 # Break out if thread_started is equal/greater than thread_max
9061                 if [[ $thread_started -ge $thread_max ]]; then
9062                         echo ll_ost_io thread_started $thread_started, \
9063                                 equal/greater than thread_max $thread_max
9064                         break
9065                 fi
9066                 sleep 1
9067         done
9068
9069         # Cleanup - We have the numbers, Kill i/o jobs if running.
9070         jobcount=($(jobs -p))
9071         for i in $(seq 0 $((${#jobcount[@]}-1)))
9072         do
9073                 kill -9 ${jobcount[$i]}
9074                 if [ $? -ne 0 ] ; then
9075                         echo Warning: \
9076                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9077                 fi
9078         done
9079
9080         # Cleanup files left by WTL binary.
9081         for i in $(seq $nfiles); do
9082                 local file=$DIR/$tdir/${tfile}-$i
9083                 rm -rf $file
9084                 if [ $? -ne 0 ] ; then
9085                         echo "Warning: Failed to delete file $file"
9086                 fi
9087         done
9088
9089         restore_lustre_params <$save_params
9090         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9091
9092         # Error out if no new thread has started or Thread started is greater
9093         # than thread max.
9094         if [[ $thread_started -le $OSTIO_pre ||
9095                         $thread_started -gt $thread_max ]]; then
9096                 error "ll_ost_io: thread_started $thread_started" \
9097                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9098                       "No new thread started or thread started greater " \
9099                       "than thread_max."
9100         fi
9101 }
9102 run_test 115 "verify dynamic thread creation===================="
9103
9104 free_min_max () {
9105         wait_delete_completed
9106         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9107         echo "OST kbytes available: ${AVAIL[@]}"
9108         MAXV=${AVAIL[0]}
9109         MAXI=0
9110         MINV=${AVAIL[0]}
9111         MINI=0
9112         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9113                 #echo OST $i: ${AVAIL[i]}kb
9114                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9115                         MAXV=${AVAIL[i]}
9116                         MAXI=$i
9117                 fi
9118                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9119                         MINV=${AVAIL[i]}
9120                         MINI=$i
9121                 fi
9122         done
9123         echo "Min free space: OST $MINI: $MINV"
9124         echo "Max free space: OST $MAXI: $MAXV"
9125 }
9126
9127 test_116a() { # was previously test_116()
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9130         remote_mds_nodsh && skip "remote MDS with nodsh"
9131
9132         echo -n "Free space priority "
9133         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9134                 head -n1
9135         declare -a AVAIL
9136         free_min_max
9137
9138         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9139         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9140         trap simple_cleanup_common EXIT
9141
9142         # Check if we need to generate uneven OSTs
9143         test_mkdir -p $DIR/$tdir/OST${MINI}
9144         local FILL=$((MINV / 4))
9145         local DIFF=$((MAXV - MINV))
9146         local DIFF2=$((DIFF * 100 / MINV))
9147
9148         local threshold=$(do_facet $SINGLEMDS \
9149                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9150         threshold=${threshold%%%}
9151         echo -n "Check for uneven OSTs: "
9152         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9153
9154         if [[ $DIFF2 -gt $threshold ]]; then
9155                 echo "ok"
9156                 echo "Don't need to fill OST$MINI"
9157         else
9158                 # generate uneven OSTs. Write 2% over the QOS threshold value
9159                 echo "no"
9160                 DIFF=$((threshold - DIFF2 + 2))
9161                 DIFF2=$((MINV * DIFF / 100))
9162                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9163                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9164                         error "setstripe failed"
9165                 DIFF=$((DIFF2 / 2048))
9166                 i=0
9167                 while [ $i -lt $DIFF ]; do
9168                         i=$((i + 1))
9169                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9170                                 bs=2M count=1 2>/dev/null
9171                         echo -n .
9172                 done
9173                 echo .
9174                 sync
9175                 sleep_maxage
9176                 free_min_max
9177         fi
9178
9179         DIFF=$((MAXV - MINV))
9180         DIFF2=$((DIFF * 100 / MINV))
9181         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9182         if [ $DIFF2 -gt $threshold ]; then
9183                 echo "ok"
9184         else
9185                 echo "failed - QOS mode won't be used"
9186                 simple_cleanup_common
9187                 skip "QOS imbalance criteria not met"
9188         fi
9189
9190         MINI1=$MINI
9191         MINV1=$MINV
9192         MAXI1=$MAXI
9193         MAXV1=$MAXV
9194
9195         # now fill using QOS
9196         $LFS setstripe -c 1 $DIR/$tdir
9197         FILL=$((FILL / 200))
9198         if [ $FILL -gt 600 ]; then
9199                 FILL=600
9200         fi
9201         echo "writing $FILL files to QOS-assigned OSTs"
9202         i=0
9203         while [ $i -lt $FILL ]; do
9204                 i=$((i + 1))
9205                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9206                         count=1 2>/dev/null
9207                 echo -n .
9208         done
9209         echo "wrote $i 200k files"
9210         sync
9211         sleep_maxage
9212
9213         echo "Note: free space may not be updated, so measurements might be off"
9214         free_min_max
9215         DIFF2=$((MAXV - MINV))
9216         echo "free space delta: orig $DIFF final $DIFF2"
9217         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9218         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9219         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9220         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9221         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9222         if [[ $DIFF -gt 0 ]]; then
9223                 FILL=$((DIFF2 * 100 / DIFF - 100))
9224                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9225         fi
9226
9227         # Figure out which files were written where
9228         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9229                awk '/'$MINI1': / {print $2; exit}')
9230         echo $UUID
9231         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9232         echo "$MINC files created on smaller OST $MINI1"
9233         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9234                awk '/'$MAXI1': / {print $2; exit}')
9235         echo $UUID
9236         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9237         echo "$MAXC files created on larger OST $MAXI1"
9238         if [[ $MINC -gt 0 ]]; then
9239                 FILL=$((MAXC * 100 / MINC - 100))
9240                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9241         fi
9242         [[ $MAXC -gt $MINC ]] ||
9243                 error_ignore LU-9 "stripe QOS didn't balance free space"
9244         simple_cleanup_common
9245 }
9246 run_test 116a "stripe QOS: free space balance ==================="
9247
9248 test_116b() { # LU-2093
9249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9250         remote_mds_nodsh && skip "remote MDS with nodsh"
9251
9252 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9253         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9254                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9255         [ -z "$old_rr" ] && skip "no QOS"
9256         do_facet $SINGLEMDS lctl set_param \
9257                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9258         mkdir -p $DIR/$tdir
9259         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9260         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9261         do_facet $SINGLEMDS lctl set_param fail_loc=0
9262         rm -rf $DIR/$tdir
9263         do_facet $SINGLEMDS lctl set_param \
9264                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9265 }
9266 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9267
9268 test_117() # bug 10891
9269 {
9270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9271
9272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9273         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9274         lctl set_param fail_loc=0x21e
9275         > $DIR/$tfile || error "truncate failed"
9276         lctl set_param fail_loc=0
9277         echo "Truncate succeeded."
9278         rm -f $DIR/$tfile
9279 }
9280 run_test 117 "verify osd extend =========="
9281
9282 NO_SLOW_RESENDCOUNT=4
9283 export OLD_RESENDCOUNT=""
9284 set_resend_count () {
9285         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9286         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9287         lctl set_param -n $PROC_RESENDCOUNT $1
9288         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9289 }
9290
9291 # for reduce test_118* time (b=14842)
9292 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9293
9294 # Reset async IO behavior after error case
9295 reset_async() {
9296         FILE=$DIR/reset_async
9297
9298         # Ensure all OSCs are cleared
9299         $LFS setstripe -c -1 $FILE
9300         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9301         sync
9302         rm $FILE
9303 }
9304
9305 test_118a() #bug 11710
9306 {
9307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9308
9309         reset_async
9310
9311         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9314
9315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9317                 return 1;
9318         fi
9319         rm -f $DIR/$tfile
9320 }
9321 run_test 118a "verify O_SYNC works =========="
9322
9323 test_118b()
9324 {
9325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9326         remote_ost_nodsh && skip "remote OST with nodsh"
9327
9328         reset_async
9329
9330         #define OBD_FAIL_SRV_ENOENT 0x217
9331         set_nodes_failloc "$(osts_nodes)" 0x217
9332         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9333         RC=$?
9334         set_nodes_failloc "$(osts_nodes)" 0
9335         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9336         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9337                     grep -c writeback)
9338
9339         if [[ $RC -eq 0 ]]; then
9340                 error "Must return error due to dropped pages, rc=$RC"
9341                 return 1;
9342         fi
9343
9344         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9345                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9346                 return 1;
9347         fi
9348
9349         echo "Dirty pages not leaked on ENOENT"
9350
9351         # Due to the above error the OSC will issue all RPCs syncronously
9352         # until a subsequent RPC completes successfully without error.
9353         $MULTIOP $DIR/$tfile Ow4096yc
9354         rm -f $DIR/$tfile
9355
9356         return 0
9357 }
9358 run_test 118b "Reclaim dirty pages on fatal error =========="
9359
9360 test_118c()
9361 {
9362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9363
9364         # for 118c, restore the original resend count, LU-1940
9365         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9366                                 set_resend_count $OLD_RESENDCOUNT
9367         remote_ost_nodsh && skip "remote OST with nodsh"
9368
9369         reset_async
9370
9371         #define OBD_FAIL_OST_EROFS               0x216
9372         set_nodes_failloc "$(osts_nodes)" 0x216
9373
9374         # multiop should block due to fsync until pages are written
9375         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9376         MULTIPID=$!
9377         sleep 1
9378
9379         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9380                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9381         fi
9382
9383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9384                     grep -c writeback)
9385         if [[ $WRITEBACK -eq 0 ]]; then
9386                 error "No page in writeback, writeback=$WRITEBACK"
9387         fi
9388
9389         set_nodes_failloc "$(osts_nodes)" 0
9390         wait $MULTIPID
9391         RC=$?
9392         if [[ $RC -ne 0 ]]; then
9393                 error "Multiop fsync failed, rc=$RC"
9394         fi
9395
9396         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9398                     grep -c writeback)
9399         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9400                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9401         fi
9402
9403         rm -f $DIR/$tfile
9404         echo "Dirty pages flushed via fsync on EROFS"
9405         return 0
9406 }
9407 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9408
9409 # continue to use small resend count to reduce test_118* time (b=14842)
9410 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9411
9412 test_118d()
9413 {
9414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9415         remote_ost_nodsh && skip "remote OST with nodsh"
9416
9417         reset_async
9418
9419         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9420         set_nodes_failloc "$(osts_nodes)" 0x214
9421         # multiop should block due to fsync until pages are written
9422         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9423         MULTIPID=$!
9424         sleep 1
9425
9426         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9427                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9428         fi
9429
9430         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9431                     grep -c writeback)
9432         if [[ $WRITEBACK -eq 0 ]]; then
9433                 error "No page in writeback, writeback=$WRITEBACK"
9434         fi
9435
9436         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9437         set_nodes_failloc "$(osts_nodes)" 0
9438
9439         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9440         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9441                     grep -c writeback)
9442         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9443                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9444         fi
9445
9446         rm -f $DIR/$tfile
9447         echo "Dirty pages gaurenteed flushed via fsync"
9448         return 0
9449 }
9450 run_test 118d "Fsync validation inject a delay of the bulk =========="
9451
9452 test_118f() {
9453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9454
9455         reset_async
9456
9457         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9458         lctl set_param fail_loc=0x8000040a
9459
9460         # Should simulate EINVAL error which is fatal
9461         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9462         RC=$?
9463         if [[ $RC -eq 0 ]]; then
9464                 error "Must return error due to dropped pages, rc=$RC"
9465         fi
9466
9467         lctl set_param fail_loc=0x0
9468
9469         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9470         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9471         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9472                     grep -c writeback)
9473         if [[ $LOCKED -ne 0 ]]; then
9474                 error "Locked pages remain in cache, locked=$LOCKED"
9475         fi
9476
9477         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9478                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9479         fi
9480
9481         rm -f $DIR/$tfile
9482         echo "No pages locked after fsync"
9483
9484         reset_async
9485         return 0
9486 }
9487 run_test 118f "Simulate unrecoverable OSC side error =========="
9488
9489 test_118g() {
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491
9492         reset_async
9493
9494         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9495         lctl set_param fail_loc=0x406
9496
9497         # simulate local -ENOMEM
9498         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9499         RC=$?
9500
9501         lctl set_param fail_loc=0
9502         if [[ $RC -eq 0 ]]; then
9503                 error "Must return error due to dropped pages, rc=$RC"
9504         fi
9505
9506         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9509                         grep -c writeback)
9510         if [[ $LOCKED -ne 0 ]]; then
9511                 error "Locked pages remain in cache, locked=$LOCKED"
9512         fi
9513
9514         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9515                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9516         fi
9517
9518         rm -f $DIR/$tfile
9519         echo "No pages locked after fsync"
9520
9521         reset_async
9522         return 0
9523 }
9524 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9525
9526 test_118h() {
9527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9528         remote_ost_nodsh && skip "remote OST with nodsh"
9529
9530         reset_async
9531
9532         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9533         set_nodes_failloc "$(osts_nodes)" 0x20e
9534         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9535         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9536         RC=$?
9537
9538         set_nodes_failloc "$(osts_nodes)" 0
9539         if [[ $RC -eq 0 ]]; then
9540                 error "Must return error due to dropped pages, rc=$RC"
9541         fi
9542
9543         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9544         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9545         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9546                     grep -c writeback)
9547         if [[ $LOCKED -ne 0 ]]; then
9548                 error "Locked pages remain in cache, locked=$LOCKED"
9549         fi
9550
9551         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9552                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9553         fi
9554
9555         rm -f $DIR/$tfile
9556         echo "No pages locked after fsync"
9557
9558         return 0
9559 }
9560 run_test 118h "Verify timeout in handling recoverables errors  =========="
9561
9562 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9563
9564 test_118i() {
9565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9566         remote_ost_nodsh && skip "remote OST with nodsh"
9567
9568         reset_async
9569
9570         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9571         set_nodes_failloc "$(osts_nodes)" 0x20e
9572
9573         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9574         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9575         PID=$!
9576         sleep 5
9577         set_nodes_failloc "$(osts_nodes)" 0
9578
9579         wait $PID
9580         RC=$?
9581         if [[ $RC -ne 0 ]]; then
9582                 error "got error, but should be not, rc=$RC"
9583         fi
9584
9585         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9586         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9587         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9588         if [[ $LOCKED -ne 0 ]]; then
9589                 error "Locked pages remain in cache, locked=$LOCKED"
9590         fi
9591
9592         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9593                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9594         fi
9595
9596         rm -f $DIR/$tfile
9597         echo "No pages locked after fsync"
9598
9599         return 0
9600 }
9601 run_test 118i "Fix error before timeout in recoverable error  =========="
9602
9603 [ "$SLOW" = "no" ] && set_resend_count 4
9604
9605 test_118j() {
9606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9607         remote_ost_nodsh && skip "remote OST with nodsh"
9608
9609         reset_async
9610
9611         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9612         set_nodes_failloc "$(osts_nodes)" 0x220
9613
9614         # return -EIO from OST
9615         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9616         RC=$?
9617         set_nodes_failloc "$(osts_nodes)" 0x0
9618         if [[ $RC -eq 0 ]]; then
9619                 error "Must return error due to dropped pages, rc=$RC"
9620         fi
9621
9622         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9625         if [[ $LOCKED -ne 0 ]]; then
9626                 error "Locked pages remain in cache, locked=$LOCKED"
9627         fi
9628
9629         # in recoverable error on OST we want resend and stay until it finished
9630         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9631                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9632         fi
9633
9634         rm -f $DIR/$tfile
9635         echo "No pages locked after fsync"
9636
9637         return 0
9638 }
9639 run_test 118j "Simulate unrecoverable OST side error =========="
9640
9641 test_118k()
9642 {
9643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9644         remote_ost_nodsh && skip "remote OSTs with nodsh"
9645
9646         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9647         set_nodes_failloc "$(osts_nodes)" 0x20e
9648         test_mkdir $DIR/$tdir
9649
9650         for ((i=0;i<10;i++)); do
9651                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9652                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9653                 SLEEPPID=$!
9654                 sleep 0.500s
9655                 kill $SLEEPPID
9656                 wait $SLEEPPID
9657         done
9658
9659         set_nodes_failloc "$(osts_nodes)" 0
9660         rm -rf $DIR/$tdir
9661 }
9662 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9663
9664 test_118l() # LU-646
9665 {
9666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9667
9668         test_mkdir $DIR/$tdir
9669         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9670         rm -rf $DIR/$tdir
9671 }
9672 run_test 118l "fsync dir"
9673
9674 test_118m() # LU-3066
9675 {
9676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9677
9678         test_mkdir $DIR/$tdir
9679         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9680         rm -rf $DIR/$tdir
9681 }
9682 run_test 118m "fdatasync dir ========="
9683
9684 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9685
9686 test_118n()
9687 {
9688         local begin
9689         local end
9690
9691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9692         remote_ost_nodsh && skip "remote OSTs with nodsh"
9693
9694         # Sleep to avoid a cached response.
9695         #define OBD_STATFS_CACHE_SECONDS 1
9696         sleep 2
9697
9698         # Inject a 10 second delay in the OST_STATFS handler.
9699         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9700         set_nodes_failloc "$(osts_nodes)" 0x242
9701
9702         begin=$SECONDS
9703         stat --file-system $MOUNT > /dev/null
9704         end=$SECONDS
9705
9706         set_nodes_failloc "$(osts_nodes)" 0
9707
9708         if ((end - begin > 20)); then
9709             error "statfs took $((end - begin)) seconds, expected 10"
9710         fi
9711 }
9712 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9713
9714 test_119a() # bug 11737
9715 {
9716         BSIZE=$((512 * 1024))
9717         directio write $DIR/$tfile 0 1 $BSIZE
9718         # We ask to read two blocks, which is more than a file size.
9719         # directio will indicate an error when requested and actual
9720         # sizes aren't equeal (a normal situation in this case) and
9721         # print actual read amount.
9722         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9723         if [ "$NOB" != "$BSIZE" ]; then
9724                 error "read $NOB bytes instead of $BSIZE"
9725         fi
9726         rm -f $DIR/$tfile
9727 }
9728 run_test 119a "Short directIO read must return actual read amount"
9729
9730 test_119b() # bug 11737
9731 {
9732         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9733
9734         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9736         sync
9737         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9738                 error "direct read failed"
9739         rm -f $DIR/$tfile
9740 }
9741 run_test 119b "Sparse directIO read must return actual read amount"
9742
9743 test_119c() # bug 13099
9744 {
9745         BSIZE=1048576
9746         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9747         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9748         rm -f $DIR/$tfile
9749 }
9750 run_test 119c "Testing for direct read hitting hole"
9751
9752 test_119d() # bug 15950
9753 {
9754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9755
9756         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9757         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9758         BSIZE=1048576
9759         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9760         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9761         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9762         lctl set_param fail_loc=0x40d
9763         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9764         pid_dio=$!
9765         sleep 1
9766         cat $DIR/$tfile > /dev/null &
9767         lctl set_param fail_loc=0
9768         pid_reads=$!
9769         wait $pid_dio
9770         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9771         sleep 2
9772         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9773         error "the read rpcs have not completed in 2s"
9774         rm -f $DIR/$tfile
9775         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9776 }
9777 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9778
9779 test_120a() {
9780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9781         remote_mds_nodsh && skip "remote MDS with nodsh"
9782         test_mkdir -i0 -c1 $DIR/$tdir
9783         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9784                 skip_env "no early lock cancel on server"
9785
9786         lru_resize_disable mdc
9787         lru_resize_disable osc
9788         cancel_lru_locks mdc
9789         # asynchronous object destroy at MDT could cause bl ast to client
9790         cancel_lru_locks osc
9791
9792         stat $DIR/$tdir > /dev/null
9793         can1=$(do_facet mds1 \
9794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9795                awk '/ldlm_cancel/ {print $2}')
9796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9797                awk '/ldlm_bl_callback/ {print $2}')
9798         test_mkdir -i0 -c1 $DIR/$tdir/d1
9799         can2=$(do_facet mds1 \
9800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9801                awk '/ldlm_cancel/ {print $2}')
9802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9803                awk '/ldlm_bl_callback/ {print $2}')
9804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9806         lru_resize_enable mdc
9807         lru_resize_enable osc
9808 }
9809 run_test 120a "Early Lock Cancel: mkdir test"
9810
9811 test_120b() {
9812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9813         remote_mds_nodsh && skip "remote MDS with nodsh"
9814         test_mkdir $DIR/$tdir
9815         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9816                 skip_env "no early lock cancel on server"
9817
9818         lru_resize_disable mdc
9819         lru_resize_disable osc
9820         cancel_lru_locks mdc
9821         stat $DIR/$tdir > /dev/null
9822         can1=$(do_facet $SINGLEMDS \
9823                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9824                awk '/ldlm_cancel/ {print $2}')
9825         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9826                awk '/ldlm_bl_callback/ {print $2}')
9827         touch $DIR/$tdir/f1
9828         can2=$(do_facet $SINGLEMDS \
9829                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9830                awk '/ldlm_cancel/ {print $2}')
9831         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9832                awk '/ldlm_bl_callback/ {print $2}')
9833         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9834         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9835         lru_resize_enable mdc
9836         lru_resize_enable osc
9837 }
9838 run_test 120b "Early Lock Cancel: create test"
9839
9840 test_120c() {
9841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9842         remote_mds_nodsh && skip "remote MDS with nodsh"
9843         test_mkdir -i0 -c1 $DIR/$tdir
9844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9845                 skip "no early lock cancel on server"
9846
9847         lru_resize_disable mdc
9848         lru_resize_disable osc
9849         test_mkdir -i0 -c1 $DIR/$tdir/d1
9850         test_mkdir -i0 -c1 $DIR/$tdir/d2
9851         touch $DIR/$tdir/d1/f1
9852         cancel_lru_locks mdc
9853         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9854         can1=$(do_facet mds1 \
9855                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9856                awk '/ldlm_cancel/ {print $2}')
9857         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9858                awk '/ldlm_bl_callback/ {print $2}')
9859         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9860         can2=$(do_facet mds1 \
9861                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9862                awk '/ldlm_cancel/ {print $2}')
9863         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9864                awk '/ldlm_bl_callback/ {print $2}')
9865         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9866         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9867         lru_resize_enable mdc
9868         lru_resize_enable osc
9869 }
9870 run_test 120c "Early Lock Cancel: link test"
9871
9872 test_120d() {
9873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9874         remote_mds_nodsh && skip "remote MDS with nodsh"
9875         test_mkdir -i0 -c1 $DIR/$tdir
9876         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9877                 skip_env "no early lock cancel on server"
9878
9879         lru_resize_disable mdc
9880         lru_resize_disable osc
9881         touch $DIR/$tdir
9882         cancel_lru_locks mdc
9883         stat $DIR/$tdir > /dev/null
9884         can1=$(do_facet mds1 \
9885                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9886                awk '/ldlm_cancel/ {print $2}')
9887         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9888                awk '/ldlm_bl_callback/ {print $2}')
9889         chmod a+x $DIR/$tdir
9890         can2=$(do_facet mds1 \
9891                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9892                awk '/ldlm_cancel/ {print $2}')
9893         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9894                awk '/ldlm_bl_callback/ {print $2}')
9895         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9896         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9897         lru_resize_enable mdc
9898         lru_resize_enable osc
9899 }
9900 run_test 120d "Early Lock Cancel: setattr test"
9901
9902 test_120e() {
9903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9904         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9905                 skip_env "no early lock cancel on server"
9906         remote_mds_nodsh && skip "remote MDS with nodsh"
9907
9908         local dlmtrace_set=false
9909
9910         test_mkdir -i0 -c1 $DIR/$tdir
9911         lru_resize_disable mdc
9912         lru_resize_disable osc
9913         ! $LCTL get_param debug | grep -q dlmtrace &&
9914                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9915         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9916         cancel_lru_locks mdc
9917         cancel_lru_locks osc
9918         dd if=$DIR/$tdir/f1 of=/dev/null
9919         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9920         # XXX client can not do early lock cancel of OST lock
9921         # during unlink (LU-4206), so cancel osc lock now.
9922         sleep 2
9923         cancel_lru_locks osc
9924         can1=$(do_facet mds1 \
9925                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9926                awk '/ldlm_cancel/ {print $2}')
9927         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9928                awk '/ldlm_bl_callback/ {print $2}')
9929         unlink $DIR/$tdir/f1
9930         sleep 5
9931         can2=$(do_facet mds1 \
9932                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9933                awk '/ldlm_cancel/ {print $2}')
9934         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9935                awk '/ldlm_bl_callback/ {print $2}')
9936         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9937                 $LCTL dk $TMP/cancel.debug.txt
9938         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9939                 $LCTL dk $TMP/blocking.debug.txt
9940         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9941         lru_resize_enable mdc
9942         lru_resize_enable osc
9943 }
9944 run_test 120e "Early Lock Cancel: unlink test"
9945
9946 test_120f() {
9947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9948         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9949                 skip_env "no early lock cancel on server"
9950         remote_mds_nodsh && skip "remote MDS with nodsh"
9951
9952         test_mkdir -i0 -c1 $DIR/$tdir
9953         lru_resize_disable mdc
9954         lru_resize_disable osc
9955         test_mkdir -i0 -c1 $DIR/$tdir/d1
9956         test_mkdir -i0 -c1 $DIR/$tdir/d2
9957         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9958         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9959         cancel_lru_locks mdc
9960         cancel_lru_locks osc
9961         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9962         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9963         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9964         # XXX client can not do early lock cancel of OST lock
9965         # during rename (LU-4206), so cancel osc lock now.
9966         sleep 2
9967         cancel_lru_locks osc
9968         can1=$(do_facet mds1 \
9969                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9970                awk '/ldlm_cancel/ {print $2}')
9971         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9972                awk '/ldlm_bl_callback/ {print $2}')
9973         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9974         sleep 5
9975         can2=$(do_facet mds1 \
9976                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9977                awk '/ldlm_cancel/ {print $2}')
9978         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9979                awk '/ldlm_bl_callback/ {print $2}')
9980         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9981         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9982         lru_resize_enable mdc
9983         lru_resize_enable osc
9984 }
9985 run_test 120f "Early Lock Cancel: rename test"
9986
9987 test_120g() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9990                 skip_env "no early lock cancel on server"
9991         remote_mds_nodsh && skip "remote MDS with nodsh"
9992
9993         lru_resize_disable mdc
9994         lru_resize_disable osc
9995         count=10000
9996         echo create $count files
9997         test_mkdir $DIR/$tdir
9998         cancel_lru_locks mdc
9999         cancel_lru_locks osc
10000         t0=$(date +%s)
10001
10002         can0=$(do_facet $SINGLEMDS \
10003                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10004                awk '/ldlm_cancel/ {print $2}')
10005         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10006                awk '/ldlm_bl_callback/ {print $2}')
10007         createmany -o $DIR/$tdir/f $count
10008         sync
10009         can1=$(do_facet $SINGLEMDS \
10010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10011                awk '/ldlm_cancel/ {print $2}')
10012         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10013                awk '/ldlm_bl_callback/ {print $2}')
10014         t1=$(date +%s)
10015         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10016         echo rm $count files
10017         rm -r $DIR/$tdir
10018         sync
10019         can2=$(do_facet $SINGLEMDS \
10020                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10021                awk '/ldlm_cancel/ {print $2}')
10022         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10023                awk '/ldlm_bl_callback/ {print $2}')
10024         t2=$(date +%s)
10025         echo total: $count removes in $((t2-t1))
10026         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10027         sleep 2
10028         # wait for commitment of removal
10029         lru_resize_enable mdc
10030         lru_resize_enable osc
10031 }
10032 run_test 120g "Early Lock Cancel: performance test"
10033
10034 test_121() { #bug #10589
10035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10036
10037         rm -rf $DIR/$tfile
10038         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10039 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10040         lctl set_param fail_loc=0x310
10041         cancel_lru_locks osc > /dev/null
10042         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10043         lctl set_param fail_loc=0
10044         [[ $reads -eq $writes ]] ||
10045                 error "read $reads blocks, must be $writes blocks"
10046 }
10047 run_test 121 "read cancel race ========="
10048
10049 test_123a() { # was test 123, statahead(bug 11401)
10050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10051
10052         SLOWOK=0
10053         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10054                 log "testing UP system. Performance may be lower than expected."
10055                 SLOWOK=1
10056         fi
10057
10058         rm -rf $DIR/$tdir
10059         test_mkdir $DIR/$tdir
10060         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10061         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10062         MULT=10
10063         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10064                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10065
10066                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10067                 lctl set_param -n llite.*.statahead_max 0
10068                 lctl get_param llite.*.statahead_max
10069                 cancel_lru_locks mdc
10070                 cancel_lru_locks osc
10071                 stime=`date +%s`
10072                 time ls -l $DIR/$tdir | wc -l
10073                 etime=`date +%s`
10074                 delta=$((etime - stime))
10075                 log "ls $i files without statahead: $delta sec"
10076                 lctl set_param llite.*.statahead_max=$max
10077
10078                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10079                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10080                 cancel_lru_locks mdc
10081                 cancel_lru_locks osc
10082                 stime=`date +%s`
10083                 time ls -l $DIR/$tdir | wc -l
10084                 etime=`date +%s`
10085                 delta_sa=$((etime - stime))
10086                 log "ls $i files with statahead: $delta_sa sec"
10087                 lctl get_param -n llite.*.statahead_stats
10088                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10089
10090                 [[ $swrong -lt $ewrong ]] &&
10091                         log "statahead was stopped, maybe too many locks held!"
10092                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10093
10094                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10095                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10096                     lctl set_param -n llite.*.statahead_max 0
10097                     lctl get_param llite.*.statahead_max
10098                     cancel_lru_locks mdc
10099                     cancel_lru_locks osc
10100                     stime=`date +%s`
10101                     time ls -l $DIR/$tdir | wc -l
10102                     etime=`date +%s`
10103                     delta=$((etime - stime))
10104                     log "ls $i files again without statahead: $delta sec"
10105                     lctl set_param llite.*.statahead_max=$max
10106                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10107                         if [  $SLOWOK -eq 0 ]; then
10108                                 error "ls $i files is slower with statahead!"
10109                         else
10110                                 log "ls $i files is slower with statahead!"
10111                         fi
10112                         break
10113                     fi
10114                 fi
10115
10116                 [ $delta -gt 20 ] && break
10117                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10118                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10119         done
10120         log "ls done"
10121
10122         stime=`date +%s`
10123         rm -r $DIR/$tdir
10124         sync
10125         etime=`date +%s`
10126         delta=$((etime - stime))
10127         log "rm -r $DIR/$tdir/: $delta seconds"
10128         log "rm done"
10129         lctl get_param -n llite.*.statahead_stats
10130 }
10131 run_test 123a "verify statahead work"
10132
10133 test_123b () { # statahead(bug 15027)
10134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10135
10136         test_mkdir $DIR/$tdir
10137         createmany -o $DIR/$tdir/$tfile-%d 1000
10138
10139         cancel_lru_locks mdc
10140         cancel_lru_locks osc
10141
10142 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10143         lctl set_param fail_loc=0x80000803
10144         ls -lR $DIR/$tdir > /dev/null
10145         log "ls done"
10146         lctl set_param fail_loc=0x0
10147         lctl get_param -n llite.*.statahead_stats
10148         rm -r $DIR/$tdir
10149         sync
10150
10151 }
10152 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10153
10154 test_124a() {
10155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10156         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10157                 skip_env "no lru resize on server"
10158
10159         local NR=2000
10160
10161         test_mkdir $DIR/$tdir
10162
10163         log "create $NR files at $DIR/$tdir"
10164         createmany -o $DIR/$tdir/f $NR ||
10165                 error "failed to create $NR files in $DIR/$tdir"
10166
10167         cancel_lru_locks mdc
10168         ls -l $DIR/$tdir > /dev/null
10169
10170         local NSDIR=""
10171         local LRU_SIZE=0
10172         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10173                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10174                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10175                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10176                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10177                         log "NSDIR=$NSDIR"
10178                         log "NS=$(basename $NSDIR)"
10179                         break
10180                 fi
10181         done
10182
10183         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10184                 skip "Not enough cached locks created!"
10185         fi
10186         log "LRU=$LRU_SIZE"
10187
10188         local SLEEP=30
10189
10190         # We know that lru resize allows one client to hold $LIMIT locks
10191         # for 10h. After that locks begin to be killed by client.
10192         local MAX_HRS=10
10193         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10194         log "LIMIT=$LIMIT"
10195         if [ $LIMIT -lt $LRU_SIZE ]; then
10196                 skip "Limit is too small $LIMIT"
10197         fi
10198
10199         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10200         # killing locks. Some time was spent for creating locks. This means
10201         # that up to the moment of sleep finish we must have killed some of
10202         # them (10-100 locks). This depends on how fast ther were created.
10203         # Many of them were touched in almost the same moment and thus will
10204         # be killed in groups.
10205         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10206
10207         # Use $LRU_SIZE_B here to take into account real number of locks
10208         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10209         local LRU_SIZE_B=$LRU_SIZE
10210         log "LVF=$LVF"
10211         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10212         log "OLD_LVF=$OLD_LVF"
10213         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10214
10215         # Let's make sure that we really have some margin. Client checks
10216         # cached locks every 10 sec.
10217         SLEEP=$((SLEEP+20))
10218         log "Sleep ${SLEEP} sec"
10219         local SEC=0
10220         while ((SEC<$SLEEP)); do
10221                 echo -n "..."
10222                 sleep 5
10223                 SEC=$((SEC+5))
10224                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10225                 echo -n "$LRU_SIZE"
10226         done
10227         echo ""
10228         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10229         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10230
10231         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10232                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10233                 unlinkmany $DIR/$tdir/f $NR
10234                 return
10235         }
10236
10237         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10238         log "unlink $NR files at $DIR/$tdir"
10239         unlinkmany $DIR/$tdir/f $NR
10240 }
10241 run_test 124a "lru resize ======================================="
10242
10243 get_max_pool_limit()
10244 {
10245         local limit=$($LCTL get_param \
10246                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10247         local max=0
10248         for l in $limit; do
10249                 if [[ $l -gt $max ]]; then
10250                         max=$l
10251                 fi
10252         done
10253         echo $max
10254 }
10255
10256 test_124b() {
10257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10258         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10259                 skip_env "no lru resize on server"
10260
10261         LIMIT=$(get_max_pool_limit)
10262
10263         NR=$(($(default_lru_size)*20))
10264         if [[ $NR -gt $LIMIT ]]; then
10265                 log "Limit lock number by $LIMIT locks"
10266                 NR=$LIMIT
10267         fi
10268
10269         IFree=$(mdsrate_inodes_available)
10270         if [ $IFree -lt $NR ]; then
10271                 log "Limit lock number by $IFree inodes"
10272                 NR=$IFree
10273         fi
10274
10275         lru_resize_disable mdc
10276         test_mkdir -p $DIR/$tdir/disable_lru_resize
10277
10278         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10279         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10280         cancel_lru_locks mdc
10281         stime=`date +%s`
10282         PID=""
10283         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10284         PID="$PID $!"
10285         sleep 2
10286         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10287         PID="$PID $!"
10288         sleep 2
10289         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10290         PID="$PID $!"
10291         wait $PID
10292         etime=`date +%s`
10293         nolruresize_delta=$((etime-stime))
10294         log "ls -la time: $nolruresize_delta seconds"
10295         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10296         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10297
10298         lru_resize_enable mdc
10299         test_mkdir -p $DIR/$tdir/enable_lru_resize
10300
10301         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10302         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10303         cancel_lru_locks mdc
10304         stime=`date +%s`
10305         PID=""
10306         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10307         PID="$PID $!"
10308         sleep 2
10309         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10310         PID="$PID $!"
10311         sleep 2
10312         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10313         PID="$PID $!"
10314         wait $PID
10315         etime=`date +%s`
10316         lruresize_delta=$((etime-stime))
10317         log "ls -la time: $lruresize_delta seconds"
10318         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10319
10320         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10321                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10322         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10323                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10324         else
10325                 log "lru resize performs the same with no lru resize"
10326         fi
10327         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10328 }
10329 run_test 124b "lru resize (performance test) ======================="
10330
10331 test_124c() {
10332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10333         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10334                 skip_env "no lru resize on server"
10335
10336         # cache ununsed locks on client
10337         local nr=100
10338         cancel_lru_locks mdc
10339         test_mkdir $DIR/$tdir
10340         createmany -o $DIR/$tdir/f $nr ||
10341                 error "failed to create $nr files in $DIR/$tdir"
10342         ls -l $DIR/$tdir > /dev/null
10343
10344         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10345         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10346         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10347         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10348         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10349
10350         # set lru_max_age to 1 sec
10351         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10352         echo "sleep $((recalc_p * 2)) seconds..."
10353         sleep $((recalc_p * 2))
10354
10355         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10356         # restore lru_max_age
10357         $LCTL set_param -n $nsdir.lru_max_age $max_age
10358         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10359         unlinkmany $DIR/$tdir/f $nr
10360 }
10361 run_test 124c "LRUR cancel very aged locks"
10362
10363 test_125() { # 13358
10364         $LCTL get_param -n llite.*.client_type | grep -q local ||
10365                 skip "must run as local client"
10366         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10367                 skip_env "must have acl enabled"
10368         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10369
10370         test_mkdir $DIR/$tdir
10371         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10372         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10373         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10374 }
10375 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10376
10377 test_126() { # bug 12829/13455
10378         $GSS && skip_env "must run as gss disabled"
10379         $LCTL get_param -n llite.*.client_type | grep -q local ||
10380                 skip "must run as local client"
10381         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10382
10383         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10384         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10385         rm -f $DIR/$tfile
10386         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10387 }
10388 run_test 126 "check that the fsgid provided by the client is taken into account"
10389
10390 test_127a() { # bug 15521
10391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10392
10393         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10394         $LCTL set_param osc.*.stats=0
10395         FSIZE=$((2048 * 1024))
10396         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10397         cancel_lru_locks osc
10398         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10399
10400         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10401         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10402                 echo "got $COUNT $NAME"
10403                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10404                 eval $NAME=$COUNT || error "Wrong proc format"
10405
10406                 case $NAME in
10407                         read_bytes|write_bytes)
10408                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10409                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10410                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10411                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10412                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10413                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10414                                 error "sumsquare is too small: $SUMSQ"
10415                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10416                                 error "sumsquare is too big: $SUMSQ"
10417                         ;;
10418                         *) ;;
10419                 esac
10420         done < $DIR/${tfile}.tmp
10421
10422         #check that we actually got some stats
10423         [ "$read_bytes" ] || error "Missing read_bytes stats"
10424         [ "$write_bytes" ] || error "Missing write_bytes stats"
10425         [ "$read_bytes" != 0 ] || error "no read done"
10426         [ "$write_bytes" != 0 ] || error "no write done"
10427 }
10428 run_test 127a "verify the client stats are sane"
10429
10430 test_127b() { # bug LU-333
10431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10432         local name count samp unit min max sum sumsq
10433
10434         $LCTL set_param llite.*.stats=0
10435
10436         # perform 2 reads and writes so MAX is different from SUM.
10437         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10438         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10439         cancel_lru_locks osc
10440         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10441         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10442
10443         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10444         while read name count samp unit min max sum sumsq; do
10445                 echo "got $count $name"
10446                 eval $name=$count || error "Wrong proc format"
10447
10448                 case $name in
10449                 read_bytes)
10450                         [ $count -ne 2 ] && error "count is not 2: $count"
10451                         [ $min -ne $PAGE_SIZE ] &&
10452                                 error "min is not $PAGE_SIZE: $min"
10453                         [ $max -ne $PAGE_SIZE ] &&
10454                                 error "max is incorrect: $max"
10455                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10456                                 error "sum is wrong: $sum"
10457                         ;;
10458                 write_bytes)
10459                         [ $count -ne 2 ] && error "count is not 2: $count"
10460                         [ $min -ne $PAGE_SIZE ] &&
10461                                 error "min is not $PAGE_SIZE: $min"
10462                         [ $max -ne $PAGE_SIZE ] &&
10463                                 error "max is incorrect: $max"
10464                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10465                                 error "sum is wrong: $sum"
10466                         ;;
10467                 *) ;;
10468                 esac
10469         done < $TMP/$tfile.tmp
10470
10471         #check that we actually got some stats
10472         [ "$read_bytes" ] || error "Missing read_bytes stats"
10473         [ "$write_bytes" ] || error "Missing write_bytes stats"
10474         [ "$read_bytes" != 0 ] || error "no read done"
10475         [ "$write_bytes" != 0 ] || error "no write done"
10476
10477         rm -f $TMP/${tfile}.tmp
10478 }
10479 run_test 127b "verify the llite client stats are sane"
10480
10481 test_128() { # bug 15212
10482         touch $DIR/$tfile
10483         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10484                 find $DIR/$tfile
10485                 find $DIR/$tfile
10486         EOF
10487
10488         result=$(grep error $TMP/$tfile.log)
10489         rm -f $DIR/$tfile $TMP/$tfile.log
10490         [ -z "$result" ] ||
10491                 error "consecutive find's under interactive lfs failed"
10492 }
10493 run_test 128 "interactive lfs for 2 consecutive find's"
10494
10495 set_dir_limits () {
10496         local mntdev
10497         local canondev
10498         local node
10499
10500         local ldproc=/proc/fs/ldiskfs
10501         local facets=$(get_facets MDS)
10502
10503         for facet in ${facets//,/ }; do
10504                 canondev=$(ldiskfs_canon \
10505                            *.$(convert_facet2label $facet).mntdev $facet)
10506                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10507                         ldproc=/sys/fs/ldiskfs
10508                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10509                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10510         done
10511 }
10512
10513 check_mds_dmesg() {
10514         local facets=$(get_facets MDS)
10515         for facet in ${facets//,/ }; do
10516                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10517         done
10518         return 1
10519 }
10520
10521 test_129() {
10522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10523         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10524                 skip "Need MDS version with at least 2.5.56"
10525         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10526                 skip_env "ldiskfs only test"
10527         fi
10528         remote_mds_nodsh && skip "remote MDS with nodsh"
10529
10530         local ENOSPC=28
10531         local EFBIG=27
10532         local has_warning=false
10533
10534         rm -rf $DIR/$tdir
10535         mkdir -p $DIR/$tdir
10536
10537         # block size of mds1
10538         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10539         set_dir_limits $maxsize $maxsize
10540         local dirsize=$(stat -c%s "$DIR/$tdir")
10541         local nfiles=0
10542         while [[ $dirsize -le $maxsize ]]; do
10543                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10544                 rc=$?
10545                 if ! $has_warning; then
10546                         check_mds_dmesg '"is approaching"' && has_warning=true
10547                 fi
10548                 # check two errors:
10549                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10550                 # EFBIG for previous versions included in ldiskfs series
10551                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
10552                         set_dir_limits 0 0
10553                         echo "return code $rc received as expected"
10554
10555                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10556                                 error_exit "create failed w/o dir size limit"
10557
10558                         check_mds_dmesg '"has reached"' ||
10559                                 error_exit "reached message should be output"
10560
10561                         [ $has_warning = "false" ] &&
10562                                 error_exit "warning message should be output"
10563
10564                         dirsize=$(stat -c%s "$DIR/$tdir")
10565
10566                         [[ $dirsize -ge $maxsize ]] && return 0
10567                         error_exit "current dir size $dirsize, " \
10568                                    "previous limit $maxsize"
10569                 elif [ $rc -ne 0 ]; then
10570                         set_dir_limits 0 0
10571                         error_exit "return $rc received instead of expected " \
10572                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10573                 fi
10574                 nfiles=$((nfiles + 1))
10575                 dirsize=$(stat -c%s "$DIR/$tdir")
10576         done
10577
10578         set_dir_limits 0 0
10579         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10580 }
10581 run_test 129 "test directory size limit ========================"
10582
10583 OLDIFS="$IFS"
10584 cleanup_130() {
10585         trap 0
10586         IFS="$OLDIFS"
10587 }
10588
10589 test_130a() {
10590         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10591         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10592
10593         trap cleanup_130 EXIT RETURN
10594
10595         local fm_file=$DIR/$tfile
10596         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10597         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10598                 error "dd failed for $fm_file"
10599
10600         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10601         filefrag -ves $fm_file
10602         RC=$?
10603         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10604                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10605         [ $RC != 0 ] && error "filefrag $fm_file failed"
10606
10607         filefrag_op=$(filefrag -ve -k $fm_file |
10608                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10609         lun=$($LFS getstripe -i $fm_file)
10610
10611         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10612         IFS=$'\n'
10613         tot_len=0
10614         for line in $filefrag_op
10615         do
10616                 frag_lun=`echo $line | cut -d: -f5`
10617                 ext_len=`echo $line | cut -d: -f4`
10618                 if (( $frag_lun != $lun )); then
10619                         cleanup_130
10620                         error "FIEMAP on 1-stripe file($fm_file) failed"
10621                         return
10622                 fi
10623                 (( tot_len += ext_len ))
10624         done
10625
10626         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10627                 cleanup_130
10628                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10629                 return
10630         fi
10631
10632         cleanup_130
10633
10634         echo "FIEMAP on single striped file succeeded"
10635 }
10636 run_test 130a "FIEMAP (1-stripe file)"
10637
10638 test_130b() {
10639         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10640
10641         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10642         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10643
10644         trap cleanup_130 EXIT RETURN
10645
10646         local fm_file=$DIR/$tfile
10647         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10648                         error "setstripe on $fm_file"
10649         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10650                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10651
10652         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10653                 error "dd failed on $fm_file"
10654
10655         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10656         filefrag_op=$(filefrag -ve -k $fm_file |
10657                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10658
10659         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10660                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10661
10662         IFS=$'\n'
10663         tot_len=0
10664         num_luns=1
10665         for line in $filefrag_op
10666         do
10667                 frag_lun=$(echo $line | cut -d: -f5 |
10668                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10669                 ext_len=$(echo $line | cut -d: -f4)
10670                 if (( $frag_lun != $last_lun )); then
10671                         if (( tot_len != 1024 )); then
10672                                 cleanup_130
10673                                 error "FIEMAP on $fm_file failed; returned " \
10674                                 "len $tot_len for OST $last_lun instead of 1024"
10675                                 return
10676                         else
10677                                 (( num_luns += 1 ))
10678                                 tot_len=0
10679                         fi
10680                 fi
10681                 (( tot_len += ext_len ))
10682                 last_lun=$frag_lun
10683         done
10684         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10685                 cleanup_130
10686                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10687                         "luns or wrong len for OST $last_lun"
10688                 return
10689         fi
10690
10691         cleanup_130
10692
10693         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10694 }
10695 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10696
10697 test_130c() {
10698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10699
10700         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10701         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10702
10703         trap cleanup_130 EXIT RETURN
10704
10705         local fm_file=$DIR/$tfile
10706         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10707         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10708                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10709
10710         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10711                         error "dd failed on $fm_file"
10712
10713         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10714         filefrag_op=$(filefrag -ve -k $fm_file |
10715                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10716
10717         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10718                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10719
10720         IFS=$'\n'
10721         tot_len=0
10722         num_luns=1
10723         for line in $filefrag_op
10724         do
10725                 frag_lun=$(echo $line | cut -d: -f5 |
10726                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10727                 ext_len=$(echo $line | cut -d: -f4)
10728                 if (( $frag_lun != $last_lun )); then
10729                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10730                         if (( logical != 512 )); then
10731                                 cleanup_130
10732                                 error "FIEMAP on $fm_file failed; returned " \
10733                                 "logical start for lun $logical instead of 512"
10734                                 return
10735                         fi
10736                         if (( tot_len != 512 )); then
10737                                 cleanup_130
10738                                 error "FIEMAP on $fm_file failed; returned " \
10739                                 "len $tot_len for OST $last_lun instead of 1024"
10740                                 return
10741                         else
10742                                 (( num_luns += 1 ))
10743                                 tot_len=0
10744                         fi
10745                 fi
10746                 (( tot_len += ext_len ))
10747                 last_lun=$frag_lun
10748         done
10749         if (( num_luns != 2 || tot_len != 512 )); then
10750                 cleanup_130
10751                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10752                         "luns or wrong len for OST $last_lun"
10753                 return
10754         fi
10755
10756         cleanup_130
10757
10758         echo "FIEMAP on 2-stripe file with hole succeeded"
10759 }
10760 run_test 130c "FIEMAP (2-stripe file with hole)"
10761
10762 test_130d() {
10763         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10764
10765         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10766         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10767
10768         trap cleanup_130 EXIT RETURN
10769
10770         local fm_file=$DIR/$tfile
10771         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10772                         error "setstripe on $fm_file"
10773         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10774                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10775
10776         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10777         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10778                 error "dd failed on $fm_file"
10779
10780         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10781         filefrag_op=$(filefrag -ve -k $fm_file |
10782                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10783
10784         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10785                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10786
10787         IFS=$'\n'
10788         tot_len=0
10789         num_luns=1
10790         for line in $filefrag_op
10791         do
10792                 frag_lun=$(echo $line | cut -d: -f5 |
10793                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10794                 ext_len=$(echo $line | cut -d: -f4)
10795                 if (( $frag_lun != $last_lun )); then
10796                         if (( tot_len != 1024 )); then
10797                                 cleanup_130
10798                                 error "FIEMAP on $fm_file failed; returned " \
10799                                 "len $tot_len for OST $last_lun instead of 1024"
10800                                 return
10801                         else
10802                                 (( num_luns += 1 ))
10803                                 tot_len=0
10804                         fi
10805                 fi
10806                 (( tot_len += ext_len ))
10807                 last_lun=$frag_lun
10808         done
10809         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10810                 cleanup_130
10811                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10812                         "luns or wrong len for OST $last_lun"
10813                 return
10814         fi
10815
10816         cleanup_130
10817
10818         echo "FIEMAP on N-stripe file succeeded"
10819 }
10820 run_test 130d "FIEMAP (N-stripe file)"
10821
10822 test_130e() {
10823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10824
10825         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10826         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10827
10828         trap cleanup_130 EXIT RETURN
10829
10830         local fm_file=$DIR/$tfile
10831         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10832         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10833                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10834
10835         NUM_BLKS=512
10836         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10837         for ((i = 0; i < $NUM_BLKS; i++))
10838         do
10839                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10840         done
10841
10842         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10843         filefrag_op=$(filefrag -ve -k $fm_file |
10844                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10845
10846         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10847                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10848
10849         IFS=$'\n'
10850         tot_len=0
10851         num_luns=1
10852         for line in $filefrag_op
10853         do
10854                 frag_lun=$(echo $line | cut -d: -f5 |
10855                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10856                 ext_len=$(echo $line | cut -d: -f4)
10857                 if (( $frag_lun != $last_lun )); then
10858                         if (( tot_len != $EXPECTED_LEN )); then
10859                                 cleanup_130
10860                                 error "FIEMAP on $fm_file failed; returned " \
10861                                 "len $tot_len for OST $last_lun instead " \
10862                                 "of $EXPECTED_LEN"
10863                                 return
10864                         else
10865                                 (( num_luns += 1 ))
10866                                 tot_len=0
10867                         fi
10868                 fi
10869                 (( tot_len += ext_len ))
10870                 last_lun=$frag_lun
10871         done
10872         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10873                 cleanup_130
10874                 error "FIEMAP on $fm_file failed; returned wrong number " \
10875                         "of luns or wrong len for OST $last_lun"
10876                 return
10877         fi
10878
10879         cleanup_130
10880
10881         echo "FIEMAP with continuation calls succeeded"
10882 }
10883 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10884
10885 test_130f() {
10886         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10887         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10888
10889         local fm_file=$DIR/$tfile
10890         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10891                 error "multiop create with lov_delay_create on $fm_file"
10892
10893         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10894         filefrag_extents=$(filefrag -vek $fm_file |
10895                            awk '/extents? found/ { print $2 }')
10896         if [[ "$filefrag_extents" != "0" ]]; then
10897                 error "FIEMAP on $fm_file failed; " \
10898                       "returned $filefrag_extents expected 0"
10899         fi
10900
10901         rm -f $fm_file
10902 }
10903 run_test 130f "FIEMAP (unstriped file)"
10904
10905 # Test for writev/readv
10906 test_131a() {
10907         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10908                 error "writev test failed"
10909         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10910                 error "readv failed"
10911         rm -f $DIR/$tfile
10912 }
10913 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10914
10915 test_131b() {
10916         local fsize=$((524288 + 1048576 + 1572864))
10917         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10918                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10919                         error "append writev test failed"
10920
10921         ((fsize += 1572864 + 1048576))
10922         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10923                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10924                         error "append writev test failed"
10925         rm -f $DIR/$tfile
10926 }
10927 run_test 131b "test append writev"
10928
10929 test_131c() {
10930         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10931         error "NOT PASS"
10932 }
10933 run_test 131c "test read/write on file w/o objects"
10934
10935 test_131d() {
10936         rwv -f $DIR/$tfile -w -n 1 1572864
10937         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10938         if [ "$NOB" != 1572864 ]; then
10939                 error "Short read filed: read $NOB bytes instead of 1572864"
10940         fi
10941         rm -f $DIR/$tfile
10942 }
10943 run_test 131d "test short read"
10944
10945 test_131e() {
10946         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10947         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10948         error "read hitting hole failed"
10949         rm -f $DIR/$tfile
10950 }
10951 run_test 131e "test read hitting hole"
10952
10953 check_stats() {
10954         local facet=$1
10955         local op=$2
10956         local want=${3:-0}
10957         local res
10958
10959         case $facet in
10960         mds*) res=$(do_facet $facet \
10961                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10962                  ;;
10963         ost*) res=$(do_facet $facet \
10964                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10965                  ;;
10966         *) error "Wrong facet '$facet'" ;;
10967         esac
10968         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10969         # if the argument $3 is zero, it means any stat increment is ok.
10970         if [[ $want -gt 0 ]]; then
10971                 local count=$(echo $res | awk '{ print $2 }')
10972                 [[ $count -ne $want ]] &&
10973                         error "The $op counter on $facet is $count, not $want"
10974         fi
10975 }
10976
10977 test_133a() {
10978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10979         remote_ost_nodsh && skip "remote OST with nodsh"
10980         remote_mds_nodsh && skip "remote MDS with nodsh"
10981         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10982                 skip_env "MDS doesn't support rename stats"
10983
10984         local testdir=$DIR/${tdir}/stats_testdir
10985
10986         mkdir -p $DIR/${tdir}
10987
10988         # clear stats.
10989         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10990         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10991
10992         # verify mdt stats first.
10993         mkdir ${testdir} || error "mkdir failed"
10994         check_stats $SINGLEMDS "mkdir" 1
10995         touch ${testdir}/${tfile} || error "touch failed"
10996         check_stats $SINGLEMDS "open" 1
10997         check_stats $SINGLEMDS "close" 1
10998         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10999                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11000                 check_stats $SINGLEMDS "mknod" 2
11001         }
11002         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11003         check_stats $SINGLEMDS "unlink" 1
11004         rm -f ${testdir}/${tfile} || error "file remove failed"
11005         check_stats $SINGLEMDS "unlink" 2
11006
11007         # remove working dir and check mdt stats again.
11008         rmdir ${testdir} || error "rmdir failed"
11009         check_stats $SINGLEMDS "rmdir" 1
11010
11011         local testdir1=$DIR/${tdir}/stats_testdir1
11012         mkdir -p ${testdir}
11013         mkdir -p ${testdir1}
11014         touch ${testdir1}/test1
11015         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11016         check_stats $SINGLEMDS "crossdir_rename" 1
11017
11018         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11019         check_stats $SINGLEMDS "samedir_rename" 1
11020
11021         rm -rf $DIR/${tdir}
11022 }
11023 run_test 133a "Verifying MDT stats ========================================"
11024
11025 test_133b() {
11026         local res
11027
11028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11029         remote_ost_nodsh && skip "remote OST with nodsh"
11030         remote_mds_nodsh && skip "remote MDS with nodsh"
11031
11032         local testdir=$DIR/${tdir}/stats_testdir
11033
11034         mkdir -p ${testdir} || error "mkdir failed"
11035         touch ${testdir}/${tfile} || error "touch failed"
11036         cancel_lru_locks mdc
11037
11038         # clear stats.
11039         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11040         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11041
11042         # extra mdt stats verification.
11043         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11044         check_stats $SINGLEMDS "setattr" 1
11045         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11046         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11047         then            # LU-1740
11048                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11049                 check_stats $SINGLEMDS "getattr" 1
11050         fi
11051         rm -rf $DIR/${tdir}
11052
11053         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11054         # so the check below is not reliable
11055         [ $MDSCOUNT -eq 1 ] || return 0
11056
11057         # Sleep to avoid a cached response.
11058         #define OBD_STATFS_CACHE_SECONDS 1
11059         sleep 2
11060         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11061         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11062         $LFS df || error "lfs failed"
11063         check_stats $SINGLEMDS "statfs" 1
11064
11065         # check aggregated statfs (LU-10018)
11066         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11067                 return 0
11068         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11069                 return 0
11070         sleep 2
11071         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11072         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11073         df $DIR
11074         check_stats $SINGLEMDS "statfs" 1
11075
11076         # We want to check that the client didn't send OST_STATFS to
11077         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11078         # extra care is needed here.
11079         if remote_mds; then
11080                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11081                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11082
11083                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11084                 [ "$res" ] && error "OST got STATFS"
11085         fi
11086
11087         return 0
11088 }
11089 run_test 133b "Verifying extra MDT stats =================================="
11090
11091 test_133c() {
11092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11093         remote_ost_nodsh && skip "remote OST with nodsh"
11094         remote_mds_nodsh && skip "remote MDS with nodsh"
11095
11096         local testdir=$DIR/$tdir/stats_testdir
11097
11098         test_mkdir -p $testdir
11099
11100         # verify obdfilter stats.
11101         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11102         sync
11103         cancel_lru_locks osc
11104         wait_delete_completed
11105
11106         # clear stats.
11107         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11108         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11109
11110         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11111                 error "dd failed"
11112         sync
11113         cancel_lru_locks osc
11114         check_stats ost1 "write" 1
11115
11116         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11117         check_stats ost1 "read" 1
11118
11119         > $testdir/$tfile || error "truncate failed"
11120         check_stats ost1 "punch" 1
11121
11122         rm -f $testdir/$tfile || error "file remove failed"
11123         wait_delete_completed
11124         check_stats ost1 "destroy" 1
11125
11126         rm -rf $DIR/$tdir
11127 }
11128 run_test 133c "Verifying OST stats ========================================"
11129
11130 order_2() {
11131         local value=$1
11132         local orig=$value
11133         local order=1
11134
11135         while [ $value -ge 2 ]; do
11136                 order=$((order*2))
11137                 value=$((value/2))
11138         done
11139
11140         if [ $orig -gt $order ]; then
11141                 order=$((order*2))
11142         fi
11143         echo $order
11144 }
11145
11146 size_in_KMGT() {
11147     local value=$1
11148     local size=('K' 'M' 'G' 'T');
11149     local i=0
11150     local size_string=$value
11151
11152     while [ $value -ge 1024 ]; do
11153         if [ $i -gt 3 ]; then
11154             #T is the biggest unit we get here, if that is bigger,
11155             #just return XXXT
11156             size_string=${value}T
11157             break
11158         fi
11159         value=$((value >> 10))
11160         if [ $value -lt 1024 ]; then
11161             size_string=${value}${size[$i]}
11162             break
11163         fi
11164         i=$((i + 1))
11165     done
11166
11167     echo $size_string
11168 }
11169
11170 get_rename_size() {
11171         local size=$1
11172         local context=${2:-.}
11173         local sample=$(do_facet $SINGLEMDS $LCTL \
11174                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11175                 grep -A1 $context |
11176                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11177         echo $sample
11178 }
11179
11180 test_133d() {
11181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11182         remote_ost_nodsh && skip "remote OST with nodsh"
11183         remote_mds_nodsh && skip "remote MDS with nodsh"
11184         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11185                 skip_env "MDS doesn't support rename stats"
11186
11187         local testdir1=$DIR/${tdir}/stats_testdir1
11188         local testdir2=$DIR/${tdir}/stats_testdir2
11189         mkdir -p $DIR/${tdir}
11190
11191         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11192
11193         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11194         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11195
11196         createmany -o $testdir1/test 512 || error "createmany failed"
11197
11198         # check samedir rename size
11199         mv ${testdir1}/test0 ${testdir1}/test_0
11200
11201         local testdir1_size=$(ls -l $DIR/${tdir} |
11202                 awk '/stats_testdir1/ {print $5}')
11203         local testdir2_size=$(ls -l $DIR/${tdir} |
11204                 awk '/stats_testdir2/ {print $5}')
11205
11206         testdir1_size=$(order_2 $testdir1_size)
11207         testdir2_size=$(order_2 $testdir2_size)
11208
11209         testdir1_size=$(size_in_KMGT $testdir1_size)
11210         testdir2_size=$(size_in_KMGT $testdir2_size)
11211
11212         echo "source rename dir size: ${testdir1_size}"
11213         echo "target rename dir size: ${testdir2_size}"
11214
11215         local cmd="do_facet $SINGLEMDS $LCTL "
11216         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11217
11218         eval $cmd || error "$cmd failed"
11219         local samedir=$($cmd | grep 'same_dir')
11220         local same_sample=$(get_rename_size $testdir1_size)
11221         [ -z "$samedir" ] && error "samedir_rename_size count error"
11222         [[ $same_sample -eq 1 ]] ||
11223                 error "samedir_rename_size error $same_sample"
11224         echo "Check same dir rename stats success"
11225
11226         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11227
11228         # check crossdir rename size
11229         mv ${testdir1}/test_0 ${testdir2}/test_0
11230
11231         testdir1_size=$(ls -l $DIR/${tdir} |
11232                 awk '/stats_testdir1/ {print $5}')
11233         testdir2_size=$(ls -l $DIR/${tdir} |
11234                 awk '/stats_testdir2/ {print $5}')
11235
11236         testdir1_size=$(order_2 $testdir1_size)
11237         testdir2_size=$(order_2 $testdir2_size)
11238
11239         testdir1_size=$(size_in_KMGT $testdir1_size)
11240         testdir2_size=$(size_in_KMGT $testdir2_size)
11241
11242         echo "source rename dir size: ${testdir1_size}"
11243         echo "target rename dir size: ${testdir2_size}"
11244
11245         eval $cmd || error "$cmd failed"
11246         local crossdir=$($cmd | grep 'crossdir')
11247         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11248         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11249         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11250         [[ $src_sample -eq 1 ]] ||
11251                 error "crossdir_rename_size error $src_sample"
11252         [[ $tgt_sample -eq 1 ]] ||
11253                 error "crossdir_rename_size error $tgt_sample"
11254         echo "Check cross dir rename stats success"
11255         rm -rf $DIR/${tdir}
11256 }
11257 run_test 133d "Verifying rename_stats ========================================"
11258
11259 test_133e() {
11260         remote_mds_nodsh && skip "remote MDS with nodsh"
11261         remote_ost_nodsh && skip "remote OST with nodsh"
11262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11263
11264         local testdir=$DIR/${tdir}/stats_testdir
11265         local ctr f0 f1 bs=32768 count=42 sum
11266
11267         mkdir -p ${testdir} || error "mkdir failed"
11268
11269         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11270
11271         for ctr in {write,read}_bytes; do
11272                 sync
11273                 cancel_lru_locks osc
11274
11275                 do_facet ost1 $LCTL set_param -n \
11276                         "obdfilter.*.exports.clear=clear"
11277
11278                 if [ $ctr = write_bytes ]; then
11279                         f0=/dev/zero
11280                         f1=${testdir}/${tfile}
11281                 else
11282                         f0=${testdir}/${tfile}
11283                         f1=/dev/null
11284                 fi
11285
11286                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11287                         error "dd failed"
11288                 sync
11289                 cancel_lru_locks osc
11290
11291                 sum=$(do_facet ost1 $LCTL get_param \
11292                         "obdfilter.*.exports.*.stats" |
11293                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11294                                 $1 == ctr { sum += $7 }
11295                                 END { printf("%0.0f", sum) }')
11296
11297                 if ((sum != bs * count)); then
11298                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11299                 fi
11300         done
11301
11302         rm -rf $DIR/${tdir}
11303 }
11304 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11305
11306 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11307
11308 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11309 # not honor the -ignore_readdir_race option correctly. So we call
11310 # error_ignore() rather than error() in these cases. See LU-11152.
11311 error_133() {
11312         if (find --version; do_facet mds1 find --version) |
11313                 grep -q '\b4\.5\.1[1-4]\b'; then
11314                 error_ignore LU-11152 "$@"
11315         else
11316                 error "$@"
11317         fi
11318 }
11319
11320 test_133f() {
11321         # First without trusting modes.
11322         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11323         echo "proc_dirs='$proc_dirs'"
11324         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11325         find $proc_dirs -exec cat '{}' \; &> /dev/null
11326
11327         # Second verifying readability.
11328         $LCTL get_param -R '*' &> /dev/null
11329
11330         # Verifing writability with badarea_io.
11331         find $proc_dirs \
11332                 -ignore_readdir_race \
11333                 -type f \
11334                 -not -name force_lbug \
11335                 -not -name changelog_mask \
11336                 -exec badarea_io '{}' \; ||
11337                         error_133 "find $proc_dirs failed"
11338 }
11339 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11340
11341 test_133g() {
11342         remote_mds_nodsh && skip "remote MDS with nodsh"
11343         remote_ost_nodsh && skip "remote OST with nodsh"
11344
11345         # eventually, this can also be replaced with "lctl get_param -R",
11346         # but not until that option is always available on the server
11347         local facet
11348         for facet in mds1 ost1; do
11349                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11350                         skip_noexit "Too old lustre on $facet"
11351                 local facet_proc_dirs=$(do_facet $facet \
11352                                         \\\ls -d $proc_regexp 2>/dev/null)
11353                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11354                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11355                 do_facet $facet find $facet_proc_dirs \
11356                         ! -name req_history \
11357                         -exec cat '{}' \\\; &> /dev/null
11358
11359                 do_facet $facet find $facet_proc_dirs \
11360                         ! -name req_history \
11361                         -type f \
11362                         -exec cat '{}' \\\; &> /dev/null ||
11363                                 error "proc file read failed"
11364
11365                 do_facet $facet find $facet_proc_dirs \
11366                         -ignore_readdir_race \
11367                         -type f \
11368                         -not -name force_lbug \
11369                         -not -name changelog_mask \
11370                         -exec badarea_io '{}' \\\; ||
11371                                 error_133 "$facet find $facet_proc_dirs failed"
11372         done
11373
11374         # remount the FS in case writes/reads /proc break the FS
11375         cleanup || error "failed to unmount"
11376         setup || error "failed to setup"
11377         true
11378 }
11379 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11380
11381 test_133h() {
11382         remote_mds_nodsh && skip "remote MDS with nodsh"
11383         remote_ost_nodsh && skip "remote OST with nodsh"
11384         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11385                 skip "Need MDS version at least 2.9.54"
11386
11387         local facet
11388
11389         for facet in client mds1 ost1; do
11390                 local facet_proc_dirs=$(do_facet $facet \
11391                                         \\\ls -d $proc_regexp 2> /dev/null)
11392                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11393                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11394                 # Get the list of files that are missing the terminating newline
11395                 local missing=($(do_facet $facet \
11396                         find ${facet_proc_dirs} -type f \|              \
11397                                 while read F\; do                       \
11398                                         awk -v FS='\v' -v RS='\v\v'     \
11399                                         "'END { if(NR>0 &&              \
11400                                         \\\$NF !~ /.*\\\n\$/)           \
11401                                                 print FILENAME}'"       \
11402                                         '\$F'\;                         \
11403                                 done 2>/dev/null))
11404                 [ ${#missing[*]} -eq 0 ] ||
11405                         error "files do not end with newline: ${missing[*]}"
11406         done
11407 }
11408 run_test 133h "Proc files should end with newlines"
11409
11410 test_134a() {
11411         remote_mds_nodsh && skip "remote MDS with nodsh"
11412         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11413                 skip "Need MDS version at least 2.7.54"
11414
11415         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11416         cancel_lru_locks mdc
11417
11418         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11419         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11420         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11421
11422         local nr=1000
11423         createmany -o $DIR/$tdir/f $nr ||
11424                 error "failed to create $nr files in $DIR/$tdir"
11425         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11426
11427         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11428         do_facet mds1 $LCTL set_param fail_loc=0x327
11429         do_facet mds1 $LCTL set_param fail_val=500
11430         touch $DIR/$tdir/m
11431
11432         echo "sleep 10 seconds ..."
11433         sleep 10
11434         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11435
11436         do_facet mds1 $LCTL set_param fail_loc=0
11437         do_facet mds1 $LCTL set_param fail_val=0
11438         [ $lck_cnt -lt $unused ] ||
11439                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11440
11441         rm $DIR/$tdir/m
11442         unlinkmany $DIR/$tdir/f $nr
11443 }
11444 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11445
11446 test_134b() {
11447         remote_mds_nodsh && skip "remote MDS with nodsh"
11448         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11449                 skip "Need MDS version at least 2.7.54"
11450
11451         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11452         cancel_lru_locks mdc
11453
11454         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11455                         ldlm.lock_reclaim_threshold_mb)
11456         # disable reclaim temporarily
11457         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11458
11459         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11460         do_facet mds1 $LCTL set_param fail_loc=0x328
11461         do_facet mds1 $LCTL set_param fail_val=500
11462
11463         $LCTL set_param debug=+trace
11464
11465         local nr=600
11466         createmany -o $DIR/$tdir/f $nr &
11467         local create_pid=$!
11468
11469         echo "Sleep $TIMEOUT seconds ..."
11470         sleep $TIMEOUT
11471         if ! ps -p $create_pid  > /dev/null 2>&1; then
11472                 do_facet mds1 $LCTL set_param fail_loc=0
11473                 do_facet mds1 $LCTL set_param fail_val=0
11474                 do_facet mds1 $LCTL set_param \
11475                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11476                 error "createmany finished incorrectly!"
11477         fi
11478         do_facet mds1 $LCTL set_param fail_loc=0
11479         do_facet mds1 $LCTL set_param fail_val=0
11480         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11481         wait $create_pid || return 1
11482
11483         unlinkmany $DIR/$tdir/f $nr
11484 }
11485 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11486
11487 test_140() { #bug-17379
11488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11489
11490         test_mkdir $DIR/$tdir
11491         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11492         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11493
11494         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11495         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11496         local i=0
11497         while i=$((i + 1)); do
11498                 test_mkdir $i
11499                 cd $i || error "Changing to $i"
11500                 ln -s ../stat stat || error "Creating stat symlink"
11501                 # Read the symlink until ELOOP present,
11502                 # not LBUGing the system is considered success,
11503                 # we didn't overrun the stack.
11504                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11505                 if [ $ret -ne 0 ]; then
11506                         if [ $ret -eq 40 ]; then
11507                                 break  # -ELOOP
11508                         else
11509                                 error "Open stat symlink"
11510                                         return
11511                         fi
11512                 fi
11513         done
11514         i=$((i - 1))
11515         echo "The symlink depth = $i"
11516         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11517                 error "Invalid symlink depth"
11518
11519         # Test recursive symlink
11520         ln -s symlink_self symlink_self
11521         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11522         echo "open symlink_self returns $ret"
11523         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11524 }
11525 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11526
11527 test_150() {
11528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11529
11530         local TF="$TMP/$tfile"
11531
11532         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11533         cp $TF $DIR/$tfile
11534         cancel_lru_locks $OSC
11535         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11536         remount_client $MOUNT
11537         df -P $MOUNT
11538         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11539
11540         $TRUNCATE $TF 6000
11541         $TRUNCATE $DIR/$tfile 6000
11542         cancel_lru_locks $OSC
11543         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11544
11545         echo "12345" >>$TF
11546         echo "12345" >>$DIR/$tfile
11547         cancel_lru_locks $OSC
11548         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11549
11550         echo "12345" >>$TF
11551         echo "12345" >>$DIR/$tfile
11552         cancel_lru_locks $OSC
11553         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11554
11555         rm -f $TF
11556         true
11557 }
11558 run_test 150 "truncate/append tests"
11559
11560 #LU-2902 roc_hit was not able to read all values from lproc
11561 function roc_hit_init() {
11562         local list=$(comma_list $(osts_nodes))
11563         local dir=$DIR/$tdir-check
11564         local file=$dir/$tfile
11565         local BEFORE
11566         local AFTER
11567         local idx
11568
11569         test_mkdir $dir
11570         #use setstripe to do a write to every ost
11571         for i in $(seq 0 $((OSTCOUNT-1))); do
11572                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11573                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11574                 idx=$(printf %04x $i)
11575                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11576                         awk '$1 == "cache_access" {sum += $7}
11577                                 END { printf("%0.0f", sum) }')
11578
11579                 cancel_lru_locks osc
11580                 cat $file >/dev/null
11581
11582                 AFTER=$(get_osd_param $list *OST*$idx stats |
11583                         awk '$1 == "cache_access" {sum += $7}
11584                                 END { printf("%0.0f", sum) }')
11585
11586                 echo BEFORE:$BEFORE AFTER:$AFTER
11587                 if ! let "AFTER - BEFORE == 4"; then
11588                         rm -rf $dir
11589                         error "roc_hit is not safe to use"
11590                 fi
11591                 rm $file
11592         done
11593
11594         rm -rf $dir
11595 }
11596
11597 function roc_hit() {
11598         local list=$(comma_list $(osts_nodes))
11599         echo $(get_osd_param $list '' stats |
11600                 awk '$1 == "cache_hit" {sum += $7}
11601                         END { printf("%0.0f", sum) }')
11602 }
11603
11604 function set_cache() {
11605         local on=1
11606
11607         if [ "$2" == "off" ]; then
11608                 on=0;
11609         fi
11610         local list=$(comma_list $(osts_nodes))
11611         set_osd_param $list '' $1_cache_enable $on
11612
11613         cancel_lru_locks osc
11614 }
11615
11616 test_151() {
11617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11618         remote_ost_nodsh && skip "remote OST with nodsh"
11619
11620         local CPAGES=3
11621         local list=$(comma_list $(osts_nodes))
11622
11623         # check whether obdfilter is cache capable at all
11624         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11625                 skip "not cache-capable obdfilter"
11626         fi
11627
11628         # check cache is enabled on all obdfilters
11629         if get_osd_param $list '' read_cache_enable | grep 0; then
11630                 skip "oss cache is disabled"
11631         fi
11632
11633         set_osd_param $list '' writethrough_cache_enable 1
11634
11635         # check write cache is enabled on all obdfilters
11636         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11637                 skip "oss write cache is NOT enabled"
11638         fi
11639
11640         roc_hit_init
11641
11642         #define OBD_FAIL_OBD_NO_LRU  0x609
11643         do_nodes $list $LCTL set_param fail_loc=0x609
11644
11645         # pages should be in the case right after write
11646         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11647                 error "dd failed"
11648
11649         local BEFORE=$(roc_hit)
11650         cancel_lru_locks osc
11651         cat $DIR/$tfile >/dev/null
11652         local AFTER=$(roc_hit)
11653
11654         do_nodes $list $LCTL set_param fail_loc=0
11655
11656         if ! let "AFTER - BEFORE == CPAGES"; then
11657                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11658         fi
11659
11660         # the following read invalidates the cache
11661         cancel_lru_locks osc
11662         set_osd_param $list '' read_cache_enable 0
11663         cat $DIR/$tfile >/dev/null
11664
11665         # now data shouldn't be found in the cache
11666         BEFORE=$(roc_hit)
11667         cancel_lru_locks osc
11668         cat $DIR/$tfile >/dev/null
11669         AFTER=$(roc_hit)
11670         if let "AFTER - BEFORE != 0"; then
11671                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11672         fi
11673
11674         set_osd_param $list '' read_cache_enable 1
11675         rm -f $DIR/$tfile
11676 }
11677 run_test 151 "test cache on oss and controls ==============================="
11678
11679 test_152() {
11680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11681
11682         local TF="$TMP/$tfile"
11683
11684         # simulate ENOMEM during write
11685 #define OBD_FAIL_OST_NOMEM      0x226
11686         lctl set_param fail_loc=0x80000226
11687         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11688         cp $TF $DIR/$tfile
11689         sync || error "sync failed"
11690         lctl set_param fail_loc=0
11691
11692         # discard client's cache
11693         cancel_lru_locks osc
11694
11695         # simulate ENOMEM during read
11696         lctl set_param fail_loc=0x80000226
11697         cmp $TF $DIR/$tfile || error "cmp failed"
11698         lctl set_param fail_loc=0
11699
11700         rm -f $TF
11701 }
11702 run_test 152 "test read/write with enomem ============================"
11703
11704 test_153() {
11705         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11706 }
11707 run_test 153 "test if fdatasync does not crash ======================="
11708
11709 dot_lustre_fid_permission_check() {
11710         local fid=$1
11711         local ffid=$MOUNT/.lustre/fid/$fid
11712         local test_dir=$2
11713
11714         echo "stat fid $fid"
11715         stat $ffid > /dev/null || error "stat $ffid failed."
11716         echo "touch fid $fid"
11717         touch $ffid || error "touch $ffid failed."
11718         echo "write to fid $fid"
11719         cat /etc/hosts > $ffid || error "write $ffid failed."
11720         echo "read fid $fid"
11721         diff /etc/hosts $ffid || error "read $ffid failed."
11722         echo "append write to fid $fid"
11723         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11724         echo "rename fid $fid"
11725         mv $ffid $test_dir/$tfile.1 &&
11726                 error "rename $ffid to $tfile.1 should fail."
11727         touch $test_dir/$tfile.1
11728         mv $test_dir/$tfile.1 $ffid &&
11729                 error "rename $tfile.1 to $ffid should fail."
11730         rm -f $test_dir/$tfile.1
11731         echo "truncate fid $fid"
11732         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11733         echo "link fid $fid"
11734         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11735         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11736                 echo "setfacl fid $fid"
11737                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11738                 echo "getfacl fid $fid"
11739                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11740         fi
11741         echo "unlink fid $fid"
11742         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11743         echo "mknod fid $fid"
11744         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11745
11746         fid=[0xf00000400:0x1:0x0]
11747         ffid=$MOUNT/.lustre/fid/$fid
11748
11749         echo "stat non-exist fid $fid"
11750         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11751         echo "write to non-exist fid $fid"
11752         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11753         echo "link new fid $fid"
11754         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11755
11756         mkdir -p $test_dir/$tdir
11757         touch $test_dir/$tdir/$tfile
11758         fid=$($LFS path2fid $test_dir/$tdir)
11759         rc=$?
11760         [ $rc -ne 0 ] &&
11761                 error "error: could not get fid for $test_dir/$dir/$tfile."
11762
11763         ffid=$MOUNT/.lustre/fid/$fid
11764
11765         echo "ls $fid"
11766         ls $ffid > /dev/null || error "ls $ffid failed."
11767         echo "touch $fid/$tfile.1"
11768         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11769
11770         echo "touch $MOUNT/.lustre/fid/$tfile"
11771         touch $MOUNT/.lustre/fid/$tfile && \
11772                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11773
11774         echo "setxattr to $MOUNT/.lustre/fid"
11775         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11776
11777         echo "listxattr for $MOUNT/.lustre/fid"
11778         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11779
11780         echo "delxattr from $MOUNT/.lustre/fid"
11781         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11782
11783         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11784         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11785                 error "touch invalid fid should fail."
11786
11787         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11788         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11789                 error "touch non-normal fid should fail."
11790
11791         echo "rename $tdir to $MOUNT/.lustre/fid"
11792         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11793                 error "rename to $MOUNT/.lustre/fid should fail."
11794
11795         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11796         then            # LU-3547
11797                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11798                 local new_obf_mode=777
11799
11800                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11801                 chmod $new_obf_mode $DIR/.lustre/fid ||
11802                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11803
11804                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11805                 [ $obf_mode -eq $new_obf_mode ] ||
11806                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11807
11808                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11809                 chmod $old_obf_mode $DIR/.lustre/fid ||
11810                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11811         fi
11812
11813         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11814         fid=$($LFS path2fid $test_dir/$tfile-2)
11815
11816         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11817         then # LU-5424
11818                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11819                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11820                         error "create lov data thru .lustre failed"
11821         fi
11822         echo "cp /etc/passwd $test_dir/$tfile-2"
11823         cp /etc/passwd $test_dir/$tfile-2 ||
11824                 error "copy to $test_dir/$tfile-2 failed."
11825         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11826         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11827                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11828
11829         rm -rf $test_dir/tfile.lnk
11830         rm -rf $test_dir/$tfile-2
11831 }
11832
11833 test_154A() {
11834         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11835                 skip "Need MDS version at least 2.4.1"
11836
11837         local tf=$DIR/$tfile
11838         touch $tf
11839
11840         local fid=$($LFS path2fid $tf)
11841         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11842
11843         # check that we get the same pathname back
11844         local found=$($LFS fid2path $MOUNT "$fid")
11845         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11846         [ "$found" == "$tf" ] ||
11847                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11848 }
11849 run_test 154A "lfs path2fid and fid2path basic checks"
11850
11851 test_154B() {
11852         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11853                 skip "Need MDS version at least 2.4.1"
11854
11855         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11856         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11857         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11858         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11859
11860         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11861         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11862
11863         # check that we get the same pathname
11864         echo "PFID: $PFID, name: $name"
11865         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11866         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11867         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11868                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11869
11870         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11871 }
11872 run_test 154B "verify the ll_decode_linkea tool"
11873
11874 test_154a() {
11875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11876         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11877         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11878                 skip "Need MDS version at least 2.2.51"
11879         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11880
11881         cp /etc/hosts $DIR/$tfile
11882
11883         fid=$($LFS path2fid $DIR/$tfile)
11884         rc=$?
11885         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11886
11887         dot_lustre_fid_permission_check "$fid" $DIR ||
11888                 error "dot lustre permission check $fid failed"
11889
11890         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11891
11892         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11893
11894         touch $MOUNT/.lustre/file &&
11895                 error "creation is not allowed under .lustre"
11896
11897         mkdir $MOUNT/.lustre/dir &&
11898                 error "mkdir is not allowed under .lustre"
11899
11900         rm -rf $DIR/$tfile
11901 }
11902 run_test 154a "Open-by-FID"
11903
11904 test_154b() {
11905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11906         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11908         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11909                 skip "Need MDS version at least 2.2.51"
11910
11911         local remote_dir=$DIR/$tdir/remote_dir
11912         local MDTIDX=1
11913         local rc=0
11914
11915         mkdir -p $DIR/$tdir
11916         $LFS mkdir -i $MDTIDX $remote_dir ||
11917                 error "create remote directory failed"
11918
11919         cp /etc/hosts $remote_dir/$tfile
11920
11921         fid=$($LFS path2fid $remote_dir/$tfile)
11922         rc=$?
11923         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11924
11925         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11926                 error "dot lustre permission check $fid failed"
11927         rm -rf $DIR/$tdir
11928 }
11929 run_test 154b "Open-by-FID for remote directory"
11930
11931 test_154c() {
11932         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11933                 skip "Need MDS version at least 2.4.1"
11934
11935         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11936         local FID1=$($LFS path2fid $DIR/$tfile.1)
11937         local FID2=$($LFS path2fid $DIR/$tfile.2)
11938         local FID3=$($LFS path2fid $DIR/$tfile.3)
11939
11940         local N=1
11941         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11942                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11943                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11944                 local want=FID$N
11945                 [ "$FID" = "${!want}" ] ||
11946                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11947                 N=$((N + 1))
11948         done
11949
11950         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11951         do
11952                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11953                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11954                 N=$((N + 1))
11955         done
11956 }
11957 run_test 154c "lfs path2fid and fid2path multiple arguments"
11958
11959 test_154d() {
11960         remote_mds_nodsh && skip "remote MDS with nodsh"
11961         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11962                 skip "Need MDS version at least 2.5.53"
11963
11964         if remote_mds; then
11965                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11966         else
11967                 nid="0@lo"
11968         fi
11969         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11970         local fd
11971         local cmd
11972
11973         rm -f $DIR/$tfile
11974         touch $DIR/$tfile
11975
11976         local fid=$($LFS path2fid $DIR/$tfile)
11977         # Open the file
11978         fd=$(free_fd)
11979         cmd="exec $fd<$DIR/$tfile"
11980         eval $cmd
11981         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11982         echo "$fid_list" | grep "$fid"
11983         rc=$?
11984
11985         cmd="exec $fd>/dev/null"
11986         eval $cmd
11987         if [ $rc -ne 0 ]; then
11988                 error "FID $fid not found in open files list $fid_list"
11989         fi
11990 }
11991 run_test 154d "Verify open file fid"
11992
11993 test_154e()
11994 {
11995         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11996                 skip "Need MDS version at least 2.6.50"
11997
11998         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11999                 error ".lustre returned by readdir"
12000         fi
12001 }
12002 run_test 154e ".lustre is not returned by readdir"
12003
12004 test_154f() {
12005         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12006
12007         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12008         test_mkdir -p -c1 $DIR/$tdir/d
12009         # test dirs inherit from its stripe
12010         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12011         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12012         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12013         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12014         touch $DIR/f
12015
12016         # get fid of parents
12017         local FID0=$($LFS path2fid $DIR/$tdir/d)
12018         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12019         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12020         local FID3=$($LFS path2fid $DIR)
12021
12022         # check that path2fid --parents returns expected <parent_fid>/name
12023         # 1) test for a directory (single parent)
12024         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12025         [ "$parent" == "$FID0/foo1" ] ||
12026                 error "expected parent: $FID0/foo1, got: $parent"
12027
12028         # 2) test for a file with nlink > 1 (multiple parents)
12029         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12030         echo "$parent" | grep -F "$FID1/$tfile" ||
12031                 error "$FID1/$tfile not returned in parent list"
12032         echo "$parent" | grep -F "$FID2/link" ||
12033                 error "$FID2/link not returned in parent list"
12034
12035         # 3) get parent by fid
12036         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12037         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12038         echo "$parent" | grep -F "$FID1/$tfile" ||
12039                 error "$FID1/$tfile not returned in parent list (by fid)"
12040         echo "$parent" | grep -F "$FID2/link" ||
12041                 error "$FID2/link not returned in parent list (by fid)"
12042
12043         # 4) test for entry in root directory
12044         parent=$($LFS path2fid --parents $DIR/f)
12045         echo "$parent" | grep -F "$FID3/f" ||
12046                 error "$FID3/f not returned in parent list"
12047
12048         # 5) test it on root directory
12049         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12050                 error "$MOUNT should not have parents"
12051
12052         # enable xattr caching and check that linkea is correctly updated
12053         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12054         save_lustre_params client "llite.*.xattr_cache" > $save
12055         lctl set_param llite.*.xattr_cache 1
12056
12057         # 6.1) linkea update on rename
12058         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12059
12060         # get parents by fid
12061         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12062         # foo1 should no longer be returned in parent list
12063         echo "$parent" | grep -F "$FID1" &&
12064                 error "$FID1 should no longer be in parent list"
12065         # the new path should appear
12066         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12067                 error "$FID2/$tfile.moved is not in parent list"
12068
12069         # 6.2) linkea update on unlink
12070         rm -f $DIR/$tdir/d/foo2/link
12071         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12072         # foo2/link should no longer be returned in parent list
12073         echo "$parent" | grep -F "$FID2/link" &&
12074                 error "$FID2/link should no longer be in parent list"
12075         true
12076
12077         rm -f $DIR/f
12078         restore_lustre_params < $save
12079         rm -f $save
12080 }
12081 run_test 154f "get parent fids by reading link ea"
12082
12083 test_154g()
12084 {
12085         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12086         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12087            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12088                 skip "Need MDS version at least 2.6.92"
12089
12090         mkdir -p $DIR/$tdir
12091         llapi_fid_test -d $DIR/$tdir
12092 }
12093 run_test 154g "various llapi FID tests"
12094
12095 test_155_small_load() {
12096     local temp=$TMP/$tfile
12097     local file=$DIR/$tfile
12098
12099     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12100         error "dd of=$temp bs=6096 count=1 failed"
12101     cp $temp $file
12102     cancel_lru_locks $OSC
12103     cmp $temp $file || error "$temp $file differ"
12104
12105     $TRUNCATE $temp 6000
12106     $TRUNCATE $file 6000
12107     cmp $temp $file || error "$temp $file differ (truncate1)"
12108
12109     echo "12345" >>$temp
12110     echo "12345" >>$file
12111     cmp $temp $file || error "$temp $file differ (append1)"
12112
12113     echo "12345" >>$temp
12114     echo "12345" >>$file
12115     cmp $temp $file || error "$temp $file differ (append2)"
12116
12117     rm -f $temp $file
12118     true
12119 }
12120
12121 test_155_big_load() {
12122         remote_ost_nodsh && skip "remote OST with nodsh"
12123
12124         local temp=$TMP/$tfile
12125         local file=$DIR/$tfile
12126
12127         free_min_max
12128         local cache_size=$(do_facet ost$((MAXI+1)) \
12129                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12130         local large_file_size=$((cache_size * 2))
12131
12132         echo "OSS cache size: $cache_size KB"
12133         echo "Large file size: $large_file_size KB"
12134
12135         [ $MAXV -le $large_file_size ] &&
12136                 skip_env "max available OST size needs > $large_file_size KB"
12137
12138         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12139
12140         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12141                 error "dd of=$temp bs=$large_file_size count=1k failed"
12142         cp $temp $file
12143         ls -lh $temp $file
12144         cancel_lru_locks osc
12145         cmp $temp $file || error "$temp $file differ"
12146
12147         rm -f $temp $file
12148         true
12149 }
12150
12151 save_writethrough() {
12152         local facets=$(get_facets OST)
12153
12154         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12155 }
12156
12157 test_155a() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159
12160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12161
12162         save_writethrough $p
12163
12164         set_cache read on
12165         set_cache writethrough on
12166         test_155_small_load
12167         restore_lustre_params < $p
12168         rm -f $p
12169 }
12170 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12171
12172 test_155b() {
12173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12174
12175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12176
12177         save_writethrough $p
12178
12179         set_cache read on
12180         set_cache writethrough off
12181         test_155_small_load
12182         restore_lustre_params < $p
12183         rm -f $p
12184 }
12185 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12186
12187 test_155c() {
12188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12189
12190         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12191
12192         save_writethrough $p
12193
12194         set_cache read off
12195         set_cache writethrough on
12196         test_155_small_load
12197         restore_lustre_params < $p
12198         rm -f $p
12199 }
12200 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12201
12202 test_155d() {
12203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12204
12205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12206
12207         save_writethrough $p
12208
12209         set_cache read off
12210         set_cache writethrough off
12211         test_155_small_load
12212         restore_lustre_params < $p
12213         rm -f $p
12214 }
12215 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12216
12217 test_155e() {
12218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12219
12220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12221
12222         save_writethrough $p
12223
12224         set_cache read on
12225         set_cache writethrough on
12226         test_155_big_load
12227         restore_lustre_params < $p
12228         rm -f $p
12229 }
12230 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12231
12232 test_155f() {
12233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12234
12235         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12236
12237         save_writethrough $p
12238
12239         set_cache read on
12240         set_cache writethrough off
12241         test_155_big_load
12242         restore_lustre_params < $p
12243         rm -f $p
12244 }
12245 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12246
12247 test_155g() {
12248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12249
12250         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12251
12252         save_writethrough $p
12253
12254         set_cache read off
12255         set_cache writethrough on
12256         test_155_big_load
12257         restore_lustre_params < $p
12258         rm -f $p
12259 }
12260 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12261
12262 test_155h() {
12263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12264
12265         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12266
12267         save_writethrough $p
12268
12269         set_cache read off
12270         set_cache writethrough off
12271         test_155_big_load
12272         restore_lustre_params < $p
12273         rm -f $p
12274 }
12275 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12276
12277 test_156() {
12278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12279         remote_ost_nodsh && skip "remote OST with nodsh"
12280         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12281                 skip "stats not implemented on old servers"
12282         [ "$ost1_FSTYPE" = "zfs" ] &&
12283                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12284
12285         local CPAGES=3
12286         local BEFORE
12287         local AFTER
12288         local file="$DIR/$tfile"
12289         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12290
12291         save_writethrough $p
12292         roc_hit_init
12293
12294         log "Turn on read and write cache"
12295         set_cache read on
12296         set_cache writethrough on
12297
12298         log "Write data and read it back."
12299         log "Read should be satisfied from the cache."
12300         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12301         BEFORE=$(roc_hit)
12302         cancel_lru_locks osc
12303         cat $file >/dev/null
12304         AFTER=$(roc_hit)
12305         if ! let "AFTER - BEFORE == CPAGES"; then
12306                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12307         else
12308                 log "cache hits:: before: $BEFORE, after: $AFTER"
12309         fi
12310
12311         log "Read again; it should be satisfied from the cache."
12312         BEFORE=$AFTER
12313         cancel_lru_locks osc
12314         cat $file >/dev/null
12315         AFTER=$(roc_hit)
12316         if ! let "AFTER - BEFORE == CPAGES"; then
12317                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12318         else
12319                 log "cache hits:: before: $BEFORE, after: $AFTER"
12320         fi
12321
12322         log "Turn off the read cache and turn on the write cache"
12323         set_cache read off
12324         set_cache writethrough on
12325
12326         log "Read again; it should be satisfied from the cache."
12327         BEFORE=$(roc_hit)
12328         cancel_lru_locks osc
12329         cat $file >/dev/null
12330         AFTER=$(roc_hit)
12331         if ! let "AFTER - BEFORE == CPAGES"; then
12332                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12333         else
12334                 log "cache hits:: before: $BEFORE, after: $AFTER"
12335         fi
12336
12337         log "Read again; it should not be satisfied from the cache."
12338         BEFORE=$AFTER
12339         cancel_lru_locks osc
12340         cat $file >/dev/null
12341         AFTER=$(roc_hit)
12342         if ! let "AFTER - BEFORE == 0"; then
12343                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12344         else
12345                 log "cache hits:: before: $BEFORE, after: $AFTER"
12346         fi
12347
12348         log "Write data and read it back."
12349         log "Read should be satisfied from the cache."
12350         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12351         BEFORE=$(roc_hit)
12352         cancel_lru_locks osc
12353         cat $file >/dev/null
12354         AFTER=$(roc_hit)
12355         if ! let "AFTER - BEFORE == CPAGES"; then
12356                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12357         else
12358                 log "cache hits:: before: $BEFORE, after: $AFTER"
12359         fi
12360
12361         log "Read again; it should not be satisfied from the cache."
12362         BEFORE=$AFTER
12363         cancel_lru_locks osc
12364         cat $file >/dev/null
12365         AFTER=$(roc_hit)
12366         if ! let "AFTER - BEFORE == 0"; then
12367                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12368         else
12369                 log "cache hits:: before: $BEFORE, after: $AFTER"
12370         fi
12371
12372         log "Turn off read and write cache"
12373         set_cache read off
12374         set_cache writethrough off
12375
12376         log "Write data and read it back"
12377         log "It should not be satisfied from the cache."
12378         rm -f $file
12379         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12380         cancel_lru_locks osc
12381         BEFORE=$(roc_hit)
12382         cat $file >/dev/null
12383         AFTER=$(roc_hit)
12384         if ! let "AFTER - BEFORE == 0"; then
12385                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12386         else
12387                 log "cache hits:: before: $BEFORE, after: $AFTER"
12388         fi
12389
12390         log "Turn on the read cache and turn off the write cache"
12391         set_cache read on
12392         set_cache writethrough off
12393
12394         log "Write data and read it back"
12395         log "It should not be satisfied from the cache."
12396         rm -f $file
12397         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12398         BEFORE=$(roc_hit)
12399         cancel_lru_locks osc
12400         cat $file >/dev/null
12401         AFTER=$(roc_hit)
12402         if ! let "AFTER - BEFORE == 0"; then
12403                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12404         else
12405                 log "cache hits:: before: $BEFORE, after: $AFTER"
12406         fi
12407
12408         log "Read again; it should be satisfied from the cache."
12409         BEFORE=$(roc_hit)
12410         cancel_lru_locks osc
12411         cat $file >/dev/null
12412         AFTER=$(roc_hit)
12413         if ! let "AFTER - BEFORE == CPAGES"; then
12414                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12415         else
12416                 log "cache hits:: before: $BEFORE, after: $AFTER"
12417         fi
12418
12419         restore_lustre_params < $p
12420         rm -f $p $file
12421 }
12422 run_test 156 "Verification of tunables"
12423
12424 test_160a() {
12425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12426         remote_mds_nodsh && skip "remote MDS with nodsh"
12427         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12428                 skip "Need MDS version at least 2.2.0"
12429
12430         changelog_register || error "changelog_register failed"
12431         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12432         changelog_users $SINGLEMDS | grep -q $cl_user ||
12433                 error "User $cl_user not found in changelog_users"
12434
12435         # change something
12436         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12437         changelog_clear 0 || error "changelog_clear failed"
12438         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12439         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12440         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12441         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12442         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12443         rm $DIR/$tdir/pics/desktop.jpg
12444
12445         changelog_dump | tail -10
12446
12447         echo "verifying changelog mask"
12448         changelog_chmask "-MKDIR"
12449         changelog_chmask "-CLOSE"
12450
12451         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12452         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12453
12454         changelog_chmask "+MKDIR"
12455         changelog_chmask "+CLOSE"
12456
12457         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12458         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12459
12460         changelog_dump | tail -10
12461         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12462         CLOSES=$(changelog_dump | grep -c "CLOSE")
12463         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12464         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12465
12466         # verify contents
12467         echo "verifying target fid"
12468         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12469         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12470         [ "$fidc" == "$fidf" ] ||
12471                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12472         echo "verifying parent fid"
12473         # The FID returned from the Changelog may be the directory shard on
12474         # a different MDT, and not the FID returned by path2fid on the parent.
12475         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12476         # since this is what will matter when recreating this file in the tree.
12477         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12478         local pathp=$($LFS fid2path $MOUNT "$fidp")
12479         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12480                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12481
12482         echo "getting records for $cl_user"
12483         changelog_users $SINGLEMDS
12484         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12485         local nclr=3
12486         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12487                 error "changelog_clear failed"
12488         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12489         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12490         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12491                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12492
12493         local min0_rec=$(changelog_users $SINGLEMDS |
12494                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12495         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12496                           awk '{ print $1; exit; }')
12497
12498         changelog_dump | tail -n 5
12499         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12500         [ $first_rec == $((min0_rec + 1)) ] ||
12501                 error "first index should be $min0_rec + 1 not $first_rec"
12502
12503         # LU-3446 changelog index reset on MDT restart
12504         local cur_rec1=$(changelog_users $SINGLEMDS |
12505                          awk '/^current.index:/ { print $NF }')
12506         changelog_clear 0 ||
12507                 error "clear all changelog records for $cl_user failed"
12508         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12509         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12510                 error "Fail to start $SINGLEMDS"
12511         local cur_rec2=$(changelog_users $SINGLEMDS |
12512                          awk '/^current.index:/ { print $NF }')
12513         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12514         [ $cur_rec1 == $cur_rec2 ] ||
12515                 error "current index should be $cur_rec1 not $cur_rec2"
12516
12517         echo "verifying users from this test are deregistered"
12518         changelog_deregister || error "changelog_deregister failed"
12519         changelog_users $SINGLEMDS | grep -q $cl_user &&
12520                 error "User '$cl_user' still in changelog_users"
12521
12522         # lctl get_param -n mdd.*.changelog_users
12523         # current index: 144
12524         # ID    index (idle seconds)
12525         # cl3   144 (2)
12526         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12527                 # this is the normal case where all users were deregistered
12528                 # make sure no new records are added when no users are present
12529                 local last_rec1=$(changelog_users $SINGLEMDS |
12530                                   awk '/^current.index:/ { print $NF }')
12531                 touch $DIR/$tdir/chloe
12532                 local last_rec2=$(changelog_users $SINGLEMDS |
12533                                   awk '/^current.index:/ { print $NF }')
12534                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12535                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12536         else
12537                 # any changelog users must be leftovers from a previous test
12538                 changelog_users $SINGLEMDS
12539                 echo "other changelog users; can't verify off"
12540         fi
12541 }
12542 run_test 160a "changelog sanity"
12543
12544 test_160b() { # LU-3587
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         remote_mds_nodsh && skip "remote MDS with nodsh"
12547         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12548                 skip "Need MDS version at least 2.2.0"
12549
12550         changelog_register || error "changelog_register failed"
12551         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12552         changelog_users $SINGLEMDS | grep -q $cl_user ||
12553                 error "User '$cl_user' not found in changelog_users"
12554
12555         local longname1=$(str_repeat a 255)
12556         local longname2=$(str_repeat b 255)
12557
12558         cd $DIR
12559         echo "creating very long named file"
12560         touch $longname1 || error "create of '$longname1' failed"
12561         echo "renaming very long named file"
12562         mv $longname1 $longname2
12563
12564         changelog_dump | grep RENME | tail -n 5
12565         rm -f $longname2
12566 }
12567 run_test 160b "Verify that very long rename doesn't crash in changelog"
12568
12569 test_160c() {
12570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12571         remote_mds_nodsh && skip "remote MDS with nodsh"
12572
12573         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12574                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12575                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12576                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12577
12578         local rc=0
12579
12580         # Registration step
12581         changelog_register || error "changelog_register failed"
12582
12583         rm -rf $DIR/$tdir
12584         mkdir -p $DIR/$tdir
12585         $MCREATE $DIR/$tdir/foo_160c
12586         changelog_chmask "-TRUNC"
12587         $TRUNCATE $DIR/$tdir/foo_160c 200
12588         changelog_chmask "+TRUNC"
12589         $TRUNCATE $DIR/$tdir/foo_160c 199
12590         changelog_dump | tail -n 5
12591         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12592         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12593 }
12594 run_test 160c "verify that changelog log catch the truncate event"
12595
12596 test_160d() {
12597         remote_mds_nodsh && skip "remote MDS with nodsh"
12598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12600         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12601                 skip "Need MDS version at least 2.7.60"
12602
12603         # Registration step
12604         changelog_register || error "changelog_register failed"
12605
12606         mkdir -p $DIR/$tdir/migrate_dir
12607         changelog_clear 0 || error "changelog_clear failed"
12608
12609         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12610         changelog_dump | tail -n 5
12611         local migrates=$(changelog_dump | grep -c "MIGRT")
12612         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12613 }
12614 run_test 160d "verify that changelog log catch the migrate event"
12615
12616 test_160e() {
12617         remote_mds_nodsh && skip "remote MDS with nodsh"
12618
12619         # Create a user
12620         changelog_register || error "changelog_register failed"
12621
12622         # Delete a future user (expect fail)
12623         local MDT0=$(facet_svc $SINGLEMDS)
12624         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12625         local rc=$?
12626
12627         if [ $rc -eq 0 ]; then
12628                 error "Deleted non-existant user cl77"
12629         elif [ $rc -ne 2 ]; then
12630                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12631         fi
12632
12633         # Clear to a bad index (1 billion should be safe)
12634         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12635         rc=$?
12636
12637         if [ $rc -eq 0 ]; then
12638                 error "Successfully cleared to invalid CL index"
12639         elif [ $rc -ne 22 ]; then
12640                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12641         fi
12642 }
12643 run_test 160e "changelog negative testing (should return errors)"
12644
12645 test_160f() {
12646         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12647         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12648                 skip "Need MDS version at least 2.10.56"
12649
12650         local mdts=$(comma_list $(mdts_nodes))
12651
12652         # Create a user
12653         changelog_register || error "first changelog_register failed"
12654         changelog_register || error "second changelog_register failed"
12655         local cl_users
12656         declare -A cl_user1
12657         declare -A cl_user2
12658         local user_rec1
12659         local user_rec2
12660         local i
12661
12662         # generate some changelog records to accumulate on each MDT
12663         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12664         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12665                 error "create $DIR/$tdir/$tfile failed"
12666
12667         # check changelogs have been generated
12668         local nbcl=$(changelog_dump | wc -l)
12669         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12670
12671         for param in "changelog_max_idle_time=10" \
12672                      "changelog_gc=1" \
12673                      "changelog_min_gc_interval=2" \
12674                      "changelog_min_free_cat_entries=3"; do
12675                 local MDT0=$(facet_svc $SINGLEMDS)
12676                 local var="${param%=*}"
12677                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12678
12679                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12680                 do_nodes $mdts $LCTL set_param mdd.*.$param
12681         done
12682
12683         # force cl_user2 to be idle (1st part)
12684         sleep 9
12685
12686         # simulate changelog catalog almost full
12687         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12688         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12689
12690         for i in $(seq $MDSCOUNT); do
12691                 cl_users=(${CL_USERS[mds$i]})
12692                 cl_user1[mds$i]="${cl_users[0]}"
12693                 cl_user2[mds$i]="${cl_users[1]}"
12694
12695                 [ -n "${cl_user1[mds$i]}" ] ||
12696                         error "mds$i: no user registered"
12697                 [ -n "${cl_user2[mds$i]}" ] ||
12698                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12699
12700                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12701                 [ -n "$user_rec1" ] ||
12702                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12703                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12704                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12705                 [ -n "$user_rec2" ] ||
12706                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12707                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12708                      "$user_rec1 + 2 == $user_rec2"
12709                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12710                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12711                               "$user_rec1 + 2, but is $user_rec2"
12712                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12713                 [ -n "$user_rec2" ] ||
12714                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12715                 [ $user_rec1 == $user_rec2 ] ||
12716                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12717                               "$user_rec1, but is $user_rec2"
12718         done
12719
12720         # force cl_user2 to be idle (2nd part) and to reach
12721         # changelog_max_idle_time
12722         sleep 2
12723
12724         # generate one more changelog to trigger fail_loc
12725         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12726                 error "create $DIR/$tdir/${tfile}bis failed"
12727
12728         # ensure gc thread is done
12729         for i in $(mdts_nodes); do
12730                 wait_update $i \
12731                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12732                         error "$i: GC-thread not done"
12733         done
12734
12735         local first_rec
12736         for i in $(seq $MDSCOUNT); do
12737                 # check cl_user1 still registered
12738                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12739                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12740                 # check cl_user2 unregistered
12741                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12742                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12743
12744                 # check changelogs are present and starting at $user_rec1 + 1
12745                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12746                 [ -n "$user_rec1" ] ||
12747                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12748                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12749                             awk '{ print $1; exit; }')
12750
12751                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12752                 [ $((user_rec1 + 1)) == $first_rec ] ||
12753                         error "mds$i: first index should be $user_rec1 + 1, " \
12754                               "but is $first_rec"
12755         done
12756 }
12757 run_test 160f "changelog garbage collect (timestamped users)"
12758
12759 test_160g() {
12760         remote_mds_nodsh && skip "remote MDS with nodsh"
12761         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12762                 skip "Need MDS version at least 2.10.56"
12763
12764         local mdts=$(comma_list $(mdts_nodes))
12765
12766         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12767         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12768
12769         # Create a user
12770         changelog_register || error "first changelog_register failed"
12771         changelog_register || error "second changelog_register failed"
12772         local cl_users
12773         declare -A cl_user1
12774         declare -A cl_user2
12775         local user_rec1
12776         local user_rec2
12777         local i
12778
12779         # generate some changelog records to accumulate on each MDT
12780         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12781         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12782                 error "create $DIR/$tdir/$tfile failed"
12783
12784         # check changelogs have been generated
12785         local nbcl=$(changelog_dump | wc -l)
12786         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12787
12788         # reduce the max_idle_indexes value to make sure we exceed it
12789         max_ndx=$((nbcl / 2 - 1))
12790
12791         for param in "changelog_max_idle_indexes=$max_ndx" \
12792                      "changelog_gc=1" \
12793                      "changelog_min_gc_interval=2" \
12794                      "changelog_min_free_cat_entries=3"; do
12795                 local MDT0=$(facet_svc $SINGLEMDS)
12796                 local var="${param%=*}"
12797                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12798
12799                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12800                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12801                         error "unable to set mdd.*.$param"
12802         done
12803
12804         # simulate changelog catalog almost full
12805         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12806         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12807
12808         for i in $(seq $MDSCOUNT); do
12809                 cl_users=(${CL_USERS[mds$i]})
12810                 cl_user1[mds$i]="${cl_users[0]}"
12811                 cl_user2[mds$i]="${cl_users[1]}"
12812
12813                 [ -n "${cl_user1[mds$i]}" ] ||
12814                         error "mds$i: no user registered"
12815                 [ -n "${cl_user2[mds$i]}" ] ||
12816                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12817
12818                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12819                 [ -n "$user_rec1" ] ||
12820                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12821                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12822                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12823                 [ -n "$user_rec2" ] ||
12824                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12825                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12826                      "$user_rec1 + 2 == $user_rec2"
12827                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12828                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12829                               "$user_rec1 + 2, but is $user_rec2"
12830                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12831                 [ -n "$user_rec2" ] ||
12832                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12833                 [ $user_rec1 == $user_rec2 ] ||
12834                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12835                               "$user_rec1, but is $user_rec2"
12836         done
12837
12838         # ensure we are past the previous changelog_min_gc_interval set above
12839         sleep 2
12840
12841         # generate one more changelog to trigger fail_loc
12842         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12843                 error "create $DIR/$tdir/${tfile}bis failed"
12844
12845         # ensure gc thread is done
12846         for i in $(mdts_nodes); do
12847                 wait_update $i \
12848                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12849                         error "$i: GC-thread not done"
12850         done
12851
12852         local first_rec
12853         for i in $(seq $MDSCOUNT); do
12854                 # check cl_user1 still registered
12855                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12856                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12857                 # check cl_user2 unregistered
12858                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12859                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12860
12861                 # check changelogs are present and starting at $user_rec1 + 1
12862                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12863                 [ -n "$user_rec1" ] ||
12864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12865                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12866                             awk '{ print $1; exit; }')
12867
12868                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12869                 [ $((user_rec1 + 1)) == $first_rec ] ||
12870                         error "mds$i: first index should be $user_rec1 + 1, " \
12871                               "but is $first_rec"
12872         done
12873 }
12874 run_test 160g "changelog garbage collect (old users)"
12875
12876 test_160h() {
12877         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12878         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12879                 skip "Need MDS version at least 2.10.56"
12880
12881         local mdts=$(comma_list $(mdts_nodes))
12882
12883         # Create a user
12884         changelog_register || error "first changelog_register failed"
12885         changelog_register || error "second changelog_register failed"
12886         local cl_users
12887         declare -A cl_user1
12888         declare -A cl_user2
12889         local user_rec1
12890         local user_rec2
12891         local i
12892
12893         # generate some changelog records to accumulate on each MDT
12894         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12895         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12896                 error "create $DIR/$tdir/$tfile failed"
12897
12898         # check changelogs have been generated
12899         local nbcl=$(changelog_dump | wc -l)
12900         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12901
12902         for param in "changelog_max_idle_time=10" \
12903                      "changelog_gc=1" \
12904                      "changelog_min_gc_interval=2"; do
12905                 local MDT0=$(facet_svc $SINGLEMDS)
12906                 local var="${param%=*}"
12907                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12908
12909                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12910                 do_nodes $mdts $LCTL set_param mdd.*.$param
12911         done
12912
12913         # force cl_user2 to be idle (1st part)
12914         sleep 9
12915
12916         for i in $(seq $MDSCOUNT); do
12917                 cl_users=(${CL_USERS[mds$i]})
12918                 cl_user1[mds$i]="${cl_users[0]}"
12919                 cl_user2[mds$i]="${cl_users[1]}"
12920
12921                 [ -n "${cl_user1[mds$i]}" ] ||
12922                         error "mds$i: no user registered"
12923                 [ -n "${cl_user2[mds$i]}" ] ||
12924                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12925
12926                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12927                 [ -n "$user_rec1" ] ||
12928                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12929                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12930                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12931                 [ -n "$user_rec2" ] ||
12932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12933                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12934                      "$user_rec1 + 2 == $user_rec2"
12935                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12936                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12937                               "$user_rec1 + 2, but is $user_rec2"
12938                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12939                 [ -n "$user_rec2" ] ||
12940                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12941                 [ $user_rec1 == $user_rec2 ] ||
12942                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12943                               "$user_rec1, but is $user_rec2"
12944         done
12945
12946         # force cl_user2 to be idle (2nd part) and to reach
12947         # changelog_max_idle_time
12948         sleep 2
12949
12950         # force each GC-thread start and block then
12951         # one per MDT/MDD, set fail_val accordingly
12952         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12953         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12954
12955         # generate more changelogs to trigger fail_loc
12956         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12957                 error "create $DIR/$tdir/${tfile}bis failed"
12958
12959         # stop MDT to stop GC-thread, should be done in back-ground as it will
12960         # block waiting for the thread to be released and exit
12961         declare -A stop_pids
12962         for i in $(seq $MDSCOUNT); do
12963                 stop mds$i &
12964                 stop_pids[mds$i]=$!
12965         done
12966
12967         for i in $(mdts_nodes); do
12968                 local facet
12969                 local nb=0
12970                 local facets=$(facets_up_on_host $i)
12971
12972                 for facet in ${facets//,/ }; do
12973                         if [[ $facet == mds* ]]; then
12974                                 nb=$((nb + 1))
12975                         fi
12976                 done
12977                 # ensure each MDS's gc threads are still present and all in "R"
12978                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12979                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12980                         error "$i: expected $nb GC-thread"
12981                 wait_update $i \
12982                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12983                         "R" 20 ||
12984                         error "$i: GC-thread not found in R-state"
12985                 # check umounts of each MDT on MDS have reached kthread_stop()
12986                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12987                         error "$i: expected $nb umount"
12988                 wait_update $i \
12989                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12990                         error "$i: umount not found in D-state"
12991         done
12992
12993         # release all GC-threads
12994         do_nodes $mdts $LCTL set_param fail_loc=0
12995
12996         # wait for MDT stop to complete
12997         for i in $(seq $MDSCOUNT); do
12998                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12999         done
13000
13001         # XXX
13002         # may try to check if any orphan changelog records are present
13003         # via ldiskfs/zfs and llog_reader...
13004
13005         # re-start/mount MDTs
13006         for i in $(seq $MDSCOUNT); do
13007                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13008                         error "Fail to start mds$i"
13009         done
13010
13011         local first_rec
13012         for i in $(seq $MDSCOUNT); do
13013                 # check cl_user1 still registered
13014                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13015                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13016                 # check cl_user2 unregistered
13017                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13018                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13019
13020                 # check changelogs are present and starting at $user_rec1 + 1
13021                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13022                 [ -n "$user_rec1" ] ||
13023                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13024                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13025                             awk '{ print $1; exit; }')
13026
13027                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13028                 [ $((user_rec1 + 1)) == $first_rec ] ||
13029                         error "mds$i: first index should be $user_rec1 + 1, " \
13030                               "but is $first_rec"
13031         done
13032 }
13033 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13034               "during mount"
13035
13036 test_160i() {
13037
13038         local mdts=$(comma_list $(mdts_nodes))
13039
13040         changelog_register || error "first changelog_register failed"
13041
13042         # generate some changelog records to accumulate on each MDT
13043         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13044         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13045                 error "create $DIR/$tdir/$tfile failed"
13046
13047         # check changelogs have been generated
13048         local nbcl=$(changelog_dump | wc -l)
13049         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13050
13051         # simulate race between register and unregister
13052         # XXX as fail_loc is set per-MDS, with DNE configs the race
13053         # simulation will only occur for one MDT per MDS and for the
13054         # others the normal race scenario will take place
13055         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13056         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13057         do_nodes $mdts $LCTL set_param fail_val=1
13058
13059         # unregister 1st user
13060         changelog_deregister &
13061         local pid1=$!
13062         # wait some time for deregister work to reach race rdv
13063         sleep 2
13064         # register 2nd user
13065         changelog_register || error "2nd user register failed"
13066
13067         wait $pid1 || error "1st user deregister failed"
13068
13069         local i
13070         local last_rec
13071         declare -A LAST_REC
13072         for i in $(seq $MDSCOUNT); do
13073                 if changelog_users mds$i | grep "^cl"; then
13074                         # make sure new records are added with one user present
13075                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13076                                           awk '/^current.index:/ { print $NF }')
13077                 else
13078                         error "mds$i has no user registered"
13079                 fi
13080         done
13081
13082         # generate more changelog records to accumulate on each MDT
13083         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13084                 error "create $DIR/$tdir/${tfile}bis failed"
13085
13086         for i in $(seq $MDSCOUNT); do
13087                 last_rec=$(changelog_users $SINGLEMDS |
13088                            awk '/^current.index:/ { print $NF }')
13089                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13090                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13091                         error "changelogs are off on mds$i"
13092         done
13093 }
13094 run_test 160i "changelog user register/unregister race"
13095
13096 test_161a() {
13097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13098
13099         test_mkdir -c1 $DIR/$tdir
13100         cp /etc/hosts $DIR/$tdir/$tfile
13101         test_mkdir -c1 $DIR/$tdir/foo1
13102         test_mkdir -c1 $DIR/$tdir/foo2
13103         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13104         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13105         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13106         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13107         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13108         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13109                 $LFS fid2path $DIR $FID
13110                 error "bad link ea"
13111         fi
13112         # middle
13113         rm $DIR/$tdir/foo2/zachary
13114         # last
13115         rm $DIR/$tdir/foo2/thor
13116         # first
13117         rm $DIR/$tdir/$tfile
13118         # rename
13119         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13120         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13121                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13122         rm $DIR/$tdir/foo2/maggie
13123
13124         # overflow the EA
13125         local longname=$tfile.avg_len_is_thirty_two_
13126         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13127                 error_noexit 'failed to unlink many hardlinks'" EXIT
13128         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13129                 error "failed to hardlink many files"
13130         links=$($LFS fid2path $DIR $FID | wc -l)
13131         echo -n "${links}/1000 links in link EA"
13132         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13133 }
13134 run_test 161a "link ea sanity"
13135
13136 test_161b() {
13137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13138         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13139
13140         local MDTIDX=1
13141         local remote_dir=$DIR/$tdir/remote_dir
13142
13143         mkdir -p $DIR/$tdir
13144         $LFS mkdir -i $MDTIDX $remote_dir ||
13145                 error "create remote directory failed"
13146
13147         cp /etc/hosts $remote_dir/$tfile
13148         mkdir -p $remote_dir/foo1
13149         mkdir -p $remote_dir/foo2
13150         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13151         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13152         ln $remote_dir/$tfile $remote_dir/foo1/luna
13153         ln $remote_dir/$tfile $remote_dir/foo2/thor
13154
13155         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13156                      tr -d ']')
13157         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13158                 $LFS fid2path $DIR $FID
13159                 error "bad link ea"
13160         fi
13161         # middle
13162         rm $remote_dir/foo2/zachary
13163         # last
13164         rm $remote_dir/foo2/thor
13165         # first
13166         rm $remote_dir/$tfile
13167         # rename
13168         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13169         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13170         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13171                 $LFS fid2path $DIR $FID
13172                 error "bad link rename"
13173         fi
13174         rm $remote_dir/foo2/maggie
13175
13176         # overflow the EA
13177         local longname=filename_avg_len_is_thirty_two_
13178         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13179                 error "failed to hardlink many files"
13180         links=$($LFS fid2path $DIR $FID | wc -l)
13181         echo -n "${links}/1000 links in link EA"
13182         [[ ${links} -gt 60 ]] ||
13183                 error "expected at least 60 links in link EA"
13184         unlinkmany $remote_dir/foo2/$longname 1000 ||
13185         error "failed to unlink many hardlinks"
13186 }
13187 run_test 161b "link ea sanity under remote directory"
13188
13189 test_161c() {
13190         remote_mds_nodsh && skip "remote MDS with nodsh"
13191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13192         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13193                 skip "Need MDS version at least 2.1.5"
13194
13195         # define CLF_RENAME_LAST 0x0001
13196         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13197         changelog_register || error "changelog_register failed"
13198
13199         rm -rf $DIR/$tdir
13200         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13201         touch $DIR/$tdir/foo_161c
13202         touch $DIR/$tdir/bar_161c
13203         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13204         changelog_dump | grep RENME | tail -n 5
13205         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13206         changelog_clear 0 || error "changelog_clear failed"
13207         if [ x$flags != "x0x1" ]; then
13208                 error "flag $flags is not 0x1"
13209         fi
13210
13211         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13212         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13213         touch $DIR/$tdir/foo_161c
13214         touch $DIR/$tdir/bar_161c
13215         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13216         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13217         changelog_dump | grep RENME | tail -n 5
13218         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13219         changelog_clear 0 || error "changelog_clear failed"
13220         if [ x$flags != "x0x0" ]; then
13221                 error "flag $flags is not 0x0"
13222         fi
13223         echo "rename overwrite a target having nlink > 1," \
13224                 "changelog record has flags of $flags"
13225
13226         # rename doesn't overwrite a target (changelog flag 0x0)
13227         touch $DIR/$tdir/foo_161c
13228         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13229         changelog_dump | grep RENME | tail -n 5
13230         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13231         changelog_clear 0 || error "changelog_clear failed"
13232         if [ x$flags != "x0x0" ]; then
13233                 error "flag $flags is not 0x0"
13234         fi
13235         echo "rename doesn't overwrite a target," \
13236                 "changelog record has flags of $flags"
13237
13238         # define CLF_UNLINK_LAST 0x0001
13239         # unlink a file having nlink = 1 (changelog flag 0x1)
13240         rm -f $DIR/$tdir/foo2_161c
13241         changelog_dump | grep UNLNK | tail -n 5
13242         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13243         changelog_clear 0 || error "changelog_clear failed"
13244         if [ x$flags != "x0x1" ]; then
13245                 error "flag $flags is not 0x1"
13246         fi
13247         echo "unlink a file having nlink = 1," \
13248                 "changelog record has flags of $flags"
13249
13250         # unlink a file having nlink > 1 (changelog flag 0x0)
13251         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13252         rm -f $DIR/$tdir/foobar_161c
13253         changelog_dump | grep UNLNK | tail -n 5
13254         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13255         changelog_clear 0 || error "changelog_clear failed"
13256         if [ x$flags != "x0x0" ]; then
13257                 error "flag $flags is not 0x0"
13258         fi
13259         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13260 }
13261 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13262
13263 test_161d() {
13264         remote_mds_nodsh && skip "remote MDS with nodsh"
13265         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13266
13267         local pid
13268         local fid
13269
13270         changelog_register || error "changelog_register failed"
13271
13272         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13273         # interfer with $MOUNT/.lustre/fid/ access
13274         mkdir $DIR/$tdir
13275         [[ $? -eq 0 ]] || error "mkdir failed"
13276
13277         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13278         $LCTL set_param fail_loc=0x8000140c
13279         # 5s pause
13280         $LCTL set_param fail_val=5
13281
13282         # create file
13283         echo foofoo > $DIR/$tdir/$tfile &
13284         pid=$!
13285
13286         # wait for create to be delayed
13287         sleep 2
13288
13289         ps -p $pid
13290         [[ $? -eq 0 ]] || error "create should be blocked"
13291
13292         local tempfile=$(mktemp)
13293         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13294         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13295         # some delay may occur during ChangeLog publishing and file read just
13296         # above, that could allow file write to happen finally
13297         [[ -s $tempfile ]] && echo "file should be empty"
13298
13299         $LCTL set_param fail_loc=0
13300
13301         wait $pid
13302         [[ $? -eq 0 ]] || error "create failed"
13303 }
13304 run_test 161d "create with concurrent .lustre/fid access"
13305
13306 check_path() {
13307         local expected="$1"
13308         shift
13309         local fid="$2"
13310
13311         local path
13312         path=$($LFS fid2path "$@")
13313         local rc=$?
13314
13315         if [ $rc -ne 0 ]; then
13316                 error "path looked up of '$expected' failed: rc=$rc"
13317         elif [ "$path" != "$expected" ]; then
13318                 error "path looked up '$path' instead of '$expected'"
13319         else
13320                 echo "FID '$fid' resolves to path '$path' as expected"
13321         fi
13322 }
13323
13324 test_162a() { # was test_162
13325         test_mkdir -p -c1 $DIR/$tdir/d2
13326         touch $DIR/$tdir/d2/$tfile
13327         touch $DIR/$tdir/d2/x1
13328         touch $DIR/$tdir/d2/x2
13329         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13330         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13331         # regular file
13332         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13333         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13334
13335         # softlink
13336         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13337         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13338         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13339
13340         # softlink to wrong file
13341         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13342         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13343         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13344
13345         # hardlink
13346         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13347         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13348         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13349         # fid2path dir/fsname should both work
13350         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13351         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13352
13353         # hardlink count: check that there are 2 links
13354         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13355         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13356
13357         # hardlink indexing: remove the first link
13358         rm $DIR/$tdir/d2/p/q/r/hlink
13359         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13360 }
13361 run_test 162a "path lookup sanity"
13362
13363 test_162b() {
13364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13366
13367         mkdir $DIR/$tdir
13368         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13369                                 error "create striped dir failed"
13370
13371         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13372                                         tail -n 1 | awk '{print $2}')
13373         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13374
13375         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13376         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13377
13378         # regular file
13379         for ((i=0;i<5;i++)); do
13380                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13381                         error "get fid for f$i failed"
13382                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13383
13384                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13385                         error "get fid for d$i failed"
13386                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13387         done
13388
13389         return 0
13390 }
13391 run_test 162b "striped directory path lookup sanity"
13392
13393 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13394 test_162c() {
13395         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13396                 skip "Need MDS version at least 2.7.51"
13397
13398         local lpath=$tdir.local
13399         local rpath=$tdir.remote
13400
13401         test_mkdir $DIR/$lpath
13402         test_mkdir $DIR/$rpath
13403
13404         for ((i = 0; i <= 101; i++)); do
13405                 lpath="$lpath/$i"
13406                 mkdir $DIR/$lpath
13407                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13408                         error "get fid for local directory $DIR/$lpath failed"
13409                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13410
13411                 rpath="$rpath/$i"
13412                 test_mkdir $DIR/$rpath
13413                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13414                         error "get fid for remote directory $DIR/$rpath failed"
13415                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13416         done
13417
13418         return 0
13419 }
13420 run_test 162c "fid2path works with paths 100 or more directories deep"
13421
13422 test_169() {
13423         # do directio so as not to populate the page cache
13424         log "creating a 10 Mb file"
13425         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13426         log "starting reads"
13427         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13428         log "truncating the file"
13429         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13430         log "killing dd"
13431         kill %+ || true # reads might have finished
13432         echo "wait until dd is finished"
13433         wait
13434         log "removing the temporary file"
13435         rm -rf $DIR/$tfile || error "tmp file removal failed"
13436 }
13437 run_test 169 "parallel read and truncate should not deadlock"
13438
13439 test_170() {
13440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13441
13442         $LCTL clear     # bug 18514
13443         $LCTL debug_daemon start $TMP/${tfile}_log_good
13444         touch $DIR/$tfile
13445         $LCTL debug_daemon stop
13446         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13447                 error "sed failed to read log_good"
13448
13449         $LCTL debug_daemon start $TMP/${tfile}_log_good
13450         rm -rf $DIR/$tfile
13451         $LCTL debug_daemon stop
13452
13453         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13454                error "lctl df log_bad failed"
13455
13456         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13457         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13458
13459         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13460         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13461
13462         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13463                 error "bad_line good_line1 good_line2 are empty"
13464
13465         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13466         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13467         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13468
13469         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13470         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13471         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13472
13473         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13474                 error "bad_line_new good_line_new are empty"
13475
13476         local expected_good=$((good_line1 + good_line2*2))
13477
13478         rm -f $TMP/${tfile}*
13479         # LU-231, short malformed line may not be counted into bad lines
13480         if [ $bad_line -ne $bad_line_new ] &&
13481                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13482                 error "expected $bad_line bad lines, but got $bad_line_new"
13483                 return 1
13484         fi
13485
13486         if [ $expected_good -ne $good_line_new ]; then
13487                 error "expected $expected_good good lines, but got $good_line_new"
13488                 return 2
13489         fi
13490         true
13491 }
13492 run_test 170 "test lctl df to handle corrupted log ====================="
13493
13494 test_171() { # bug20592
13495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13496
13497         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13498         $LCTL set_param fail_loc=0x50e
13499         $LCTL set_param fail_val=3000
13500         multiop_bg_pause $DIR/$tfile O_s || true
13501         local MULTIPID=$!
13502         kill -USR1 $MULTIPID
13503         # cause log dump
13504         sleep 3
13505         wait $MULTIPID
13506         if dmesg | grep "recursive fault"; then
13507                 error "caught a recursive fault"
13508         fi
13509         $LCTL set_param fail_loc=0
13510         true
13511 }
13512 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13513
13514 # it would be good to share it with obdfilter-survey/iokit-libecho code
13515 setup_obdecho_osc () {
13516         local rc=0
13517         local ost_nid=$1
13518         local obdfilter_name=$2
13519         echo "Creating new osc for $obdfilter_name on $ost_nid"
13520         # make sure we can find loopback nid
13521         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13522
13523         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13524                            ${obdfilter_name}_osc_UUID || rc=2; }
13525         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13526                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13527         return $rc
13528 }
13529
13530 cleanup_obdecho_osc () {
13531         local obdfilter_name=$1
13532         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13533         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13534         return 0
13535 }
13536
13537 obdecho_test() {
13538         local OBD=$1
13539         local node=$2
13540         local pages=${3:-64}
13541         local rc=0
13542         local id
13543
13544         local count=10
13545         local obd_size=$(get_obd_size $node $OBD)
13546         local page_size=$(get_page_size $node)
13547         if [[ -n "$obd_size" ]]; then
13548                 local new_count=$((obd_size / (pages * page_size / 1024)))
13549                 [[ $new_count -ge $count ]] || count=$new_count
13550         fi
13551
13552         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13553         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13554                            rc=2; }
13555         if [ $rc -eq 0 ]; then
13556             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13557             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13558         fi
13559         echo "New object id is $id"
13560         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13561                            rc=4; }
13562         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13563                            "test_brw $count w v $pages $id" || rc=4; }
13564         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13565                            rc=4; }
13566         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
13567                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
13568         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
13569                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
13570         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13571         return $rc
13572 }
13573
13574 test_180a() {
13575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13576
13577         if ! module_loaded obdecho; then
13578                 load_module obdecho/obdecho &&
13579                         stack_trap "rmmod obdecho" EXIT ||
13580                         error "unable to load obdecho on client"
13581         fi
13582
13583         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13584         local host=$($LCTL get_param -n osc.$osc.import |
13585                      awk '/current_connection:/ { print $2 }' )
13586         local target=$($LCTL get_param -n osc.$osc.import |
13587                        awk '/target:/ { print $2 }' )
13588         target=${target%_UUID}
13589
13590         if [ -n "$target" ]; then
13591                 setup_obdecho_osc $host $target &&
13592                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13593                         { error "obdecho setup failed with $?"; return; }
13594
13595                 obdecho_test ${target}_osc client ||
13596                         error "obdecho_test failed on ${target}_osc"
13597         else
13598                 $LCTL get_param osc.$osc.import
13599                 error "there is no osc.$osc.import target"
13600         fi
13601 }
13602 run_test 180a "test obdecho on osc"
13603
13604 test_180b() {
13605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13606         remote_ost_nodsh && skip "remote OST with nodsh"
13607
13608         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13609                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13610                 error "failed to load module obdecho"
13611
13612         local target=$(do_facet ost1 $LCTL dl |
13613                        awk '/obdfilter/ { print $4; exit; }')
13614
13615         if [ -n "$target" ]; then
13616                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13617         else
13618                 do_facet ost1 $LCTL dl
13619                 error "there is no obdfilter target on ost1"
13620         fi
13621 }
13622 run_test 180b "test obdecho directly on obdfilter"
13623
13624 test_180c() { # LU-2598
13625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13626         remote_ost_nodsh && skip "remote OST with nodsh"
13627         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13628                 skip "Need MDS version at least 2.4.0"
13629
13630         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13631                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13632                 error "failed to load module obdecho"
13633
13634         local target=$(do_facet ost1 $LCTL dl |
13635                        awk '/obdfilter/ { print $4; exit; }')
13636
13637         if [ -n "$target" ]; then
13638                 local pages=16384 # 64MB bulk I/O RPC size
13639
13640                 obdecho_test "$target" ost1 "$pages" ||
13641                         error "obdecho_test with pages=$pages failed with $?"
13642         else
13643                 do_facet ost1 $LCTL dl
13644                 error "there is no obdfilter target on ost1"
13645         fi
13646 }
13647 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13648
13649 test_181() { # bug 22177
13650         test_mkdir $DIR/$tdir
13651         # create enough files to index the directory
13652         createmany -o $DIR/$tdir/foobar 4000
13653         # print attributes for debug purpose
13654         lsattr -d .
13655         # open dir
13656         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13657         MULTIPID=$!
13658         # remove the files & current working dir
13659         unlinkmany $DIR/$tdir/foobar 4000
13660         rmdir $DIR/$tdir
13661         kill -USR1 $MULTIPID
13662         wait $MULTIPID
13663         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13664         return 0
13665 }
13666 run_test 181 "Test open-unlinked dir ========================"
13667
13668 test_182() {
13669         local fcount=1000
13670         local tcount=10
13671
13672         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13673
13674         $LCTL set_param mdc.*.rpc_stats=clear
13675
13676         for (( i = 0; i < $tcount; i++ )) ; do
13677                 mkdir $DIR/$tdir/$i
13678         done
13679
13680         for (( i = 0; i < $tcount; i++ )) ; do
13681                 createmany -o $DIR/$tdir/$i/f- $fcount &
13682         done
13683         wait
13684
13685         for (( i = 0; i < $tcount; i++ )) ; do
13686                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13687         done
13688         wait
13689
13690         $LCTL get_param mdc.*.rpc_stats
13691
13692         rm -rf $DIR/$tdir
13693 }
13694 run_test 182 "Test parallel modify metadata operations ================"
13695
13696 test_183() { # LU-2275
13697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13698         remote_mds_nodsh && skip "remote MDS with nodsh"
13699         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13700                 skip "Need MDS version at least 2.3.56"
13701
13702         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13703         echo aaa > $DIR/$tdir/$tfile
13704
13705 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13706         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13707
13708         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13709         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13710
13711         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13712
13713         # Flush negative dentry cache
13714         touch $DIR/$tdir/$tfile
13715
13716         # We are not checking for any leaked references here, they'll
13717         # become evident next time we do cleanup with module unload.
13718         rm -rf $DIR/$tdir
13719 }
13720 run_test 183 "No crash or request leak in case of strange dispositions ========"
13721
13722 # test suite 184 is for LU-2016, LU-2017
13723 test_184a() {
13724         check_swap_layouts_support
13725
13726         dir0=$DIR/$tdir/$testnum
13727         test_mkdir -p -c1 $dir0
13728         ref1=/etc/passwd
13729         ref2=/etc/group
13730         file1=$dir0/f1
13731         file2=$dir0/f2
13732         $LFS setstripe -c1 $file1
13733         cp $ref1 $file1
13734         $LFS setstripe -c2 $file2
13735         cp $ref2 $file2
13736         gen1=$($LFS getstripe -g $file1)
13737         gen2=$($LFS getstripe -g $file2)
13738
13739         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13740         gen=$($LFS getstripe -g $file1)
13741         [[ $gen1 != $gen ]] ||
13742                 "Layout generation on $file1 does not change"
13743         gen=$($LFS getstripe -g $file2)
13744         [[ $gen2 != $gen ]] ||
13745                 "Layout generation on $file2 does not change"
13746
13747         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13748         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13749
13750         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13751 }
13752 run_test 184a "Basic layout swap"
13753
13754 test_184b() {
13755         check_swap_layouts_support
13756
13757         dir0=$DIR/$tdir/$testnum
13758         mkdir -p $dir0 || error "creating dir $dir0"
13759         file1=$dir0/f1
13760         file2=$dir0/f2
13761         file3=$dir0/f3
13762         dir1=$dir0/d1
13763         dir2=$dir0/d2
13764         mkdir $dir1 $dir2
13765         $LFS setstripe -c1 $file1
13766         $LFS setstripe -c2 $file2
13767         $LFS setstripe -c1 $file3
13768         chown $RUNAS_ID $file3
13769         gen1=$($LFS getstripe -g $file1)
13770         gen2=$($LFS getstripe -g $file2)
13771
13772         $LFS swap_layouts $dir1 $dir2 &&
13773                 error "swap of directories layouts should fail"
13774         $LFS swap_layouts $dir1 $file1 &&
13775                 error "swap of directory and file layouts should fail"
13776         $RUNAS $LFS swap_layouts $file1 $file2 &&
13777                 error "swap of file we cannot write should fail"
13778         $LFS swap_layouts $file1 $file3 &&
13779                 error "swap of file with different owner should fail"
13780         /bin/true # to clear error code
13781 }
13782 run_test 184b "Forbidden layout swap (will generate errors)"
13783
13784 test_184c() {
13785         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13786         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13787         check_swap_layouts_support
13788
13789         local dir0=$DIR/$tdir/$testnum
13790         mkdir -p $dir0 || error "creating dir $dir0"
13791
13792         local ref1=$dir0/ref1
13793         local ref2=$dir0/ref2
13794         local file1=$dir0/file1
13795         local file2=$dir0/file2
13796         # create a file large enough for the concurrent test
13797         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13798         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13799         echo "ref file size: ref1($(stat -c %s $ref1))," \
13800              "ref2($(stat -c %s $ref2))"
13801
13802         cp $ref2 $file2
13803         dd if=$ref1 of=$file1 bs=16k &
13804         local DD_PID=$!
13805
13806         # Make sure dd starts to copy file
13807         while [ ! -f $file1 ]; do sleep 0.1; done
13808
13809         $LFS swap_layouts $file1 $file2
13810         local rc=$?
13811         wait $DD_PID
13812         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13813         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13814
13815         # how many bytes copied before swapping layout
13816         local copied=$(stat -c %s $file2)
13817         local remaining=$(stat -c %s $ref1)
13818         remaining=$((remaining - copied))
13819         echo "Copied $copied bytes before swapping layout..."
13820
13821         cmp -n $copied $file1 $ref2 | grep differ &&
13822                 error "Content mismatch [0, $copied) of ref2 and file1"
13823         cmp -n $copied $file2 $ref1 ||
13824                 error "Content mismatch [0, $copied) of ref1 and file2"
13825         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13826                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13827
13828         # clean up
13829         rm -f $ref1 $ref2 $file1 $file2
13830 }
13831 run_test 184c "Concurrent write and layout swap"
13832
13833 test_184d() {
13834         check_swap_layouts_support
13835         [ -z "$(which getfattr 2>/dev/null)" ] &&
13836                 skip_env "no getfattr command"
13837
13838         local file1=$DIR/$tdir/$tfile-1
13839         local file2=$DIR/$tdir/$tfile-2
13840         local file3=$DIR/$tdir/$tfile-3
13841         local lovea1
13842         local lovea2
13843
13844         mkdir -p $DIR/$tdir
13845         touch $file1 || error "create $file1 failed"
13846         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13847                 error "create $file2 failed"
13848         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13849                 error "create $file3 failed"
13850         lovea1=$(get_layout_param $file1)
13851
13852         $LFS swap_layouts $file2 $file3 ||
13853                 error "swap $file2 $file3 layouts failed"
13854         $LFS swap_layouts $file1 $file2 ||
13855                 error "swap $file1 $file2 layouts failed"
13856
13857         lovea2=$(get_layout_param $file2)
13858         echo "$lovea1"
13859         echo "$lovea2"
13860         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13861
13862         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13863         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13864 }
13865 run_test 184d "allow stripeless layouts swap"
13866
13867 test_184e() {
13868         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13869                 skip "Need MDS version at least 2.6.94"
13870         check_swap_layouts_support
13871         [ -z "$(which getfattr 2>/dev/null)" ] &&
13872                 skip_env "no getfattr command"
13873
13874         local file1=$DIR/$tdir/$tfile-1
13875         local file2=$DIR/$tdir/$tfile-2
13876         local file3=$DIR/$tdir/$tfile-3
13877         local lovea
13878
13879         mkdir -p $DIR/$tdir
13880         touch $file1 || error "create $file1 failed"
13881         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13882                 error "create $file2 failed"
13883         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13884                 error "create $file3 failed"
13885
13886         $LFS swap_layouts $file1 $file2 ||
13887                 error "swap $file1 $file2 layouts failed"
13888
13889         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13890         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13891
13892         echo 123 > $file1 || error "Should be able to write into $file1"
13893
13894         $LFS swap_layouts $file1 $file3 ||
13895                 error "swap $file1 $file3 layouts failed"
13896
13897         echo 123 > $file1 || error "Should be able to write into $file1"
13898
13899         rm -rf $file1 $file2 $file3
13900 }
13901 run_test 184e "Recreate layout after stripeless layout swaps"
13902
13903 test_184f() {
13904         # Create a file with name longer than sizeof(struct stat) ==
13905         # 144 to see if we can get chars from the file name to appear
13906         # in the returned striping. Note that 'f' == 0x66.
13907         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13908
13909         mkdir -p $DIR/$tdir
13910         mcreate $DIR/$tdir/$file
13911         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13912                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13913         fi
13914 }
13915 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13916
13917 test_185() { # LU-2441
13918         # LU-3553 - no volatile file support in old servers
13919         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13920                 skip "Need MDS version at least 2.3.60"
13921
13922         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13923         touch $DIR/$tdir/spoo
13924         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13925         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13926                 error "cannot create/write a volatile file"
13927         [ "$FILESET" == "" ] &&
13928         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13929                 error "FID is still valid after close"
13930
13931         multiop_bg_pause $DIR/$tdir vVw4096_c
13932         local multi_pid=$!
13933
13934         local OLD_IFS=$IFS
13935         IFS=":"
13936         local fidv=($fid)
13937         IFS=$OLD_IFS
13938         # assume that the next FID for this client is sequential, since stdout
13939         # is unfortunately eaten by multiop_bg_pause
13940         local n=$((${fidv[1]} + 1))
13941         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13942         if [ "$FILESET" == "" ]; then
13943                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13944                         error "FID is missing before close"
13945         fi
13946         kill -USR1 $multi_pid
13947         # 1 second delay, so if mtime change we will see it
13948         sleep 1
13949         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13950         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13951 }
13952 run_test 185 "Volatile file support"
13953
13954 test_187a() {
13955         remote_mds_nodsh && skip "remote MDS with nodsh"
13956         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13957                 skip "Need MDS version at least 2.3.0"
13958
13959         local dir0=$DIR/$tdir/$testnum
13960         mkdir -p $dir0 || error "creating dir $dir0"
13961
13962         local file=$dir0/file1
13963         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13964         local dv1=$($LFS data_version $file)
13965         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13966         local dv2=$($LFS data_version $file)
13967         [[ $dv1 != $dv2 ]] ||
13968                 error "data version did not change on write $dv1 == $dv2"
13969
13970         # clean up
13971         rm -f $file1
13972 }
13973 run_test 187a "Test data version change"
13974
13975 test_187b() {
13976         remote_mds_nodsh && skip "remote MDS with nodsh"
13977         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13978                 skip "Need MDS version at least 2.3.0"
13979
13980         local dir0=$DIR/$tdir/$testnum
13981         mkdir -p $dir0 || error "creating dir $dir0"
13982
13983         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13984         [[ ${DV[0]} != ${DV[1]} ]] ||
13985                 error "data version did not change on write"\
13986                       " ${DV[0]} == ${DV[1]}"
13987
13988         # clean up
13989         rm -f $file1
13990 }
13991 run_test 187b "Test data version change on volatile file"
13992
13993 test_200() {
13994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13995         remote_mgs_nodsh && skip "remote MGS with nodsh"
13996         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13997
13998         local POOL=${POOL:-cea1}
13999         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14000         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14001         # Pool OST targets
14002         local first_ost=0
14003         local last_ost=$(($OSTCOUNT - 1))
14004         local ost_step=2
14005         local ost_list=$(seq $first_ost $ost_step $last_ost)
14006         local ost_range="$first_ost $last_ost $ost_step"
14007         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14008         local file_dir=$POOL_ROOT/file_tst
14009         local subdir=$test_path/subdir
14010         local rc=0
14011
14012         if ! combined_mgs_mds ; then
14013                 mount_mgs_client
14014         fi
14015
14016         while : ; do
14017                 # former test_200a test_200b
14018                 pool_add $POOL                          || { rc=$? ; break; }
14019                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14020                 # former test_200c test_200d
14021                 mkdir -p $test_path
14022                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14023                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14024                 mkdir -p $subdir
14025                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14026                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14027                                                         || { rc=$? ; break; }
14028                 # former test_200e test_200f
14029                 local files=$((OSTCOUNT*3))
14030                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14031                                                         || { rc=$? ; break; }
14032                 pool_create_files $POOL $file_dir $files "$ost_list" \
14033                                                         || { rc=$? ; break; }
14034                 # former test_200g test_200h
14035                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14036                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14037
14038                 # former test_201a test_201b test_201c
14039                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14040
14041                 local f=$test_path/$tfile
14042                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14043                 pool_remove $POOL $f                    || { rc=$? ; break; }
14044                 break
14045         done
14046
14047         destroy_test_pools
14048
14049         if ! combined_mgs_mds ; then
14050                 umount_mgs_client
14051         fi
14052         return $rc
14053 }
14054 run_test 200 "OST pools"
14055
14056 # usage: default_attr <count | size | offset>
14057 default_attr() {
14058         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14059 }
14060
14061 # usage: check_default_stripe_attr
14062 check_default_stripe_attr() {
14063         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14064         case $1 in
14065         --stripe-count|-c)
14066                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14067         --stripe-size|-S)
14068                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14069         --stripe-index|-i)
14070                 EXPECTED=-1;;
14071         *)
14072                 error "unknown getstripe attr '$1'"
14073         esac
14074
14075         [ $ACTUAL == $EXPECTED ] ||
14076                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14077 }
14078
14079 test_204a() {
14080         test_mkdir $DIR/$tdir
14081         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14082
14083         check_default_stripe_attr --stripe-count
14084         check_default_stripe_attr --stripe-size
14085         check_default_stripe_attr --stripe-index
14086 }
14087 run_test 204a "Print default stripe attributes"
14088
14089 test_204b() {
14090         test_mkdir $DIR/$tdir
14091         $LFS setstripe --stripe-count 1 $DIR/$tdir
14092
14093         check_default_stripe_attr --stripe-size
14094         check_default_stripe_attr --stripe-index
14095 }
14096 run_test 204b "Print default stripe size and offset"
14097
14098 test_204c() {
14099         test_mkdir $DIR/$tdir
14100         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14101
14102         check_default_stripe_attr --stripe-count
14103         check_default_stripe_attr --stripe-index
14104 }
14105 run_test 204c "Print default stripe count and offset"
14106
14107 test_204d() {
14108         test_mkdir $DIR/$tdir
14109         $LFS setstripe --stripe-index 0 $DIR/$tdir
14110
14111         check_default_stripe_attr --stripe-count
14112         check_default_stripe_attr --stripe-size
14113 }
14114 run_test 204d "Print default stripe count and size"
14115
14116 test_204e() {
14117         test_mkdir $DIR/$tdir
14118         $LFS setstripe -d $DIR/$tdir
14119
14120         check_default_stripe_attr --stripe-count --raw
14121         check_default_stripe_attr --stripe-size --raw
14122         check_default_stripe_attr --stripe-index --raw
14123 }
14124 run_test 204e "Print raw stripe attributes"
14125
14126 test_204f() {
14127         test_mkdir $DIR/$tdir
14128         $LFS setstripe --stripe-count 1 $DIR/$tdir
14129
14130         check_default_stripe_attr --stripe-size --raw
14131         check_default_stripe_attr --stripe-index --raw
14132 }
14133 run_test 204f "Print raw stripe size and offset"
14134
14135 test_204g() {
14136         test_mkdir $DIR/$tdir
14137         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14138
14139         check_default_stripe_attr --stripe-count --raw
14140         check_default_stripe_attr --stripe-index --raw
14141 }
14142 run_test 204g "Print raw stripe count and offset"
14143
14144 test_204h() {
14145         test_mkdir $DIR/$tdir
14146         $LFS setstripe --stripe-index 0 $DIR/$tdir
14147
14148         check_default_stripe_attr --stripe-count --raw
14149         check_default_stripe_attr --stripe-size --raw
14150 }
14151 run_test 204h "Print raw stripe count and size"
14152
14153 # Figure out which job scheduler is being used, if any,
14154 # or use a fake one
14155 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14156         JOBENV=SLURM_JOB_ID
14157 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14158         JOBENV=LSB_JOBID
14159 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14160         JOBENV=PBS_JOBID
14161 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14162         JOBENV=LOADL_STEP_ID
14163 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14164         JOBENV=JOB_ID
14165 else
14166         $LCTL list_param jobid_name > /dev/null 2>&1
14167         if [ $? -eq 0 ]; then
14168                 JOBENV=nodelocal
14169         else
14170                 JOBENV=FAKE_JOBID
14171         fi
14172 fi
14173 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14174
14175 verify_jobstats() {
14176         local cmd=($1)
14177         shift
14178         local facets="$@"
14179
14180 # we don't really need to clear the stats for this test to work, since each
14181 # command has a unique jobid, but it makes debugging easier if needed.
14182 #       for facet in $facets; do
14183 #               local dev=$(convert_facet2label $facet)
14184 #               # clear old jobstats
14185 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14186 #       done
14187
14188         # use a new JobID for each test, or we might see an old one
14189         [ "$JOBENV" = "FAKE_JOBID" ] &&
14190                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14191
14192         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14193
14194         [ "$JOBENV" = "nodelocal" ] && {
14195                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14196                 $LCTL set_param jobid_name=$FAKE_JOBID
14197                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14198         }
14199
14200         log "Test: ${cmd[*]}"
14201         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14202
14203         if [ $JOBENV = "FAKE_JOBID" ]; then
14204                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14205         else
14206                 ${cmd[*]}
14207         fi
14208
14209         # all files are created on OST0000
14210         for facet in $facets; do
14211                 local stats="*.$(convert_facet2label $facet).job_stats"
14212
14213                 # strip out libtool wrappers for in-tree executables
14214                 if [ $(do_facet $facet lctl get_param $stats |
14215                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14216                         do_facet $facet lctl get_param $stats
14217                         error "No jobstats for $JOBVAL found on $facet::$stats"
14218                 fi
14219         done
14220 }
14221
14222 jobstats_set() {
14223         local new_jobenv=$1
14224
14225         set_persistent_param_and_check client "jobid_var" \
14226                 "$FSNAME.sys.jobid_var" $new_jobenv
14227 }
14228
14229 test_205() { # Job stats
14230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14231         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14232                 skip "Need MDS version with at least 2.7.1"
14233         remote_mgs_nodsh && skip "remote MGS with nodsh"
14234         remote_mds_nodsh && skip "remote MDS with nodsh"
14235         remote_ost_nodsh && skip "remote OST with nodsh"
14236         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14237                 skip "Server doesn't support jobstats"
14238         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14239
14240         local old_jobenv=$($LCTL get_param -n jobid_var)
14241         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14242
14243         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14244                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14245         else
14246                 stack_trap "do_facet mgs $PERM_CMD \
14247                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14248         fi
14249         changelog_register
14250
14251         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14252                                 mdt.*.job_cleanup_interval | head -n 1)
14253         local new_interval=5
14254         do_facet $SINGLEMDS \
14255                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14256         stack_trap "do_facet $SINGLEMDS \
14257                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14258         local start=$SECONDS
14259
14260         local cmd
14261         # mkdir
14262         cmd="mkdir $DIR/$tdir"
14263         verify_jobstats "$cmd" "$SINGLEMDS"
14264         # rmdir
14265         cmd="rmdir $DIR/$tdir"
14266         verify_jobstats "$cmd" "$SINGLEMDS"
14267         # mkdir on secondary MDT
14268         if [ $MDSCOUNT -gt 1 ]; then
14269                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14270                 verify_jobstats "$cmd" "mds2"
14271         fi
14272         # mknod
14273         cmd="mknod $DIR/$tfile c 1 3"
14274         verify_jobstats "$cmd" "$SINGLEMDS"
14275         # unlink
14276         cmd="rm -f $DIR/$tfile"
14277         verify_jobstats "$cmd" "$SINGLEMDS"
14278         # create all files on OST0000 so verify_jobstats can find OST stats
14279         # open & close
14280         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14281         verify_jobstats "$cmd" "$SINGLEMDS"
14282         # setattr
14283         cmd="touch $DIR/$tfile"
14284         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14285         # write
14286         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14287         verify_jobstats "$cmd" "ost1"
14288         # read
14289         cancel_lru_locks osc
14290         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14291         verify_jobstats "$cmd" "ost1"
14292         # truncate
14293         cmd="$TRUNCATE $DIR/$tfile 0"
14294         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14295         # rename
14296         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14297         verify_jobstats "$cmd" "$SINGLEMDS"
14298         # jobstats expiry - sleep until old stats should be expired
14299         local left=$((new_interval + 5 - (SECONDS - start)))
14300         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14301                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14302                         "0" $left
14303         cmd="mkdir $DIR/$tdir.expire"
14304         verify_jobstats "$cmd" "$SINGLEMDS"
14305         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14306             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14307
14308         # Ensure that jobid are present in changelog (if supported by MDS)
14309         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14310                 changelog_dump | tail -10
14311                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14312                 [ $jobids -eq 9 ] ||
14313                         error "Wrong changelog jobid count $jobids != 9"
14314
14315                 # LU-5862
14316                 JOBENV="disable"
14317                 jobstats_set $JOBENV
14318                 touch $DIR/$tfile
14319                 changelog_dump | grep $tfile
14320                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14321                 [ $jobids -eq 0 ] ||
14322                         error "Unexpected jobids when jobid_var=$JOBENV"
14323         fi
14324
14325         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14326         JOBENV="JOBCOMPLEX"
14327         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14328
14329         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14330 }
14331 run_test 205 "Verify job stats"
14332
14333 # LU-1480, LU-1773 and LU-1657
14334 test_206() {
14335         mkdir -p $DIR/$tdir
14336         $LFS setstripe -c -1 $DIR/$tdir
14337 #define OBD_FAIL_LOV_INIT 0x1403
14338         $LCTL set_param fail_loc=0xa0001403
14339         $LCTL set_param fail_val=1
14340         touch $DIR/$tdir/$tfile || true
14341 }
14342 run_test 206 "fail lov_init_raid0() doesn't lbug"
14343
14344 test_207a() {
14345         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14346         local fsz=`stat -c %s $DIR/$tfile`
14347         cancel_lru_locks mdc
14348
14349         # do not return layout in getattr intent
14350 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14351         $LCTL set_param fail_loc=0x170
14352         local sz=`stat -c %s $DIR/$tfile`
14353
14354         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14355
14356         rm -rf $DIR/$tfile
14357 }
14358 run_test 207a "can refresh layout at glimpse"
14359
14360 test_207b() {
14361         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14362         local cksum=`md5sum $DIR/$tfile`
14363         local fsz=`stat -c %s $DIR/$tfile`
14364         cancel_lru_locks mdc
14365         cancel_lru_locks osc
14366
14367         # do not return layout in getattr intent
14368 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14369         $LCTL set_param fail_loc=0x171
14370
14371         # it will refresh layout after the file is opened but before read issues
14372         echo checksum is "$cksum"
14373         echo "$cksum" |md5sum -c --quiet || error "file differs"
14374
14375         rm -rf $DIR/$tfile
14376 }
14377 run_test 207b "can refresh layout at open"
14378
14379 test_208() {
14380         # FIXME: in this test suite, only RD lease is used. This is okay
14381         # for now as only exclusive open is supported. After generic lease
14382         # is done, this test suite should be revised. - Jinshan
14383
14384         remote_mds_nodsh && skip "remote MDS with nodsh"
14385         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14386                 skip "Need MDS version at least 2.4.52"
14387
14388         echo "==== test 1: verify get lease work"
14389         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14390
14391         echo "==== test 2: verify lease can be broken by upcoming open"
14392         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14393         local PID=$!
14394         sleep 1
14395
14396         $MULTIOP $DIR/$tfile oO_RDONLY:c
14397         kill -USR1 $PID && wait $PID || error "break lease error"
14398
14399         echo "==== test 3: verify lease can't be granted if an open already exists"
14400         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14401         local PID=$!
14402         sleep 1
14403
14404         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14405         kill -USR1 $PID && wait $PID || error "open file error"
14406
14407         echo "==== test 4: lease can sustain over recovery"
14408         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14409         PID=$!
14410         sleep 1
14411
14412         fail mds1
14413
14414         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14415
14416         echo "==== test 5: lease broken can't be regained by replay"
14417         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14418         PID=$!
14419         sleep 1
14420
14421         # open file to break lease and then recovery
14422         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14423         fail mds1
14424
14425         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14426
14427         rm -f $DIR/$tfile
14428 }
14429 run_test 208 "Exclusive open"
14430
14431 test_209() {
14432         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14433                 skip_env "must have disp_stripe"
14434
14435         touch $DIR/$tfile
14436         sync; sleep 5; sync;
14437
14438         echo 3 > /proc/sys/vm/drop_caches
14439         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14440
14441         # open/close 500 times
14442         for i in $(seq 500); do
14443                 cat $DIR/$tfile
14444         done
14445
14446         echo 3 > /proc/sys/vm/drop_caches
14447         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14448
14449         echo "before: $req_before, after: $req_after"
14450         [ $((req_after - req_before)) -ge 300 ] &&
14451                 error "open/close requests are not freed"
14452         return 0
14453 }
14454 run_test 209 "read-only open/close requests should be freed promptly"
14455
14456 test_212() {
14457         size=`date +%s`
14458         size=$((size % 8192 + 1))
14459         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14460         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14461         rm -f $DIR/f212 $DIR/f212.xyz
14462 }
14463 run_test 212 "Sendfile test ============================================"
14464
14465 test_213() {
14466         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14467         cancel_lru_locks osc
14468         lctl set_param fail_loc=0x8000040f
14469         # generate a read lock
14470         cat $DIR/$tfile > /dev/null
14471         # write to the file, it will try to cancel the above read lock.
14472         cat /etc/hosts >> $DIR/$tfile
14473 }
14474 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14475
14476 test_214() { # for bug 20133
14477         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14478         for (( i=0; i < 340; i++ )) ; do
14479                 touch $DIR/$tdir/d214c/a$i
14480         done
14481
14482         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14483         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14484         ls $DIR/d214c || error "ls $DIR/d214c failed"
14485         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14486         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14487 }
14488 run_test 214 "hash-indexed directory test - bug 20133"
14489
14490 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14491 create_lnet_proc_files() {
14492         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14493 }
14494
14495 # counterpart of create_lnet_proc_files
14496 remove_lnet_proc_files() {
14497         rm -f $TMP/lnet_$1.sys
14498 }
14499
14500 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14501 # 3rd arg as regexp for body
14502 check_lnet_proc_stats() {
14503         local l=$(cat "$TMP/lnet_$1" |wc -l)
14504         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14505
14506         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14507 }
14508
14509 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14510 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14511 # optional and can be regexp for 2nd line (lnet.routes case)
14512 check_lnet_proc_entry() {
14513         local blp=2          # blp stands for 'position of 1st line of body'
14514         [ -z "$5" ] || blp=3 # lnet.routes case
14515
14516         local l=$(cat "$TMP/lnet_$1" |wc -l)
14517         # subtracting one from $blp because the body can be empty
14518         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14519
14520         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14521                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14522
14523         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14524                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14525
14526         # bail out if any unexpected line happened
14527         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14528         [ "$?" != 0 ] || error "$2 misformatted"
14529 }
14530
14531 test_215() { # for bugs 18102, 21079, 21517
14532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14533
14534         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14535         local P='[1-9][0-9]*'           # positive numeric
14536         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14537         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14538         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14539         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14540
14541         local L1 # regexp for 1st line
14542         local L2 # regexp for 2nd line (optional)
14543         local BR # regexp for the rest (body)
14544
14545         # lnet.stats should look as 11 space-separated non-negative numerics
14546         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14547         create_lnet_proc_files "stats"
14548         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14549         remove_lnet_proc_files "stats"
14550
14551         # lnet.routes should look like this:
14552         # Routing disabled/enabled
14553         # net hops priority state router
14554         # where net is a string like tcp0, hops > 0, priority >= 0,
14555         # state is up/down,
14556         # router is a string like 192.168.1.1@tcp2
14557         L1="^Routing (disabled|enabled)$"
14558         L2="^net +hops +priority +state +router$"
14559         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14560         create_lnet_proc_files "routes"
14561         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14562         remove_lnet_proc_files "routes"
14563
14564         # lnet.routers should look like this:
14565         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14566         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14567         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14568         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14569         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14570         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14571         create_lnet_proc_files "routers"
14572         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14573         remove_lnet_proc_files "routers"
14574
14575         # lnet.peers should look like this:
14576         # nid refs state last max rtr min tx min queue
14577         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14578         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14579         # numeric (0 or >0 or <0), queue >= 0.
14580         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14581         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14582         create_lnet_proc_files "peers"
14583         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14584         remove_lnet_proc_files "peers"
14585
14586         # lnet.buffers  should look like this:
14587         # pages count credits min
14588         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14589         L1="^pages +count +credits +min$"
14590         BR="^ +$N +$N +$I +$I$"
14591         create_lnet_proc_files "buffers"
14592         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14593         remove_lnet_proc_files "buffers"
14594
14595         # lnet.nis should look like this:
14596         # nid status alive refs peer rtr max tx min
14597         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14598         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14599         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14600         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14601         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14602         create_lnet_proc_files "nis"
14603         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14604         remove_lnet_proc_files "nis"
14605
14606         # can we successfully write to lnet.stats?
14607         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14608 }
14609 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14610
14611 test_216() { # bug 20317
14612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14613         remote_ost_nodsh && skip "remote OST with nodsh"
14614
14615         local node
14616         local facets=$(get_facets OST)
14617         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14618
14619         save_lustre_params client "osc.*.contention_seconds" > $p
14620         save_lustre_params $facets \
14621                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14622         save_lustre_params $facets \
14623                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14624         save_lustre_params $facets \
14625                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14626         clear_stats osc.*.osc_stats
14627
14628         # agressive lockless i/o settings
14629         do_nodes $(comma_list $(osts_nodes)) \
14630                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14631                         ldlm.namespaces.filter-*.contended_locks=0 \
14632                         ldlm.namespaces.filter-*.contention_seconds=60"
14633         lctl set_param -n osc.*.contention_seconds=60
14634
14635         $DIRECTIO write $DIR/$tfile 0 10 4096
14636         $CHECKSTAT -s 40960 $DIR/$tfile
14637
14638         # disable lockless i/o
14639         do_nodes $(comma_list $(osts_nodes)) \
14640                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14641                         ldlm.namespaces.filter-*.contended_locks=32 \
14642                         ldlm.namespaces.filter-*.contention_seconds=0"
14643         lctl set_param -n osc.*.contention_seconds=0
14644         clear_stats osc.*.osc_stats
14645
14646         dd if=/dev/zero of=$DIR/$tfile count=0
14647         $CHECKSTAT -s 0 $DIR/$tfile
14648
14649         restore_lustre_params <$p
14650         rm -f $p
14651         rm $DIR/$tfile
14652 }
14653 run_test 216 "check lockless direct write updates file size and kms correctly"
14654
14655 test_217() { # bug 22430
14656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14657
14658         local node
14659         local nid
14660
14661         for node in $(nodes_list); do
14662                 nid=$(host_nids_address $node $NETTYPE)
14663                 if [[ $nid = *-* ]] ; then
14664                         echo "lctl ping $(h2nettype $nid)"
14665                         lctl ping $(h2nettype $nid)
14666                 else
14667                         echo "skipping $node (no hyphen detected)"
14668                 fi
14669         done
14670 }
14671 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14672
14673 test_218() {
14674        # do directio so as not to populate the page cache
14675        log "creating a 10 Mb file"
14676        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14677        log "starting reads"
14678        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14679        log "truncating the file"
14680        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14681        log "killing dd"
14682        kill %+ || true # reads might have finished
14683        echo "wait until dd is finished"
14684        wait
14685        log "removing the temporary file"
14686        rm -rf $DIR/$tfile || error "tmp file removal failed"
14687 }
14688 run_test 218 "parallel read and truncate should not deadlock"
14689
14690 test_219() {
14691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14692
14693         # write one partial page
14694         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14695         # set no grant so vvp_io_commit_write will do sync write
14696         $LCTL set_param fail_loc=0x411
14697         # write a full page at the end of file
14698         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14699
14700         $LCTL set_param fail_loc=0
14701         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14702         $LCTL set_param fail_loc=0x411
14703         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14704
14705         # LU-4201
14706         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14707         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14708 }
14709 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14710
14711 test_220() { #LU-325
14712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14713         remote_ost_nodsh && skip "remote OST with nodsh"
14714         remote_mds_nodsh && skip "remote MDS with nodsh"
14715         remote_mgs_nodsh && skip "remote MGS with nodsh"
14716
14717         local OSTIDX=0
14718
14719         # create on MDT0000 so the last_id and next_id are correct
14720         mkdir $DIR/$tdir
14721         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14722         OST=${OST%_UUID}
14723
14724         # on the mdt's osc
14725         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14726         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14727                         osc.$mdtosc_proc1.prealloc_last_id)
14728         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14729                         osc.$mdtosc_proc1.prealloc_next_id)
14730
14731         $LFS df -i
14732
14733         if ! combined_mgs_mds ; then
14734                 mount_mgs_client
14735         fi
14736
14737         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14738         #define OBD_FAIL_OST_ENOINO              0x229
14739         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14740         create_pool $FSNAME.$TESTNAME || return 1
14741         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14742
14743         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14744
14745         MDSOBJS=$((last_id - next_id))
14746         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14747
14748         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14749         echo "OST still has $count kbytes free"
14750
14751         echo "create $MDSOBJS files @next_id..."
14752         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14753
14754         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14755                         osc.$mdtosc_proc1.prealloc_last_id)
14756         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14757                         osc.$mdtosc_proc1.prealloc_next_id)
14758
14759         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14760         $LFS df -i
14761
14762         echo "cleanup..."
14763
14764         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14765         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14766
14767         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14768                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14769         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14770                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14771         echo "unlink $MDSOBJS files @$next_id..."
14772         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14773
14774         if ! combined_mgs_mds ; then
14775                 umount_mgs_client
14776         fi
14777 }
14778 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14779
14780 test_221() {
14781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14782
14783         dd if=`which date` of=$MOUNT/date oflag=sync
14784         chmod +x $MOUNT/date
14785
14786         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14787         $LCTL set_param fail_loc=0x80001401
14788
14789         $MOUNT/date > /dev/null
14790         rm -f $MOUNT/date
14791 }
14792 run_test 221 "make sure fault and truncate race to not cause OOM"
14793
14794 test_222a () {
14795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14796
14797         rm -rf $DIR/$tdir
14798         test_mkdir $DIR/$tdir
14799         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14800         createmany -o $DIR/$tdir/$tfile 10
14801         cancel_lru_locks mdc
14802         cancel_lru_locks osc
14803         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14804         $LCTL set_param fail_loc=0x31a
14805         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14806         $LCTL set_param fail_loc=0
14807         rm -r $DIR/$tdir
14808 }
14809 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14810
14811 test_222b () {
14812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14813
14814         rm -rf $DIR/$tdir
14815         test_mkdir $DIR/$tdir
14816         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14817         createmany -o $DIR/$tdir/$tfile 10
14818         cancel_lru_locks mdc
14819         cancel_lru_locks osc
14820         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14821         $LCTL set_param fail_loc=0x31a
14822         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14823         $LCTL set_param fail_loc=0
14824 }
14825 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14826
14827 test_223 () {
14828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14829
14830         rm -rf $DIR/$tdir
14831         test_mkdir $DIR/$tdir
14832         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14833         createmany -o $DIR/$tdir/$tfile 10
14834         cancel_lru_locks mdc
14835         cancel_lru_locks osc
14836         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14837         $LCTL set_param fail_loc=0x31b
14838         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14839         $LCTL set_param fail_loc=0
14840         rm -r $DIR/$tdir
14841 }
14842 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14843
14844 test_224a() { # LU-1039, MRP-303
14845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14846
14847         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14848         $LCTL set_param fail_loc=0x508
14849         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14850         $LCTL set_param fail_loc=0
14851         df $DIR
14852 }
14853 run_test 224a "Don't panic on bulk IO failure"
14854
14855 test_224b() { # LU-1039, MRP-303
14856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14857
14858         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14859         cancel_lru_locks osc
14860         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14861         $LCTL set_param fail_loc=0x515
14862         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14863         $LCTL set_param fail_loc=0
14864         df $DIR
14865 }
14866 run_test 224b "Don't panic on bulk IO failure"
14867
14868 test_224c() { # LU-6441
14869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14870         remote_mds_nodsh && skip "remote MDS with nodsh"
14871
14872         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14873         save_writethrough $p
14874         set_cache writethrough on
14875
14876         local pages_per_rpc=$($LCTL get_param \
14877                                 osc.*.max_pages_per_rpc)
14878         local at_max=$($LCTL get_param -n at_max)
14879         local timeout=$($LCTL get_param -n timeout)
14880         local test_at="at_max"
14881         local param_at="$FSNAME.sys.at_max"
14882         local test_timeout="timeout"
14883         local param_timeout="$FSNAME.sys.timeout"
14884
14885         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14886
14887         set_persistent_param_and_check client "$test_at" "$param_at" 0
14888         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14889
14890         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14891         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14892         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14893         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14894         sync
14895         do_facet ost1 "$LCTL set_param fail_loc=0"
14896
14897         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14898         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14899                 $timeout
14900
14901         $LCTL set_param -n $pages_per_rpc
14902         restore_lustre_params < $p
14903         rm -f $p
14904 }
14905 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14906
14907 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14908 test_225a () {
14909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14910         if [ -z ${MDSSURVEY} ]; then
14911                 skip_env "mds-survey not found"
14912         fi
14913         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14914                 skip "Need MDS version at least 2.2.51"
14915
14916         local mds=$(facet_host $SINGLEMDS)
14917         local target=$(do_nodes $mds 'lctl dl' |
14918                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14919
14920         local cmd1="file_count=1000 thrhi=4"
14921         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14922         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14923         local cmd="$cmd1 $cmd2 $cmd3"
14924
14925         rm -f ${TMP}/mds_survey*
14926         echo + $cmd
14927         eval $cmd || error "mds-survey with zero-stripe failed"
14928         cat ${TMP}/mds_survey*
14929         rm -f ${TMP}/mds_survey*
14930 }
14931 run_test 225a "Metadata survey sanity with zero-stripe"
14932
14933 test_225b () {
14934         if [ -z ${MDSSURVEY} ]; then
14935                 skip_env "mds-survey not found"
14936         fi
14937         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14938                 skip "Need MDS version at least 2.2.51"
14939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14940         remote_mds_nodsh && skip "remote MDS with nodsh"
14941         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14942                 skip_env "Need to mount OST to test"
14943         fi
14944
14945         local mds=$(facet_host $SINGLEMDS)
14946         local target=$(do_nodes $mds 'lctl dl' |
14947                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14948
14949         local cmd1="file_count=1000 thrhi=4"
14950         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14951         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14952         local cmd="$cmd1 $cmd2 $cmd3"
14953
14954         rm -f ${TMP}/mds_survey*
14955         echo + $cmd
14956         eval $cmd || error "mds-survey with stripe_count failed"
14957         cat ${TMP}/mds_survey*
14958         rm -f ${TMP}/mds_survey*
14959 }
14960 run_test 225b "Metadata survey sanity with stripe_count = 1"
14961
14962 mcreate_path2fid () {
14963         local mode=$1
14964         local major=$2
14965         local minor=$3
14966         local name=$4
14967         local desc=$5
14968         local path=$DIR/$tdir/$name
14969         local fid
14970         local rc
14971         local fid_path
14972
14973         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14974                 error "cannot create $desc"
14975
14976         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14977         rc=$?
14978         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14979
14980         fid_path=$($LFS fid2path $MOUNT $fid)
14981         rc=$?
14982         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14983
14984         [ "$path" == "$fid_path" ] ||
14985                 error "fid2path returned $fid_path, expected $path"
14986
14987         echo "pass with $path and $fid"
14988 }
14989
14990 test_226a () {
14991         rm -rf $DIR/$tdir
14992         mkdir -p $DIR/$tdir
14993
14994         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14995         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14996         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14997         mcreate_path2fid 0040666 0 0 dir "directory"
14998         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14999         mcreate_path2fid 0100666 0 0 file "regular file"
15000         mcreate_path2fid 0120666 0 0 link "symbolic link"
15001         mcreate_path2fid 0140666 0 0 sock "socket"
15002 }
15003 run_test 226a "call path2fid and fid2path on files of all type"
15004
15005 test_226b () {
15006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15007
15008         local MDTIDX=1
15009
15010         rm -rf $DIR/$tdir
15011         mkdir -p $DIR/$tdir
15012         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15013                 error "create remote directory failed"
15014         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15015         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15016                                 "character special file (null)"
15017         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15018                                 "character special file (no device)"
15019         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15020         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15021                                 "block special file (loop)"
15022         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15023         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15024         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15025 }
15026 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15027
15028 # LU-1299 Executing or running ldd on a truncated executable does not
15029 # cause an out-of-memory condition.
15030 test_227() {
15031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15032         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15033
15034         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15035         chmod +x $MOUNT/date
15036
15037         $MOUNT/date > /dev/null
15038         ldd $MOUNT/date > /dev/null
15039         rm -f $MOUNT/date
15040 }
15041 run_test 227 "running truncated executable does not cause OOM"
15042
15043 # LU-1512 try to reuse idle OI blocks
15044 test_228a() {
15045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15046         remote_mds_nodsh && skip "remote MDS with nodsh"
15047         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15048
15049         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15050         local myDIR=$DIR/$tdir
15051
15052         mkdir -p $myDIR
15053         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15054         $LCTL set_param fail_loc=0x80001002
15055         createmany -o $myDIR/t- 10000
15056         $LCTL set_param fail_loc=0
15057         # The guard is current the largest FID holder
15058         touch $myDIR/guard
15059         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15060                     tr -d '[')
15061         local IDX=$(($SEQ % 64))
15062
15063         do_facet $SINGLEMDS sync
15064         # Make sure journal flushed.
15065         sleep 6
15066         local blk1=$(do_facet $SINGLEMDS \
15067                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15068                      grep Blockcount | awk '{print $4}')
15069
15070         # Remove old files, some OI blocks will become idle.
15071         unlinkmany $myDIR/t- 10000
15072         # Create new files, idle OI blocks should be reused.
15073         createmany -o $myDIR/t- 2000
15074         do_facet $SINGLEMDS sync
15075         # Make sure journal flushed.
15076         sleep 6
15077         local blk2=$(do_facet $SINGLEMDS \
15078                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15079                      grep Blockcount | awk '{print $4}')
15080
15081         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15082 }
15083 run_test 228a "try to reuse idle OI blocks"
15084
15085 test_228b() {
15086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15087         remote_mds_nodsh && skip "remote MDS with nodsh"
15088         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15089
15090         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15091         local myDIR=$DIR/$tdir
15092
15093         mkdir -p $myDIR
15094         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15095         $LCTL set_param fail_loc=0x80001002
15096         createmany -o $myDIR/t- 10000
15097         $LCTL set_param fail_loc=0
15098         # The guard is current the largest FID holder
15099         touch $myDIR/guard
15100         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15101                     tr -d '[')
15102         local IDX=$(($SEQ % 64))
15103
15104         do_facet $SINGLEMDS sync
15105         # Make sure journal flushed.
15106         sleep 6
15107         local blk1=$(do_facet $SINGLEMDS \
15108                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15109                      grep Blockcount | awk '{print $4}')
15110
15111         # Remove old files, some OI blocks will become idle.
15112         unlinkmany $myDIR/t- 10000
15113
15114         # stop the MDT
15115         stop $SINGLEMDS || error "Fail to stop MDT."
15116         # remount the MDT
15117         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15118
15119         df $MOUNT || error "Fail to df."
15120         # Create new files, idle OI blocks should be reused.
15121         createmany -o $myDIR/t- 2000
15122         do_facet $SINGLEMDS sync
15123         # Make sure journal flushed.
15124         sleep 6
15125         local blk2=$(do_facet $SINGLEMDS \
15126                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15127                      grep Blockcount | awk '{print $4}')
15128
15129         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15130 }
15131 run_test 228b "idle OI blocks can be reused after MDT restart"
15132
15133 #LU-1881
15134 test_228c() {
15135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15136         remote_mds_nodsh && skip "remote MDS with nodsh"
15137         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15138
15139         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15140         local myDIR=$DIR/$tdir
15141
15142         mkdir -p $myDIR
15143         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15144         $LCTL set_param fail_loc=0x80001002
15145         # 20000 files can guarantee there are index nodes in the OI file
15146         createmany -o $myDIR/t- 20000
15147         $LCTL set_param fail_loc=0
15148         # The guard is current the largest FID holder
15149         touch $myDIR/guard
15150         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15151                     tr -d '[')
15152         local IDX=$(($SEQ % 64))
15153
15154         do_facet $SINGLEMDS sync
15155         # Make sure journal flushed.
15156         sleep 6
15157         local blk1=$(do_facet $SINGLEMDS \
15158                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15159                      grep Blockcount | awk '{print $4}')
15160
15161         # Remove old files, some OI blocks will become idle.
15162         unlinkmany $myDIR/t- 20000
15163         rm -f $myDIR/guard
15164         # The OI file should become empty now
15165
15166         # Create new files, idle OI blocks should be reused.
15167         createmany -o $myDIR/t- 2000
15168         do_facet $SINGLEMDS sync
15169         # Make sure journal flushed.
15170         sleep 6
15171         local blk2=$(do_facet $SINGLEMDS \
15172                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15173                      grep Blockcount | awk '{print $4}')
15174
15175         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15176 }
15177 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15178
15179 test_229() { # LU-2482, LU-3448
15180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15181         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15182         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15183                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15184
15185         rm -f $DIR/$tfile
15186
15187         # Create a file with a released layout and stripe count 2.
15188         $MULTIOP $DIR/$tfile H2c ||
15189                 error "failed to create file with released layout"
15190
15191         $LFS getstripe -v $DIR/$tfile
15192
15193         local pattern=$($LFS getstripe -L $DIR/$tfile)
15194         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15195
15196         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15197                 error "getstripe"
15198         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15199         stat $DIR/$tfile || error "failed to stat released file"
15200
15201         chown $RUNAS_ID $DIR/$tfile ||
15202                 error "chown $RUNAS_ID $DIR/$tfile failed"
15203
15204         chgrp $RUNAS_ID $DIR/$tfile ||
15205                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15206
15207         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15208         rm $DIR/$tfile || error "failed to remove released file"
15209 }
15210 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15211
15212 test_230a() {
15213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15214         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15215         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15216                 skip "Need MDS version at least 2.11.52"
15217
15218         local MDTIDX=1
15219
15220         test_mkdir $DIR/$tdir
15221         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15222         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15223         [ $mdt_idx -ne 0 ] &&
15224                 error "create local directory on wrong MDT $mdt_idx"
15225
15226         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15227                         error "create remote directory failed"
15228         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15229         [ $mdt_idx -ne $MDTIDX ] &&
15230                 error "create remote directory on wrong MDT $mdt_idx"
15231
15232         createmany -o $DIR/$tdir/test_230/t- 10 ||
15233                 error "create files on remote directory failed"
15234         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15235         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15236         rm -r $DIR/$tdir || error "unlink remote directory failed"
15237 }
15238 run_test 230a "Create remote directory and files under the remote directory"
15239
15240 test_230b() {
15241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15243         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15244                 skip "Need MDS version at least 2.11.52"
15245
15246         local MDTIDX=1
15247         local mdt_index
15248         local i
15249         local file
15250         local pid
15251         local stripe_count
15252         local migrate_dir=$DIR/$tdir/migrate_dir
15253         local other_dir=$DIR/$tdir/other_dir
15254
15255         test_mkdir $DIR/$tdir
15256         test_mkdir -i0 -c1 $migrate_dir
15257         test_mkdir -i0 -c1 $other_dir
15258         for ((i=0; i<10; i++)); do
15259                 mkdir -p $migrate_dir/dir_${i}
15260                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15261                         error "create files under remote dir failed $i"
15262         done
15263
15264         cp /etc/passwd $migrate_dir/$tfile
15265         cp /etc/passwd $other_dir/$tfile
15266         chattr +SAD $migrate_dir
15267         chattr +SAD $migrate_dir/$tfile
15268
15269         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15270         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15271         local old_dir_mode=$(stat -c%f $migrate_dir)
15272         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15273
15274         mkdir -p $migrate_dir/dir_default_stripe2
15275         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15276         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15277
15278         mkdir -p $other_dir
15279         ln $migrate_dir/$tfile $other_dir/luna
15280         ln $migrate_dir/$tfile $migrate_dir/sofia
15281         ln $other_dir/$tfile $migrate_dir/david
15282         ln -s $migrate_dir/$tfile $other_dir/zachary
15283         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15284         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15285
15286         $LFS migrate -m $MDTIDX $migrate_dir ||
15287                 error "fails on migrating remote dir to MDT1"
15288
15289         echo "migratate to MDT1, then checking.."
15290         for ((i = 0; i < 10; i++)); do
15291                 for file in $(find $migrate_dir/dir_${i}); do
15292                         mdt_index=$($LFS getstripe -m $file)
15293                         [ $mdt_index == $MDTIDX ] ||
15294                                 error "$file is not on MDT${MDTIDX}"
15295                 done
15296         done
15297
15298         # the multiple link file should still in MDT0
15299         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15300         [ $mdt_index == 0 ] ||
15301                 error "$file is not on MDT${MDTIDX}"
15302
15303         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15304         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15305                 error " expect $old_dir_flag get $new_dir_flag"
15306
15307         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15308         [ "$old_file_flag" = "$new_file_flag" ] ||
15309                 error " expect $old_file_flag get $new_file_flag"
15310
15311         local new_dir_mode=$(stat -c%f $migrate_dir)
15312         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15313                 error "expect mode $old_dir_mode get $new_dir_mode"
15314
15315         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15316         [ "$old_file_mode" = "$new_file_mode" ] ||
15317                 error "expect mode $old_file_mode get $new_file_mode"
15318
15319         diff /etc/passwd $migrate_dir/$tfile ||
15320                 error "$tfile different after migration"
15321
15322         diff /etc/passwd $other_dir/luna ||
15323                 error "luna different after migration"
15324
15325         diff /etc/passwd $migrate_dir/sofia ||
15326                 error "sofia different after migration"
15327
15328         diff /etc/passwd $migrate_dir/david ||
15329                 error "david different after migration"
15330
15331         diff /etc/passwd $other_dir/zachary ||
15332                 error "zachary different after migration"
15333
15334         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15335                 error "${tfile}_ln different after migration"
15336
15337         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15338                 error "${tfile}_ln_other different after migration"
15339
15340         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15341         [ $stripe_count = 2 ] ||
15342                 error "dir strpe_count $d != 2 after migration."
15343
15344         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15345         [ $stripe_count = 2 ] ||
15346                 error "file strpe_count $d != 2 after migration."
15347
15348         #migrate back to MDT0
15349         MDTIDX=0
15350
15351         $LFS migrate -m $MDTIDX $migrate_dir ||
15352                 error "fails on migrating remote dir to MDT0"
15353
15354         echo "migrate back to MDT0, checking.."
15355         for file in $(find $migrate_dir); do
15356                 mdt_index=$($LFS getstripe -m $file)
15357                 [ $mdt_index == $MDTIDX ] ||
15358                         error "$file is not on MDT${MDTIDX}"
15359         done
15360
15361         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15362         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15363                 error " expect $old_dir_flag get $new_dir_flag"
15364
15365         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15366         [ "$old_file_flag" = "$new_file_flag" ] ||
15367                 error " expect $old_file_flag get $new_file_flag"
15368
15369         local new_dir_mode=$(stat -c%f $migrate_dir)
15370         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15371                 error "expect mode $old_dir_mode get $new_dir_mode"
15372
15373         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15374         [ "$old_file_mode" = "$new_file_mode" ] ||
15375                 error "expect mode $old_file_mode get $new_file_mode"
15376
15377         diff /etc/passwd ${migrate_dir}/$tfile ||
15378                 error "$tfile different after migration"
15379
15380         diff /etc/passwd ${other_dir}/luna ||
15381                 error "luna different after migration"
15382
15383         diff /etc/passwd ${migrate_dir}/sofia ||
15384                 error "sofia different after migration"
15385
15386         diff /etc/passwd ${other_dir}/zachary ||
15387                 error "zachary different after migration"
15388
15389         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15390                 error "${tfile}_ln different after migration"
15391
15392         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15393                 error "${tfile}_ln_other different after migration"
15394
15395         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15396         [ $stripe_count = 2 ] ||
15397                 error "dir strpe_count $d != 2 after migration."
15398
15399         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15400         [ $stripe_count = 2 ] ||
15401                 error "file strpe_count $d != 2 after migration."
15402
15403         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15404 }
15405 run_test 230b "migrate directory"
15406
15407 test_230c() {
15408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15409         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15410         remote_mds_nodsh && skip "remote MDS with nodsh"
15411         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15412                 skip "Need MDS version at least 2.11.52"
15413
15414         local MDTIDX=1
15415         local total=3
15416         local mdt_index
15417         local file
15418         local migrate_dir=$DIR/$tdir/migrate_dir
15419
15420         #If migrating directory fails in the middle, all entries of
15421         #the directory is still accessiable.
15422         test_mkdir $DIR/$tdir
15423         test_mkdir -i0 -c1 $migrate_dir
15424         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15425         stat $migrate_dir
15426         createmany -o $migrate_dir/f $total ||
15427                 error "create files under ${migrate_dir} failed"
15428
15429         # fail after migrating top dir, and this will fail only once, so the
15430         # first sub file migration will fail (currently f3), others succeed.
15431         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15432         do_facet mds1 lctl set_param fail_loc=0x1801
15433         local t=$(ls $migrate_dir | wc -l)
15434         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15435                 error "migrate should fail"
15436         local u=$(ls $migrate_dir | wc -l)
15437         [ "$u" == "$t" ] || error "$u != $t during migration"
15438
15439         # add new dir/file should succeed
15440         mkdir $migrate_dir/dir ||
15441                 error "mkdir failed under migrating directory"
15442         touch $migrate_dir/file ||
15443                 error "create file failed under migrating directory"
15444
15445         # add file with existing name should fail
15446         for file in $migrate_dir/f*; do
15447                 stat $file > /dev/null || error "stat $file failed"
15448                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15449                         error "open(O_CREAT|O_EXCL) $file should fail"
15450                 $MULTIOP $file m && error "create $file should fail"
15451                 touch $DIR/$tdir/remote_dir/$tfile ||
15452                         error "touch $tfile failed"
15453                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15454                         error "link $file should fail"
15455                 mdt_index=$($LFS getstripe -m $file)
15456                 if [ $mdt_index == 0 ]; then
15457                         # file failed to migrate is not allowed to rename to
15458                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15459                                 error "rename to $file should fail"
15460                 else
15461                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15462                                 error "rename to $file failed"
15463                 fi
15464                 echo hello >> $file || error "write $file failed"
15465         done
15466
15467         # resume migration with different options should fail
15468         $LFS migrate -m 0 $migrate_dir &&
15469                 error "migrate -m 0 $migrate_dir should fail"
15470
15471         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15472                 error "migrate -c 2 $migrate_dir should fail"
15473
15474         # resume migration should succeed
15475         $LFS migrate -m $MDTIDX $migrate_dir ||
15476                 error "migrate $migrate_dir failed"
15477
15478         echo "Finish migration, then checking.."
15479         for file in $(find $migrate_dir); do
15480                 mdt_index=$($LFS getstripe -m $file)
15481                 [ $mdt_index == $MDTIDX ] ||
15482                         error "$file is not on MDT${MDTIDX}"
15483         done
15484
15485         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15486 }
15487 run_test 230c "check directory accessiblity if migration failed"
15488
15489 test_230d() {
15490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15492         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15493                 skip "Need MDS version at least 2.11.52"
15494         # LU-11235
15495         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15496
15497         local migrate_dir=$DIR/$tdir/migrate_dir
15498         local old_index
15499         local new_index
15500         local old_count
15501         local new_count
15502         local new_hash
15503         local mdt_index
15504         local i
15505         local j
15506
15507         old_index=$((RANDOM % MDSCOUNT))
15508         old_count=$((MDSCOUNT - old_index))
15509         new_index=$((RANDOM % MDSCOUNT))
15510         new_count=$((MDSCOUNT - new_index))
15511         new_hash="all_char"
15512
15513         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15514         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15515
15516         test_mkdir $DIR/$tdir
15517         test_mkdir -i $old_index -c $old_count $migrate_dir
15518
15519         for ((i=0; i<100; i++)); do
15520                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15521                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15522                         error "create files under remote dir failed $i"
15523         done
15524
15525         echo -n "Migrate from MDT$old_index "
15526         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15527         echo -n "to MDT$new_index"
15528         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15529         echo
15530
15531         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15532         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15533                 error "migrate remote dir error"
15534
15535         echo "Finish migration, then checking.."
15536         for file in $(find $migrate_dir); do
15537                 mdt_index=$($LFS getstripe -m $file)
15538                 if [ $mdt_index -lt $new_index ] ||
15539                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15540                         error "$file is on MDT$mdt_index"
15541                 fi
15542         done
15543
15544         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15545 }
15546 run_test 230d "check migrate big directory"
15547
15548 test_230e() {
15549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15552                 skip "Need MDS version at least 2.11.52"
15553
15554         local i
15555         local j
15556         local a_fid
15557         local b_fid
15558
15559         mkdir -p $DIR/$tdir
15560         mkdir $DIR/$tdir/migrate_dir
15561         mkdir $DIR/$tdir/other_dir
15562         touch $DIR/$tdir/migrate_dir/a
15563         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15564         ls $DIR/$tdir/other_dir
15565
15566         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15567                 error "migrate dir fails"
15568
15569         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15570         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15571
15572         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15573         [ $mdt_index == 0 ] || error "a is not on MDT0"
15574
15575         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15576                 error "migrate dir fails"
15577
15578         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15579         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15580
15581         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15582         [ $mdt_index == 1 ] || error "a is not on MDT1"
15583
15584         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15585         [ $mdt_index == 1 ] || error "b is not on MDT1"
15586
15587         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15588         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15589
15590         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15591
15592         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15593 }
15594 run_test 230e "migrate mulitple local link files"
15595
15596 test_230f() {
15597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15599         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15600                 skip "Need MDS version at least 2.11.52"
15601
15602         local a_fid
15603         local ln_fid
15604
15605         mkdir -p $DIR/$tdir
15606         mkdir $DIR/$tdir/migrate_dir
15607         $LFS mkdir -i1 $DIR/$tdir/other_dir
15608         touch $DIR/$tdir/migrate_dir/a
15609         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15610         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15611         ls $DIR/$tdir/other_dir
15612
15613         # a should be migrated to MDT1, since no other links on MDT0
15614         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15615                 error "#1 migrate dir fails"
15616         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15617         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15618         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15619         [ $mdt_index == 1 ] || error "a is not on MDT1"
15620
15621         # a should stay on MDT1, because it is a mulitple link file
15622         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15623                 error "#2 migrate dir fails"
15624         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15625         [ $mdt_index == 1 ] || error "a is not on MDT1"
15626
15627         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15628                 error "#3 migrate dir fails"
15629
15630         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15631         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15632         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15633
15634         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15635         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15636
15637         # a should be migrated to MDT0, since no other links on MDT1
15638         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15639                 error "#4 migrate dir fails"
15640         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15641         [ $mdt_index == 0 ] || error "a is not on MDT0"
15642
15643         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15644 }
15645 run_test 230f "migrate mulitple remote link files"
15646
15647 test_230g() {
15648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15650         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15651                 skip "Need MDS version at least 2.11.52"
15652
15653         mkdir -p $DIR/$tdir/migrate_dir
15654
15655         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15656                 error "migrating dir to non-exist MDT succeeds"
15657         true
15658 }
15659 run_test 230g "migrate dir to non-exist MDT"
15660
15661 test_230h() {
15662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15663         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15664         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15665                 skip "Need MDS version at least 2.11.52"
15666
15667         local mdt_index
15668
15669         mkdir -p $DIR/$tdir/migrate_dir
15670
15671         $LFS migrate -m1 $DIR &&
15672                 error "migrating mountpoint1 should fail"
15673
15674         $LFS migrate -m1 $DIR/$tdir/.. &&
15675                 error "migrating mountpoint2 should fail"
15676
15677         # same as mv
15678         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15679                 error "migrating $tdir/migrate_dir/.. should fail"
15680
15681         true
15682 }
15683 run_test 230h "migrate .. and root"
15684
15685 test_230i() {
15686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15688         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15689                 skip "Need MDS version at least 2.11.52"
15690
15691         mkdir -p $DIR/$tdir/migrate_dir
15692
15693         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15694                 error "migration fails with a tailing slash"
15695
15696         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15697                 error "migration fails with two tailing slashes"
15698 }
15699 run_test 230i "lfs migrate -m tolerates trailing slashes"
15700
15701 test_230j() {
15702         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15703         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15704                 skip "Need MDS version at least 2.11.52"
15705
15706         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15707         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15708                 error "create $tfile failed"
15709         cat /etc/passwd > $DIR/$tdir/$tfile
15710
15711         $LFS migrate -m 1 $DIR/$tdir
15712
15713         cmp /etc/passwd $DIR/$tdir/$tfile ||
15714                 error "DoM file mismatch after migration"
15715 }
15716 run_test 230j "DoM file data not changed after dir migration"
15717
15718 test_230k() {
15719         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15720         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15721                 skip "Need MDS version at least 2.11.56"
15722
15723         local total=20
15724         local files_on_starting_mdt=0
15725
15726         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15727         $LFS getdirstripe $DIR/$tdir
15728         for i in $(seq $total); do
15729                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15730                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15731                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15732         done
15733
15734         echo "$files_on_starting_mdt files on MDT0"
15735
15736         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15737         $LFS getdirstripe $DIR/$tdir
15738
15739         files_on_starting_mdt=0
15740         for i in $(seq $total); do
15741                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15742                         error "file $tfile.$i mismatch after migration"
15743                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15744                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15745         done
15746
15747         echo "$files_on_starting_mdt files on MDT1 after migration"
15748         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15749
15750         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15751         $LFS getdirstripe $DIR/$tdir
15752
15753         files_on_starting_mdt=0
15754         for i in $(seq $total); do
15755                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15756                         error "file $tfile.$i mismatch after 2nd migration"
15757                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15758                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15759         done
15760
15761         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15762         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15763
15764         true
15765 }
15766 run_test 230k "file data not changed after dir migration"
15767
15768 test_230l() {
15769         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15770         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15771                 skip "Need MDS version at least 2.11.56"
15772
15773         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15774         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15775                 error "create files under remote dir failed $i"
15776         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15777 }
15778 run_test 230l "readdir between MDTs won't crash"
15779
15780 test_231a()
15781 {
15782         # For simplicity this test assumes that max_pages_per_rpc
15783         # is the same across all OSCs
15784         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15785         local bulk_size=$((max_pages * PAGE_SIZE))
15786         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15787                                        head -n 1)
15788
15789         mkdir -p $DIR/$tdir
15790         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15791                 error "failed to set stripe with -S ${brw_size}M option"
15792
15793         # clear the OSC stats
15794         $LCTL set_param osc.*.stats=0 &>/dev/null
15795         stop_writeback
15796
15797         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15798         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15799                 oflag=direct &>/dev/null || error "dd failed"
15800
15801         sync; sleep 1; sync # just to be safe
15802         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15803         if [ x$nrpcs != "x1" ]; then
15804                 $LCTL get_param osc.*.stats
15805                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15806         fi
15807
15808         start_writeback
15809         # Drop the OSC cache, otherwise we will read from it
15810         cancel_lru_locks osc
15811
15812         # clear the OSC stats
15813         $LCTL set_param osc.*.stats=0 &>/dev/null
15814
15815         # Client reads $bulk_size.
15816         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15817                 iflag=direct &>/dev/null || error "dd failed"
15818
15819         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15820         if [ x$nrpcs != "x1" ]; then
15821                 $LCTL get_param osc.*.stats
15822                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15823         fi
15824 }
15825 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15826
15827 test_231b() {
15828         mkdir -p $DIR/$tdir
15829         local i
15830         for i in {0..1023}; do
15831                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15832                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15833                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15834         done
15835         sync
15836 }
15837 run_test 231b "must not assert on fully utilized OST request buffer"
15838
15839 test_232a() {
15840         mkdir -p $DIR/$tdir
15841         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15842
15843         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15844         do_facet ost1 $LCTL set_param fail_loc=0x31c
15845
15846         # ignore dd failure
15847         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15848
15849         do_facet ost1 $LCTL set_param fail_loc=0
15850         umount_client $MOUNT || error "umount failed"
15851         mount_client $MOUNT || error "mount failed"
15852         stop ost1 || error "cannot stop ost1"
15853         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15854 }
15855 run_test 232a "failed lock should not block umount"
15856
15857 test_232b() {
15858         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15859                 skip "Need MDS version at least 2.10.58"
15860
15861         mkdir -p $DIR/$tdir
15862         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15863         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15864         sync
15865         cancel_lru_locks osc
15866
15867         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15868         do_facet ost1 $LCTL set_param fail_loc=0x31c
15869
15870         # ignore failure
15871         $LFS data_version $DIR/$tdir/$tfile || true
15872
15873         do_facet ost1 $LCTL set_param fail_loc=0
15874         umount_client $MOUNT || error "umount failed"
15875         mount_client $MOUNT || error "mount failed"
15876         stop ost1 || error "cannot stop ost1"
15877         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15878 }
15879 run_test 232b "failed data version lock should not block umount"
15880
15881 test_233a() {
15882         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15883                 skip "Need MDS version at least 2.3.64"
15884         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15885
15886         local fid=$($LFS path2fid $MOUNT)
15887
15888         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15889                 error "cannot access $MOUNT using its FID '$fid'"
15890 }
15891 run_test 233a "checking that OBF of the FS root succeeds"
15892
15893 test_233b() {
15894         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15895                 skip "Need MDS version at least 2.5.90"
15896         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15897
15898         local fid=$($LFS path2fid $MOUNT/.lustre)
15899
15900         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15901                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15902
15903         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15904         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15905                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15906 }
15907 run_test 233b "checking that OBF of the FS .lustre succeeds"
15908
15909 test_234() {
15910         local p="$TMP/sanityN-$TESTNAME.parameters"
15911         save_lustre_params client "llite.*.xattr_cache" > $p
15912         lctl set_param llite.*.xattr_cache 1 ||
15913                 skip_env "xattr cache is not supported"
15914
15915         mkdir -p $DIR/$tdir || error "mkdir failed"
15916         touch $DIR/$tdir/$tfile || error "touch failed"
15917         # OBD_FAIL_LLITE_XATTR_ENOMEM
15918         $LCTL set_param fail_loc=0x1405
15919         getfattr -n user.attr $DIR/$tdir/$tfile &&
15920                 error "getfattr should have failed with ENOMEM"
15921         $LCTL set_param fail_loc=0x0
15922         rm -rf $DIR/$tdir
15923
15924         restore_lustre_params < $p
15925         rm -f $p
15926 }
15927 run_test 234 "xattr cache should not crash on ENOMEM"
15928
15929 test_235() {
15930         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15931                 skip "Need MDS version at least 2.4.52"
15932
15933         flock_deadlock $DIR/$tfile
15934         local RC=$?
15935         case $RC in
15936                 0)
15937                 ;;
15938                 124) error "process hangs on a deadlock"
15939                 ;;
15940                 *) error "error executing flock_deadlock $DIR/$tfile"
15941                 ;;
15942         esac
15943 }
15944 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15945
15946 #LU-2935
15947 test_236() {
15948         check_swap_layouts_support
15949
15950         local ref1=/etc/passwd
15951         local ref2=/etc/group
15952         local file1=$DIR/$tdir/f1
15953         local file2=$DIR/$tdir/f2
15954
15955         test_mkdir -c1 $DIR/$tdir
15956         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15957         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15958         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15959         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15960         local fd=$(free_fd)
15961         local cmd="exec $fd<>$file2"
15962         eval $cmd
15963         rm $file2
15964         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15965                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15966         cmd="exec $fd>&-"
15967         eval $cmd
15968         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15969
15970         #cleanup
15971         rm -rf $DIR/$tdir
15972 }
15973 run_test 236 "Layout swap on open unlinked file"
15974
15975 # LU-4659 linkea consistency
15976 test_238() {
15977         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15978                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15979                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15980                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15981
15982         touch $DIR/$tfile
15983         ln $DIR/$tfile $DIR/$tfile.lnk
15984         touch $DIR/$tfile.new
15985         mv $DIR/$tfile.new $DIR/$tfile
15986         local fid1=$($LFS path2fid $DIR/$tfile)
15987         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15988         local path1=$($LFS fid2path $FSNAME "$fid1")
15989         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15990         local path2=$($LFS fid2path $FSNAME "$fid2")
15991         [ $tfile.lnk == $path2 ] ||
15992                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15993         rm -f $DIR/$tfile*
15994 }
15995 run_test 238 "Verify linkea consistency"
15996
15997 test_239A() { # was test_239
15998         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15999                 skip "Need MDS version at least 2.5.60"
16000
16001         local list=$(comma_list $(mdts_nodes))
16002
16003         mkdir -p $DIR/$tdir
16004         createmany -o $DIR/$tdir/f- 5000
16005         unlinkmany $DIR/$tdir/f- 5000
16006         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16007                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16008         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16009                         osp.*MDT*.sync_in_flight" | calc_sum)
16010         [ "$changes" -eq 0 ] || error "$changes not synced"
16011 }
16012 run_test 239A "osp_sync test"
16013
16014 test_239a() { #LU-5297
16015         remote_mds_nodsh && skip "remote MDS with nodsh"
16016
16017         touch $DIR/$tfile
16018         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16019         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16020         chgrp $RUNAS_GID $DIR/$tfile
16021         wait_delete_completed
16022 }
16023 run_test 239a "process invalid osp sync record correctly"
16024
16025 test_239b() { #LU-5297
16026         remote_mds_nodsh && skip "remote MDS with nodsh"
16027
16028         touch $DIR/$tfile1
16029         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16030         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16031         chgrp $RUNAS_GID $DIR/$tfile1
16032         wait_delete_completed
16033         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16034         touch $DIR/$tfile2
16035         chgrp $RUNAS_GID $DIR/$tfile2
16036         wait_delete_completed
16037 }
16038 run_test 239b "process osp sync record with ENOMEM error correctly"
16039
16040 test_240() {
16041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16042         remote_mds_nodsh && skip "remote MDS with nodsh"
16043
16044         mkdir -p $DIR/$tdir
16045
16046         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16047                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16048         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16049                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16050
16051         umount_client $MOUNT || error "umount failed"
16052         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16053         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16054         mount_client $MOUNT || error "failed to mount client"
16055
16056         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16057         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16058 }
16059 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16060
16061 test_241_bio() {
16062         local count=$1
16063         local bsize=$2
16064
16065         for LOOP in $(seq $count); do
16066                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16067                 cancel_lru_locks $OSC || true
16068         done
16069 }
16070
16071 test_241_dio() {
16072         local count=$1
16073         local bsize=$2
16074
16075         for LOOP in $(seq $1); do
16076                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16077                         2>/dev/null
16078         done
16079 }
16080
16081 test_241a() { # was test_241
16082         local bsize=$PAGE_SIZE
16083
16084         (( bsize < 40960 )) && bsize=40960
16085         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16086         ls -la $DIR/$tfile
16087         cancel_lru_locks $OSC
16088         test_241_bio 1000 $bsize &
16089         PID=$!
16090         test_241_dio 1000 $bsize
16091         wait $PID
16092 }
16093 run_test 241a "bio vs dio"
16094
16095 test_241b() {
16096         local bsize=$PAGE_SIZE
16097
16098         (( bsize < 40960 )) && bsize=40960
16099         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16100         ls -la $DIR/$tfile
16101         test_241_dio 1000 $bsize &
16102         PID=$!
16103         test_241_dio 1000 $bsize
16104         wait $PID
16105 }
16106 run_test 241b "dio vs dio"
16107
16108 test_242() {
16109         remote_mds_nodsh && skip "remote MDS with nodsh"
16110
16111         mkdir -p $DIR/$tdir
16112         touch $DIR/$tdir/$tfile
16113
16114         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16115         do_facet mds1 lctl set_param fail_loc=0x105
16116         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16117
16118         do_facet mds1 lctl set_param fail_loc=0
16119         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16120 }
16121 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16122
16123 test_243()
16124 {
16125         test_mkdir $DIR/$tdir
16126         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16127 }
16128 run_test 243 "various group lock tests"
16129
16130 test_244()
16131 {
16132         test_mkdir $DIR/$tdir
16133         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16134         sendfile_grouplock $DIR/$tdir/$tfile || \
16135                 error "sendfile+grouplock failed"
16136         rm -rf $DIR/$tdir
16137 }
16138 run_test 244 "sendfile with group lock tests"
16139
16140 test_245() {
16141         local flagname="multi_mod_rpcs"
16142         local connect_data_name="max_mod_rpcs"
16143         local out
16144
16145         # check if multiple modify RPCs flag is set
16146         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16147                 grep "connect_flags:")
16148         echo "$out"
16149
16150         echo "$out" | grep -qw $flagname
16151         if [ $? -ne 0 ]; then
16152                 echo "connect flag $flagname is not set"
16153                 return
16154         fi
16155
16156         # check if multiple modify RPCs data is set
16157         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16158         echo "$out"
16159
16160         echo "$out" | grep -qw $connect_data_name ||
16161                 error "import should have connect data $connect_data_name"
16162 }
16163 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16164
16165 test_246() { # LU-7371
16166         remote_ost_nodsh && skip "remote OST with nodsh"
16167         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16168                 skip "Need OST version >= 2.7.62"
16169
16170         do_facet ost1 $LCTL set_param fail_val=4095
16171 #define OBD_FAIL_OST_READ_SIZE          0x234
16172         do_facet ost1 $LCTL set_param fail_loc=0x234
16173         $LFS setstripe $DIR/$tfile -i 0 -c 1
16174         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16175         cancel_lru_locks $FSNAME-OST0000
16176         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16177 }
16178 run_test 246 "Read file of size 4095 should return right length"
16179
16180 cleanup_247() {
16181         local submount=$1
16182
16183         trap 0
16184         umount_client $submount
16185         rmdir $submount
16186 }
16187
16188 test_247a() {
16189         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16190                 grep -q subtree ||
16191                 skip_env "Fileset feature is not supported"
16192
16193         local submount=${MOUNT}_$tdir
16194
16195         mkdir $MOUNT/$tdir
16196         mkdir -p $submount || error "mkdir $submount failed"
16197         FILESET="$FILESET/$tdir" mount_client $submount ||
16198                 error "mount $submount failed"
16199         trap "cleanup_247 $submount" EXIT
16200         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16201         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16202                 error "read $MOUNT/$tdir/$tfile failed"
16203         cleanup_247 $submount
16204 }
16205 run_test 247a "mount subdir as fileset"
16206
16207 test_247b() {
16208         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16209                 skip_env "Fileset feature is not supported"
16210
16211         local submount=${MOUNT}_$tdir
16212
16213         rm -rf $MOUNT/$tdir
16214         mkdir -p $submount || error "mkdir $submount failed"
16215         SKIP_FILESET=1
16216         FILESET="$FILESET/$tdir" mount_client $submount &&
16217                 error "mount $submount should fail"
16218         rmdir $submount
16219 }
16220 run_test 247b "mount subdir that dose not exist"
16221
16222 test_247c() {
16223         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16224                 skip_env "Fileset feature is not supported"
16225
16226         local submount=${MOUNT}_$tdir
16227
16228         mkdir -p $MOUNT/$tdir/dir1
16229         mkdir -p $submount || error "mkdir $submount failed"
16230         trap "cleanup_247 $submount" EXIT
16231         FILESET="$FILESET/$tdir" mount_client $submount ||
16232                 error "mount $submount failed"
16233         local fid=$($LFS path2fid $MOUNT/)
16234         $LFS fid2path $submount $fid && error "fid2path should fail"
16235         cleanup_247 $submount
16236 }
16237 run_test 247c "running fid2path outside root"
16238
16239 test_247d() {
16240         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16241                 skip "Fileset feature is not supported"
16242
16243         local submount=${MOUNT}_$tdir
16244
16245         mkdir -p $MOUNT/$tdir/dir1
16246         mkdir -p $submount || error "mkdir $submount failed"
16247         FILESET="$FILESET/$tdir" mount_client $submount ||
16248                 error "mount $submount failed"
16249         trap "cleanup_247 $submount" EXIT
16250         local fid=$($LFS path2fid $submount/dir1)
16251         $LFS fid2path $submount $fid || error "fid2path should succeed"
16252         cleanup_247 $submount
16253 }
16254 run_test 247d "running fid2path inside root"
16255
16256 # LU-8037
16257 test_247e() {
16258         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16259                 grep -q subtree ||
16260                 skip "Fileset feature is not supported"
16261
16262         local submount=${MOUNT}_$tdir
16263
16264         mkdir $MOUNT/$tdir
16265         mkdir -p $submount || error "mkdir $submount failed"
16266         FILESET="$FILESET/.." mount_client $submount &&
16267                 error "mount $submount should fail"
16268         rmdir $submount
16269 }
16270 run_test 247e "mount .. as fileset"
16271
16272 test_248() {
16273         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16274         [ -z "$fast_read_sav" ] && skip "no fast read support"
16275
16276         # create a large file for fast read verification
16277         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16278
16279         # make sure the file is created correctly
16280         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16281                 { rm -f $DIR/$tfile; skip "file creation error"; }
16282
16283         echo "Test 1: verify that fast read is 4 times faster on cache read"
16284
16285         # small read with fast read enabled
16286         $LCTL set_param -n llite.*.fast_read=1
16287         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16288                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16289                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16290         # small read with fast read disabled
16291         $LCTL set_param -n llite.*.fast_read=0
16292         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16293                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16294                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16295
16296         # verify that fast read is 4 times faster for cache read
16297         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16298                 error_not_in_vm "fast read was not 4 times faster: " \
16299                            "$t_fast vs $t_slow"
16300
16301         echo "Test 2: verify the performance between big and small read"
16302         $LCTL set_param -n llite.*.fast_read=1
16303
16304         # 1k non-cache read
16305         cancel_lru_locks osc
16306         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16307                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16308                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16309
16310         # 1M non-cache read
16311         cancel_lru_locks osc
16312         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16313                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16314                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16315
16316         # verify that big IO is not 4 times faster than small IO
16317         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16318                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16319
16320         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16321         rm -f $DIR/$tfile
16322 }
16323 run_test 248 "fast read verification"
16324
16325 test_249() { # LU-7890
16326         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16327                 skip "Need at least version 2.8.54"
16328
16329         rm -f $DIR/$tfile
16330         $LFS setstripe -c 1 $DIR/$tfile
16331         # Offset 2T == 4k * 512M
16332         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16333                 error "dd to 2T offset failed"
16334 }
16335 run_test 249 "Write above 2T file size"
16336
16337 test_250() {
16338         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16339          && skip "no 16TB file size limit on ZFS"
16340
16341         $LFS setstripe -c 1 $DIR/$tfile
16342         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16343         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16344         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16345         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16346                 conv=notrunc,fsync && error "append succeeded"
16347         return 0
16348 }
16349 run_test 250 "Write above 16T limit"
16350
16351 test_251() {
16352         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16353
16354         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16355         #Skip once - writing the first stripe will succeed
16356         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16357         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16358                 error "short write happened"
16359
16360         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16361         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16362                 error "short read happened"
16363
16364         rm -f $DIR/$tfile
16365 }
16366 run_test 251 "Handling short read and write correctly"
16367
16368 test_252() {
16369         remote_mds_nodsh && skip "remote MDS with nodsh"
16370         remote_ost_nodsh && skip "remote OST with nodsh"
16371         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16372                 skip_env "ldiskfs only test"
16373         fi
16374
16375         local tgt
16376         local dev
16377         local out
16378         local uuid
16379         local num
16380         local gen
16381
16382         # check lr_reader on OST0000
16383         tgt=ost1
16384         dev=$(facet_device $tgt)
16385         out=$(do_facet $tgt $LR_READER $dev)
16386         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16387         echo "$out"
16388         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16389         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16390                 error "Invalid uuid returned by $LR_READER on target $tgt"
16391         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16392
16393         # check lr_reader -c on MDT0000
16394         tgt=mds1
16395         dev=$(facet_device $tgt)
16396         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16397                 skip "$LR_READER does not support additional options"
16398         fi
16399         out=$(do_facet $tgt $LR_READER -c $dev)
16400         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16401         echo "$out"
16402         num=$(echo "$out" | grep -c "mdtlov")
16403         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16404                 error "Invalid number of mdtlov clients returned by $LR_READER"
16405         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16406
16407         # check lr_reader -cr on MDT0000
16408         out=$(do_facet $tgt $LR_READER -cr $dev)
16409         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16410         echo "$out"
16411         echo "$out" | grep -q "^reply_data:$" ||
16412                 error "$LR_READER should have returned 'reply_data' section"
16413         num=$(echo "$out" | grep -c "client_generation")
16414         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16415 }
16416 run_test 252 "check lr_reader tool"
16417
16418 test_253_fill_ost() {
16419         local size_mb #how many MB should we write to pass watermark
16420         local lwm=$3  #low watermark
16421         local free_10mb #10% of free space
16422
16423         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16424         size_mb=$((free_kb / 1024 - lwm))
16425         free_10mb=$((free_kb / 10240))
16426         #If 10% of free space cross low watermark use it
16427         if (( free_10mb > size_mb )); then
16428                 size_mb=$free_10mb
16429         else
16430                 #At least we need to store 1.1 of difference between
16431                 #free space and low watermark
16432                 size_mb=$((size_mb + size_mb / 10))
16433         fi
16434         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16435                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16436                          oflag=append conv=notrunc
16437         fi
16438
16439         sleep_maxage
16440
16441         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16442         echo "OST still has $((free_kb / 1024)) mbytes free"
16443 }
16444
16445 test_253() {
16446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16447         remote_mds_nodsh && skip "remote MDS with nodsh"
16448         remote_mgs_nodsh && skip "remote MGS with nodsh"
16449
16450         local ostidx=0
16451         local rc=0
16452
16453         local ost_name=$($LFS osts |
16454                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16455         # on the mdt's osc
16456         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16457         do_facet $SINGLEMDS $LCTL get_param -n \
16458                 osp.$mdtosc_proc1.reserved_mb_high ||
16459                 skip  "remote MDS does not support reserved_mb_high"
16460
16461         rm -rf $DIR/$tdir
16462         wait_mds_ost_sync
16463         wait_delete_completed
16464         mkdir $DIR/$tdir
16465
16466         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16467                         osp.$mdtosc_proc1.reserved_mb_high)
16468         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16469                         osp.$mdtosc_proc1.reserved_mb_low)
16470         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16471
16472         if ! combined_mgs_mds ; then
16473                 mount_mgs_client
16474         fi
16475         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16476         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16477                 error "Adding $ost_name to pool failed"
16478
16479         # Wait for client to see a OST at pool
16480         wait_update $HOSTNAME "$LCTL get_param -n
16481                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16482                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16483                 error "Client can not see the pool"
16484         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16485                 error "Setstripe failed"
16486
16487         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16488         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16489         echo "OST still has $((blocks/1024)) mbytes free"
16490
16491         local new_lwm=$((blocks/1024-10))
16492         do_facet $SINGLEMDS $LCTL set_param \
16493                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16494         do_facet $SINGLEMDS $LCTL set_param \
16495                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16496
16497         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16498
16499         #First enospc could execute orphan deletion so repeat.
16500         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16501
16502         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16503                         osp.$mdtosc_proc1.prealloc_status)
16504         echo "prealloc_status $oa_status"
16505
16506         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16507                 error "File creation should fail"
16508         #object allocation was stopped, but we still able to append files
16509         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16510                 error "Append failed"
16511         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16512
16513         wait_delete_completed
16514
16515         sleep_maxage
16516
16517         for i in $(seq 10 12); do
16518                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16519                         error "File creation failed after rm";
16520         done
16521
16522         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16523                         osp.$mdtosc_proc1.prealloc_status)
16524         echo "prealloc_status $oa_status"
16525
16526         if (( oa_status != 0 )); then
16527                 error "Object allocation still disable after rm"
16528         fi
16529         do_facet $SINGLEMDS $LCTL set_param \
16530                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16531         do_facet $SINGLEMDS $LCTL set_param \
16532                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16533
16534
16535         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16536                 error "Remove $ost_name from pool failed"
16537         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16538                 error "Pool destroy fialed"
16539
16540         if ! combined_mgs_mds ; then
16541                 umount_mgs_client
16542         fi
16543 }
16544 run_test 253 "Check object allocation limit"
16545
16546 test_254() {
16547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16548         remote_mds_nodsh && skip "remote MDS with nodsh"
16549         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16550                 skip "MDS does not support changelog_size"
16551
16552         local cl_user
16553         local MDT0=$(facet_svc $SINGLEMDS)
16554
16555         changelog_register || error "changelog_register failed"
16556
16557         changelog_clear 0 || error "changelog_clear failed"
16558
16559         local size1=$(do_facet $SINGLEMDS \
16560                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16561         echo "Changelog size $size1"
16562
16563         rm -rf $DIR/$tdir
16564         $LFS mkdir -i 0 $DIR/$tdir
16565         # change something
16566         mkdir -p $DIR/$tdir/pics/2008/zachy
16567         touch $DIR/$tdir/pics/2008/zachy/timestamp
16568         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16569         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16570         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16571         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16572         rm $DIR/$tdir/pics/desktop.jpg
16573
16574         local size2=$(do_facet $SINGLEMDS \
16575                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16576         echo "Changelog size after work $size2"
16577
16578         (( $size2 > $size1 )) ||
16579                 error "new Changelog size=$size2 less than old size=$size1"
16580 }
16581 run_test 254 "Check changelog size"
16582
16583 ladvise_no_type()
16584 {
16585         local type=$1
16586         local file=$2
16587
16588         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16589                 awk -F: '{print $2}' | grep $type > /dev/null
16590         if [ $? -ne 0 ]; then
16591                 return 0
16592         fi
16593         return 1
16594 }
16595
16596 ladvise_no_ioctl()
16597 {
16598         local file=$1
16599
16600         lfs ladvise -a willread $file > /dev/null 2>&1
16601         if [ $? -eq 0 ]; then
16602                 return 1
16603         fi
16604
16605         lfs ladvise -a willread $file 2>&1 |
16606                 grep "Inappropriate ioctl for device" > /dev/null
16607         if [ $? -eq 0 ]; then
16608                 return 0
16609         fi
16610         return 1
16611 }
16612
16613 percent() {
16614         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16615 }
16616
16617 # run a random read IO workload
16618 # usage: random_read_iops <filename> <filesize> <iosize>
16619 random_read_iops() {
16620         local file=$1
16621         local fsize=$2
16622         local iosize=${3:-4096}
16623
16624         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16625                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16626 }
16627
16628 drop_file_oss_cache() {
16629         local file="$1"
16630         local nodes="$2"
16631
16632         $LFS ladvise -a dontneed $file 2>/dev/null ||
16633                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16634 }
16635
16636 ladvise_willread_performance()
16637 {
16638         local repeat=10
16639         local average_origin=0
16640         local average_cache=0
16641         local average_ladvise=0
16642
16643         for ((i = 1; i <= $repeat; i++)); do
16644                 echo "Iter $i/$repeat: reading without willread hint"
16645                 cancel_lru_locks osc
16646                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16647                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16648                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16649                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16650
16651                 cancel_lru_locks osc
16652                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16653                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16654                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16655
16656                 cancel_lru_locks osc
16657                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16658                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16659                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16660                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16661                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16662         done
16663         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16664         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16665         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16666
16667         speedup_cache=$(percent $average_cache $average_origin)
16668         speedup_ladvise=$(percent $average_ladvise $average_origin)
16669
16670         echo "Average uncached read: $average_origin"
16671         echo "Average speedup with OSS cached read: " \
16672                 "$average_cache = +$speedup_cache%"
16673         echo "Average speedup with ladvise willread: " \
16674                 "$average_ladvise = +$speedup_ladvise%"
16675
16676         local lowest_speedup=20
16677         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16678                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16679                         "got $average_cache%. Skipping ladvise willread check."
16680                 return 0
16681         fi
16682
16683         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16684         # it is still good to run until then to exercise 'ladvise willread'
16685         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16686                 [ "$ost1_FSTYPE" = "zfs" ] &&
16687                 echo "osd-zfs does not support dontneed or drop_caches" &&
16688                 return 0
16689
16690         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16691         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16692                 error_not_in_vm "Speedup with willread is less than " \
16693                         "$lowest_speedup%, got $average_ladvise%"
16694 }
16695
16696 test_255a() {
16697         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16698                 skip "lustre < 2.8.54 does not support ladvise "
16699         remote_ost_nodsh && skip "remote OST with nodsh"
16700
16701         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16702
16703         ladvise_no_type willread $DIR/$tfile &&
16704                 skip "willread ladvise is not supported"
16705
16706         ladvise_no_ioctl $DIR/$tfile &&
16707                 skip "ladvise ioctl is not supported"
16708
16709         local size_mb=100
16710         local size=$((size_mb * 1048576))
16711         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16712                 error "dd to $DIR/$tfile failed"
16713
16714         lfs ladvise -a willread $DIR/$tfile ||
16715                 error "Ladvise failed with no range argument"
16716
16717         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16718                 error "Ladvise failed with no -l or -e argument"
16719
16720         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16721                 error "Ladvise failed with only -e argument"
16722
16723         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16724                 error "Ladvise failed with only -l argument"
16725
16726         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16727                 error "End offset should not be smaller than start offset"
16728
16729         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16730                 error "End offset should not be equal to start offset"
16731
16732         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16733                 error "Ladvise failed with overflowing -s argument"
16734
16735         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16736                 error "Ladvise failed with overflowing -e argument"
16737
16738         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16739                 error "Ladvise failed with overflowing -l argument"
16740
16741         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16742                 error "Ladvise succeeded with conflicting -l and -e arguments"
16743
16744         echo "Synchronous ladvise should wait"
16745         local delay=4
16746 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16747         do_nodes $(comma_list $(osts_nodes)) \
16748                 $LCTL set_param fail_val=$delay fail_loc=0x237
16749
16750         local start_ts=$SECONDS
16751         lfs ladvise -a willread $DIR/$tfile ||
16752                 error "Ladvise failed with no range argument"
16753         local end_ts=$SECONDS
16754         local inteval_ts=$((end_ts - start_ts))
16755
16756         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16757                 error "Synchronous advice didn't wait reply"
16758         fi
16759
16760         echo "Asynchronous ladvise shouldn't wait"
16761         local start_ts=$SECONDS
16762         lfs ladvise -a willread -b $DIR/$tfile ||
16763                 error "Ladvise failed with no range argument"
16764         local end_ts=$SECONDS
16765         local inteval_ts=$((end_ts - start_ts))
16766
16767         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16768                 error "Asynchronous advice blocked"
16769         fi
16770
16771         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16772         ladvise_willread_performance
16773 }
16774 run_test 255a "check 'lfs ladvise -a willread'"
16775
16776 facet_meminfo() {
16777         local facet=$1
16778         local info=$2
16779
16780         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16781 }
16782
16783 test_255b() {
16784         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16785                 skip "lustre < 2.8.54 does not support ladvise "
16786         remote_ost_nodsh && skip "remote OST with nodsh"
16787
16788         lfs setstripe -c 1 -i 0 $DIR/$tfile
16789
16790         ladvise_no_type dontneed $DIR/$tfile &&
16791                 skip "dontneed ladvise is not supported"
16792
16793         ladvise_no_ioctl $DIR/$tfile &&
16794                 skip "ladvise ioctl is not supported"
16795
16796         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16797                 [ "$ost1_FSTYPE" = "zfs" ] &&
16798                 skip "zfs-osd does not support 'ladvise dontneed'"
16799
16800         local size_mb=100
16801         local size=$((size_mb * 1048576))
16802         # In order to prevent disturbance of other processes, only check 3/4
16803         # of the memory usage
16804         local kibibytes=$((size_mb * 1024 * 3 / 4))
16805
16806         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16807                 error "dd to $DIR/$tfile failed"
16808
16809         #force write to complete before dropping OST cache & checking memory
16810         sync
16811
16812         local total=$(facet_meminfo ost1 MemTotal)
16813         echo "Total memory: $total KiB"
16814
16815         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16816         local before_read=$(facet_meminfo ost1 Cached)
16817         echo "Cache used before read: $before_read KiB"
16818
16819         lfs ladvise -a willread $DIR/$tfile ||
16820                 error "Ladvise willread failed"
16821         local after_read=$(facet_meminfo ost1 Cached)
16822         echo "Cache used after read: $after_read KiB"
16823
16824         lfs ladvise -a dontneed $DIR/$tfile ||
16825                 error "Ladvise dontneed again failed"
16826         local no_read=$(facet_meminfo ost1 Cached)
16827         echo "Cache used after dontneed ladvise: $no_read KiB"
16828
16829         if [ $total -lt $((before_read + kibibytes)) ]; then
16830                 echo "Memory is too small, abort checking"
16831                 return 0
16832         fi
16833
16834         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16835                 error "Ladvise willread should use more memory" \
16836                         "than $kibibytes KiB"
16837         fi
16838
16839         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16840                 error "Ladvise dontneed should release more memory" \
16841                         "than $kibibytes KiB"
16842         fi
16843 }
16844 run_test 255b "check 'lfs ladvise -a dontneed'"
16845
16846 test_255c() {
16847         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16848                 skip "lustre < 2.10.53 does not support lockahead"
16849
16850         local count
16851         local new_count
16852         local difference
16853         local i
16854         local rc
16855
16856         test_mkdir -p $DIR/$tdir
16857         $LFS setstripe -i 0 -c 1 $DIR/$tdir
16858
16859         #test 10 returns only success/failure
16860         i=10
16861         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16862         rc=$?
16863         if [ $rc -eq 255 ]; then
16864                 error "Ladvise test${i} failed, ${rc}"
16865         fi
16866
16867         #test 11 counts lock enqueue requests, all others count new locks
16868         i=11
16869         count=$(do_facet ost1 \
16870                 $LCTL get_param -n ost.OSS.ost.stats)
16871         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16872
16873         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16874         rc=$?
16875         if [ $rc -eq 255 ]; then
16876                 error "Ladvise test${i} failed, ${rc}"
16877         fi
16878
16879         new_count=$(do_facet ost1 \
16880                 $LCTL get_param -n ost.OSS.ost.stats)
16881         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16882                    awk '{ print $2 }')
16883
16884         difference="$((new_count - count))"
16885         if [ $difference -ne $rc ]; then
16886                 error "Ladvise test${i}, bad enqueue count, returned " \
16887                       "${rc}, actual ${difference}"
16888         fi
16889
16890         for i in $(seq 12 21); do
16891                 # If we do not do this, we run the risk of having too many
16892                 # locks and starting lock cancellation while we are checking
16893                 # lock counts.
16894                 cancel_lru_locks osc
16895
16896                 count=$($LCTL get_param -n \
16897                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16898
16899                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16900                 rc=$?
16901                 if [ $rc -eq 255 ]; then
16902                         error "Ladvise test ${i} failed, ${rc}"
16903                 fi
16904
16905                 new_count=$($LCTL get_param -n \
16906                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16907                 difference="$((new_count - count))"
16908
16909                 # Test 15 output is divided by 100 to map down to valid return
16910                 if [ $i -eq 15 ]; then
16911                         rc="$((rc * 100))"
16912                 fi
16913
16914                 if [ $difference -ne $rc ]; then
16915                         error "Ladvise test ${i}, bad lock count, returned " \
16916                               "${rc}, actual ${difference}"
16917                 fi
16918         done
16919
16920         #test 22 returns only success/failure
16921         i=22
16922         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16923         rc=$?
16924         if [ $rc -eq 255 ]; then
16925                 error "Ladvise test${i} failed, ${rc}"
16926         fi
16927 }
16928 run_test 255c "suite of ladvise lockahead tests"
16929
16930 test_256() {
16931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16932         remote_mds_nodsh && skip "remote MDS with nodsh"
16933         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16934         changelog_users $SINGLEMDS | grep "^cl" &&
16935                 skip "active changelog user"
16936
16937         local cl_user
16938         local cat_sl
16939         local mdt_dev
16940
16941         mdt_dev=$(mdsdevname 1)
16942         echo $mdt_dev
16943
16944         changelog_register || error "changelog_register failed"
16945
16946         rm -rf $DIR/$tdir
16947         mkdir -p $DIR/$tdir
16948
16949         changelog_clear 0 || error "changelog_clear failed"
16950
16951         # change something
16952         touch $DIR/$tdir/{1..10}
16953
16954         # stop the MDT
16955         stop $SINGLEMDS || error "Fail to stop MDT"
16956
16957         # remount the MDT
16958
16959         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16960
16961         #after mount new plainllog is used
16962         touch $DIR/$tdir/{11..19}
16963         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16964         cat_sl=$(do_facet $SINGLEMDS "sync; \
16965                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16966                  llog_reader $tmpfile | grep -c type=1064553b")
16967         do_facet $SINGLEMDS llog_reader $tmpfile
16968
16969         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16970
16971         changelog_clear 0 || error "changelog_clear failed"
16972
16973         cat_sl=$(do_facet $SINGLEMDS "sync; \
16974                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16975                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16976
16977         if (( cat_sl == 2 )); then
16978                 error "Empty plain llog was not deleted from changelog catalog"
16979         elif (( cat_sl != 1 )); then
16980                 error "Active plain llog shouldn't be deleted from catalog"
16981         fi
16982 }
16983 run_test 256 "Check llog delete for empty and not full state"
16984
16985 test_257() {
16986         remote_mds_nodsh && skip "remote MDS with nodsh"
16987         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16988                 skip "Need MDS version at least 2.8.55"
16989
16990         test_mkdir $DIR/$tdir
16991
16992         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16993                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16994         stat $DIR/$tdir
16995
16996 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16997         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16998         local facet=mds$((mdtidx + 1))
16999         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17000         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17001
17002         stop $facet || error "stop MDS failed"
17003         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17004                 error "start MDS fail"
17005         wait_recovery_complete $facet
17006 }
17007 run_test 257 "xattr locks are not lost"
17008
17009 # Verify we take the i_mutex when security requires it
17010 test_258a() {
17011 #define OBD_FAIL_IMUTEX_SEC 0x141c
17012         $LCTL set_param fail_loc=0x141c
17013         touch $DIR/$tfile
17014         chmod u+s $DIR/$tfile
17015         chmod a+rwx $DIR/$tfile
17016         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17017         RC=$?
17018         if [ $RC -ne 0 ]; then
17019                 error "error, failed to take i_mutex, rc=$?"
17020         fi
17021         rm -f $DIR/$tfile
17022 }
17023 run_test 258a
17024
17025 # Verify we do NOT take the i_mutex in the normal case
17026 test_258b() {
17027 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17028         $LCTL set_param fail_loc=0x141d
17029         touch $DIR/$tfile
17030         chmod a+rwx $DIR
17031         chmod a+rw $DIR/$tfile
17032         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17033         RC=$?
17034         if [ $RC -ne 0 ]; then
17035                 error "error, took i_mutex unnecessarily, rc=$?"
17036         fi
17037         rm -f $DIR/$tfile
17038
17039 }
17040 run_test 258b "verify i_mutex security behavior"
17041
17042 test_259() {
17043         local file=$DIR/$tfile
17044         local before
17045         local after
17046
17047         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17048
17049         stack_trap "rm -f $file" EXIT
17050
17051         wait_delete_completed
17052         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17053         echo "before: $before"
17054
17055         $LFS setstripe -i 0 -c 1 $file
17056         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17057         sync_all_data
17058         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17059         echo "after write: $after"
17060
17061 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17062         do_facet ost1 $LCTL set_param fail_loc=0x2301
17063         $TRUNCATE $file 0
17064         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17065         echo "after truncate: $after"
17066
17067         stop ost1
17068         do_facet ost1 $LCTL set_param fail_loc=0
17069         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17070         sleep 2
17071         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17072         echo "after restart: $after"
17073         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17074                 error "missing truncate?"
17075
17076         return 0
17077 }
17078 run_test 259 "crash at delayed truncate"
17079
17080 test_260() {
17081 #define OBD_FAIL_MDC_CLOSE               0x806
17082         $LCTL set_param fail_loc=0x80000806
17083         touch $DIR/$tfile
17084
17085 }
17086 run_test 260 "Check mdc_close fail"
17087
17088 ### Data-on-MDT sanity tests ###
17089 test_270a() {
17090         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17091                 skip "Need MDS version at least 2.10.55 for DoM"
17092
17093         # create DoM file
17094         local dom=$DIR/$tdir/dom_file
17095         local tmp=$DIR/$tdir/tmp_file
17096
17097         mkdir -p $DIR/$tdir
17098
17099         # basic checks for DoM component creation
17100         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17101                 error "Can set MDT layout to non-first entry"
17102
17103         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17104                 error "Can define multiple entries as MDT layout"
17105
17106         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17107
17108         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17109         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17110         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17111
17112         local mdtidx=$($LFS getstripe -m $dom)
17113         local mdtname=MDT$(printf %04x $mdtidx)
17114         local facet=mds$((mdtidx + 1))
17115         local space_check=1
17116
17117         # Skip free space checks with ZFS
17118         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17119
17120         # write
17121         sync
17122         local size_tmp=$((65536 * 3))
17123         local mdtfree1=$(do_facet $facet \
17124                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17125
17126         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17127         # check also direct IO along write
17128         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17129         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17130         sync
17131         cmp $tmp $dom || error "file data is different"
17132         [ $(stat -c%s $dom) == $size_tmp ] ||
17133                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17134         if [ $space_check == 1 ]; then
17135                 local mdtfree2=$(do_facet $facet \
17136                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17137
17138                 # increase in usage from by $size_tmp
17139                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17140                         error "MDT free space wrong after write: " \
17141                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17142         fi
17143
17144         # truncate
17145         local size_dom=10000
17146
17147         $TRUNCATE $dom $size_dom
17148         [ $(stat -c%s $dom) == $size_dom ] ||
17149                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17150         if [ $space_check == 1 ]; then
17151                 mdtfree1=$(do_facet $facet \
17152                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17153                 # decrease in usage from $size_tmp to new $size_dom
17154                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17155                   $(((size_tmp - size_dom) / 1024)) ] ||
17156                         error "MDT free space is wrong after truncate: " \
17157                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17158         fi
17159
17160         # append
17161         cat $tmp >> $dom
17162         sync
17163         size_dom=$((size_dom + size_tmp))
17164         [ $(stat -c%s $dom) == $size_dom ] ||
17165                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17166         if [ $space_check == 1 ]; then
17167                 mdtfree2=$(do_facet $facet \
17168                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17169                 # increase in usage by $size_tmp from previous
17170                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17171                         error "MDT free space is wrong after append: " \
17172                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17173         fi
17174
17175         # delete
17176         rm $dom
17177         if [ $space_check == 1 ]; then
17178                 mdtfree1=$(do_facet $facet \
17179                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17180                 # decrease in usage by $size_dom from previous
17181                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17182                         error "MDT free space is wrong after removal: " \
17183                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17184         fi
17185
17186         # combined striping
17187         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17188                 error "Can't create DoM + OST striping"
17189
17190         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17191         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17192         # check also direct IO along write
17193         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17194         sync
17195         cmp $tmp $dom || error "file data is different"
17196         [ $(stat -c%s $dom) == $size_tmp ] ||
17197                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17198         rm $dom $tmp
17199
17200         return 0
17201 }
17202 run_test 270a "DoM: basic functionality tests"
17203
17204 test_270b() {
17205         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17206                 skip "Need MDS version at least 2.10.55"
17207
17208         local dom=$DIR/$tdir/dom_file
17209         local max_size=1048576
17210
17211         mkdir -p $DIR/$tdir
17212         $LFS setstripe -E $max_size -L mdt $dom
17213
17214         # truncate over the limit
17215         $TRUNCATE $dom $(($max_size + 1)) &&
17216                 error "successful truncate over the maximum size"
17217         # write over the limit
17218         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17219                 error "successful write over the maximum size"
17220         # append over the limit
17221         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17222         echo "12345" >> $dom && error "successful append over the maximum size"
17223         rm $dom
17224
17225         return 0
17226 }
17227 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17228
17229 test_270c() {
17230         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17231                 skip "Need MDS version at least 2.10.55"
17232
17233         mkdir -p $DIR/$tdir
17234         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17235
17236         # check files inherit DoM EA
17237         touch $DIR/$tdir/first
17238         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17239                 error "bad pattern"
17240         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17241                 error "bad stripe count"
17242         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17243                 error "bad stripe size"
17244
17245         # check directory inherits DoM EA and uses it as default
17246         mkdir $DIR/$tdir/subdir
17247         touch $DIR/$tdir/subdir/second
17248         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17249                 error "bad pattern in sub-directory"
17250         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17251                 error "bad stripe count in sub-directory"
17252         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17253                 error "bad stripe size in sub-directory"
17254         return 0
17255 }
17256 run_test 270c "DoM: DoM EA inheritance tests"
17257
17258 test_270d() {
17259         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17260                 skip "Need MDS version at least 2.10.55"
17261
17262         mkdir -p $DIR/$tdir
17263         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17264
17265         # inherit default DoM striping
17266         mkdir $DIR/$tdir/subdir
17267         touch $DIR/$tdir/subdir/f1
17268
17269         # change default directory striping
17270         $LFS setstripe -c 1 $DIR/$tdir/subdir
17271         touch $DIR/$tdir/subdir/f2
17272         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17273                 error "wrong default striping in file 2"
17274         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17275                 error "bad pattern in file 2"
17276         return 0
17277 }
17278 run_test 270d "DoM: change striping from DoM to RAID0"
17279
17280 test_270e() {
17281         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17282                 skip "Need MDS version at least 2.10.55"
17283
17284         mkdir -p $DIR/$tdir/dom
17285         mkdir -p $DIR/$tdir/norm
17286         DOMFILES=20
17287         NORMFILES=10
17288         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17289         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17290
17291         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17292         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17293
17294         # find DoM files by layout
17295         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17296         [ $NUM -eq  $DOMFILES ] ||
17297                 error "lfs find -L: found $NUM, expected $DOMFILES"
17298         echo "Test 1: lfs find 20 DOM files by layout: OK"
17299
17300         # there should be 1 dir with default DOM striping
17301         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17302         [ $NUM -eq  1 ] ||
17303                 error "lfs find -L: found $NUM, expected 1 dir"
17304         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17305
17306         # find DoM files by stripe size
17307         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17308         [ $NUM -eq  $DOMFILES ] ||
17309                 error "lfs find -S: found $NUM, expected $DOMFILES"
17310         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17311
17312         # find files by stripe offset except DoM files
17313         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17314         [ $NUM -eq  $NORMFILES ] ||
17315                 error "lfs find -i: found $NUM, expected $NORMFILES"
17316         echo "Test 5: lfs find no DOM files by stripe index: OK"
17317         return 0
17318 }
17319 run_test 270e "DoM: lfs find with DoM files test"
17320
17321 test_270f() {
17322         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17323                 skip "Need MDS version at least 2.10.55"
17324
17325         local mdtname=${FSNAME}-MDT0000-mdtlov
17326         local dom=$DIR/$tdir/dom_file
17327         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17328                                                 lod.$mdtname.dom_stripesize)
17329         local dom_limit=131072
17330
17331         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17332         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17333                                                 lod.$mdtname.dom_stripesize)
17334         [ ${dom_limit} -eq ${dom_current} ] ||
17335                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17336
17337         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17338         $LFS setstripe -d $DIR/$tdir
17339         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17340                 error "Can't set directory default striping"
17341
17342         # exceed maximum stripe size
17343         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17344                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17345         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17346                 error "Able to create DoM component size more than LOD limit"
17347
17348         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17349         dom_current=$(do_facet mds1 $LCTL get_param -n \
17350                                                 lod.$mdtname.dom_stripesize)
17351         [ 0 -eq ${dom_current} ] ||
17352                 error "Can't set zero DoM stripe limit"
17353         rm $dom
17354
17355         # attempt to create DoM file on server with disabled DoM should
17356         # remove DoM entry from layout and be succeed
17357         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17358                 error "Can't create DoM file (DoM is disabled)"
17359         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17360                 error "File has DoM component while DoM is disabled"
17361         rm $dom
17362
17363         # attempt to create DoM file with only DoM stripe should return error
17364         $LFS setstripe -E $dom_limit -L mdt $dom &&
17365                 error "Able to create DoM-only file while DoM is disabled"
17366
17367         # too low values to be aligned with smallest stripe size 64K
17368         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17369         dom_current=$(do_facet mds1 $LCTL get_param -n \
17370                                                 lod.$mdtname.dom_stripesize)
17371         [ 30000 -eq ${dom_current} ] &&
17372                 error "Can set too small DoM stripe limit"
17373
17374         # 64K is a minimal stripe size in Lustre, expect limit of that size
17375         [ 65536 -eq ${dom_current} ] ||
17376                 error "Limit is not set to 64K but ${dom_current}"
17377
17378         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17379         dom_current=$(do_facet mds1 $LCTL get_param -n \
17380                                                 lod.$mdtname.dom_stripesize)
17381         echo $dom_current
17382         [ 2147483648 -eq ${dom_current} ] &&
17383                 error "Can set too large DoM stripe limit"
17384
17385         do_facet mds1 $LCTL set_param -n \
17386                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17387         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17388                 error "Can't create DoM component size after limit change"
17389         do_facet mds1 $LCTL set_param -n \
17390                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17391         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17392                 error "Can't create DoM file after limit decrease"
17393         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17394                 error "Can create big DoM component after limit decrease"
17395         touch ${dom}_def ||
17396                 error "Can't create file with old default layout"
17397
17398         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17399         return 0
17400 }
17401 run_test 270f "DoM: maximum DoM stripe size checks"
17402
17403 test_271a() {
17404         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17405                 skip "Need MDS version at least 2.10.55"
17406
17407         local dom=$DIR/$tdir/dom
17408
17409         mkdir -p $DIR/$tdir
17410
17411         $LFS setstripe -E 1024K -L mdt $dom
17412
17413         lctl set_param -n mdc.*.stats=clear
17414         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17415         cat $dom > /dev/null
17416         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17417         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17418         ls $dom
17419         rm -f $dom
17420 }
17421 run_test 271a "DoM: data is cached for read after write"
17422
17423 test_271b() {
17424         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17425                 skip "Need MDS version at least 2.10.55"
17426
17427         local dom=$DIR/$tdir/dom
17428
17429         mkdir -p $DIR/$tdir
17430
17431         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17432
17433         lctl set_param -n mdc.*.stats=clear
17434         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17435         cancel_lru_locks mdc
17436         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17437         # second stat to check size is cached on client
17438         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17439         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17440         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17441         rm -f $dom
17442 }
17443 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17444
17445 test_271ba() {
17446         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17447                 skip "Need MDS version at least 2.10.55"
17448
17449         local dom=$DIR/$tdir/dom
17450
17451         mkdir -p $DIR/$tdir
17452
17453         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17454
17455         lctl set_param -n mdc.*.stats=clear
17456         lctl set_param -n osc.*.stats=clear
17457         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17458         cancel_lru_locks mdc
17459         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17460         # second stat to check size is cached on client
17461         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17462         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17463         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17464         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17465         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17466         rm -f $dom
17467 }
17468 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17469
17470
17471 get_mdc_stats() {
17472         local mdtidx=$1
17473         local param=$2
17474         local mdt=MDT$(printf %04x $mdtidx)
17475
17476         if [ -z $param ]; then
17477                 lctl get_param -n mdc.*$mdt*.stats
17478         else
17479                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17480         fi
17481 }
17482
17483 test_271c() {
17484         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17485                 skip "Need MDS version at least 2.10.55"
17486
17487         local dom=$DIR/$tdir/dom
17488
17489         mkdir -p $DIR/$tdir
17490
17491         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17492
17493         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17494         local facet=mds$((mdtidx + 1))
17495
17496         cancel_lru_locks mdc
17497         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17498         createmany -o $dom 1000
17499         lctl set_param -n mdc.*.stats=clear
17500         smalliomany -w $dom 1000 200
17501         get_mdc_stats $mdtidx
17502         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17503         # Each file has 1 open, 1 IO enqueues, total 2000
17504         # but now we have also +1 getxattr for security.capability, total 3000
17505         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17506         unlinkmany $dom 1000
17507
17508         cancel_lru_locks mdc
17509         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17510         createmany -o $dom 1000
17511         lctl set_param -n mdc.*.stats=clear
17512         smalliomany -w $dom 1000 200
17513         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17514         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17515         # for OPEN and IO lock.
17516         [ $((enq - enq_2)) -ge 1000 ] ||
17517                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17518         unlinkmany $dom 1000
17519         return 0
17520 }
17521 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17522
17523 cleanup_271def_tests() {
17524         trap 0
17525         rm -f $1
17526 }
17527
17528 test_271d() {
17529         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17530                 skip "Need MDS version at least 2.10.57"
17531
17532         local dom=$DIR/$tdir/dom
17533         local tmp=$TMP/$tfile
17534         trap "cleanup_271def_tests $tmp" EXIT
17535
17536         mkdir -p $DIR/$tdir
17537
17538         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17539
17540         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17541
17542         cancel_lru_locks mdc
17543         dd if=/dev/urandom of=$tmp bs=1000 count=1
17544         dd if=$tmp of=$dom bs=1000 count=1
17545         cancel_lru_locks mdc
17546
17547         cat /etc/hosts >> $tmp
17548         lctl set_param -n mdc.*.stats=clear
17549
17550         # append data to the same file it should update local page
17551         echo "Append to the same page"
17552         cat /etc/hosts >> $dom
17553         local num=$(get_mdc_stats $mdtidx ost_read)
17554         local ra=$(get_mdc_stats $mdtidx req_active)
17555         local rw=$(get_mdc_stats $mdtidx req_waittime)
17556
17557         [ -z $num ] || error "$num READ RPC occured"
17558         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17559         echo "... DONE"
17560
17561         # compare content
17562         cmp $tmp $dom || error "file miscompare"
17563
17564         cancel_lru_locks mdc
17565         lctl set_param -n mdc.*.stats=clear
17566
17567         echo "Open and read file"
17568         cat $dom > /dev/null
17569         local num=$(get_mdc_stats $mdtidx ost_read)
17570         local ra=$(get_mdc_stats $mdtidx req_active)
17571         local rw=$(get_mdc_stats $mdtidx req_waittime)
17572
17573         [ -z $num ] || error "$num READ RPC occured"
17574         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17575         echo "... DONE"
17576
17577         # compare content
17578         cmp $tmp $dom || error "file miscompare"
17579
17580         return 0
17581 }
17582 run_test 271d "DoM: read on open (1K file in reply buffer)"
17583
17584 test_271f() {
17585         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17586                 skip "Need MDS version at least 2.10.57"
17587
17588         local dom=$DIR/$tdir/dom
17589         local tmp=$TMP/$tfile
17590         trap "cleanup_271def_tests $tmp" EXIT
17591
17592         mkdir -p $DIR/$tdir
17593
17594         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17595
17596         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17597
17598         cancel_lru_locks mdc
17599         dd if=/dev/urandom of=$tmp bs=200000 count=1
17600         dd if=$tmp of=$dom bs=200000 count=1
17601         cancel_lru_locks mdc
17602         cat /etc/hosts >> $tmp
17603         lctl set_param -n mdc.*.stats=clear
17604
17605         echo "Append to the same page"
17606         cat /etc/hosts >> $dom
17607         local num=$(get_mdc_stats $mdtidx ost_read)
17608         local ra=$(get_mdc_stats $mdtidx req_active)
17609         local rw=$(get_mdc_stats $mdtidx req_waittime)
17610
17611         [ -z $num ] || error "$num READ RPC occured"
17612         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17613         echo "... DONE"
17614
17615         # compare content
17616         cmp $tmp $dom || error "file miscompare"
17617
17618         cancel_lru_locks mdc
17619         lctl set_param -n mdc.*.stats=clear
17620
17621         echo "Open and read file"
17622         cat $dom > /dev/null
17623         local num=$(get_mdc_stats $mdtidx ost_read)
17624         local ra=$(get_mdc_stats $mdtidx req_active)
17625         local rw=$(get_mdc_stats $mdtidx req_waittime)
17626
17627         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17628         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17629         echo "... DONE"
17630
17631         # compare content
17632         cmp $tmp $dom || error "file miscompare"
17633
17634         return 0
17635 }
17636 run_test 271f "DoM: read on open (200K file and read tail)"
17637
17638 test_272a() {
17639         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17640                 skip "Need MDS version at least 2.11.50"
17641
17642         local dom=$DIR/$tdir/dom
17643         mkdir -p $DIR/$tdir
17644
17645         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17646         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17647                 error "failed to write data into $dom"
17648         local old_md5=$(md5sum $dom)
17649
17650         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17651                 error "failed to migrate to the same DoM component"
17652
17653         local new_md5=$(md5sum $dom)
17654
17655         [ "$old_md5" == "$new_md5" ] ||
17656                 error "md5sum differ: $old_md5, $new_md5"
17657
17658         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17659                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17660 }
17661 run_test 272a "DoM migration: new layout with the same DOM component"
17662
17663 test_272b() {
17664         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17665                 skip "Need MDS version at least 2.11.50"
17666
17667         local dom=$DIR/$tdir/dom
17668         mkdir -p $DIR/$tdir
17669         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17670
17671         local mdtidx=$($LFS getstripe -m $dom)
17672         local mdtname=MDT$(printf %04x $mdtidx)
17673         local facet=mds$((mdtidx + 1))
17674
17675         local mdtfree1=$(do_facet $facet \
17676                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17677         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17678                 error "failed to write data into $dom"
17679         local old_md5=$(md5sum $dom)
17680         cancel_lru_locks mdc
17681         local mdtfree1=$(do_facet $facet \
17682                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17683
17684         $LFS migrate -c2 $dom ||
17685                 error "failed to migrate to the new composite layout"
17686         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17687                 error "MDT stripe was not removed"
17688
17689         cancel_lru_locks mdc
17690         local new_md5=$(md5sum $dom)
17691         [ "$old_md5" != "$new_md5" ] &&
17692                 error "$old_md5 != $new_md5"
17693
17694         # Skip free space checks with ZFS
17695         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17696                 local mdtfree2=$(do_facet $facet \
17697                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17698                 [ $mdtfree2 -gt $mdtfree1 ] ||
17699                         error "MDT space is not freed after migration"
17700         fi
17701         return 0
17702 }
17703 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17704
17705 test_272c() {
17706         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17707                 skip "Need MDS version at least 2.11.50"
17708
17709         local dom=$DIR/$tdir/$tfile
17710         mkdir -p $DIR/$tdir
17711         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17712
17713         local mdtidx=$($LFS getstripe -m $dom)
17714         local mdtname=MDT$(printf %04x $mdtidx)
17715         local facet=mds$((mdtidx + 1))
17716
17717         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17718                 error "failed to write data into $dom"
17719         local old_md5=$(md5sum $dom)
17720         cancel_lru_locks mdc
17721         local mdtfree1=$(do_facet $facet \
17722                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17723
17724         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17725                 error "failed to migrate to the new composite layout"
17726         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17727                 error "MDT stripe was not removed"
17728
17729         cancel_lru_locks mdc
17730         local new_md5=$(md5sum $dom)
17731         [ "$old_md5" != "$new_md5" ] &&
17732                 error "$old_md5 != $new_md5"
17733
17734         # Skip free space checks with ZFS
17735         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17736                 local mdtfree2=$(do_facet $facet \
17737                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17738                 [ $mdtfree2 -gt $mdtfree1 ] ||
17739                         error "MDS space is not freed after migration"
17740         fi
17741         return 0
17742 }
17743 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17744
17745 test_273a() {
17746         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17747                 skip "Need MDS version at least 2.11.50"
17748
17749         # Layout swap cannot be done if either file has DOM component,
17750         # this will never be supported, migration should be used instead
17751
17752         local dom=$DIR/$tdir/$tfile
17753         mkdir -p $DIR/$tdir
17754
17755         $LFS setstripe -c2 ${dom}_plain
17756         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17757         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17758                 error "can swap layout with DoM component"
17759         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17760                 error "can swap layout with DoM component"
17761
17762         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17763         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17764                 error "can swap layout with DoM component"
17765         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17766                 error "can swap layout with DoM component"
17767         return 0
17768 }
17769 run_test 273a "DoM: layout swapping should fail with DOM"
17770
17771 test_275() {
17772         remote_ost_nodsh && skip "remote OST with nodsh"
17773         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17774                 skip "Need OST version >= 2.10.57"
17775
17776         local file=$DIR/$tfile
17777         local oss
17778
17779         oss=$(comma_list $(osts_nodes))
17780
17781         dd if=/dev/urandom of=$file bs=1M count=2 ||
17782                 error "failed to create a file"
17783         cancel_lru_locks osc
17784
17785         #lock 1
17786         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17787                 error "failed to read a file"
17788
17789 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17790         $LCTL set_param fail_loc=0x8000031f
17791
17792         cancel_lru_locks osc &
17793         sleep 1
17794
17795 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17796         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17797         #IO takes another lock, but matches the PENDING one
17798         #and places it to the IO RPC
17799         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17800                 error "failed to read a file with PENDING lock"
17801 }
17802 run_test 275 "Read on a canceled duplicate lock"
17803
17804 test_276() {
17805         remote_ost_nodsh && skip "remote OST with nodsh"
17806         local pid
17807
17808         do_facet ost1 "(while true; do \
17809                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17810                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17811         pid=$!
17812
17813         for LOOP in $(seq 20); do
17814                 stop ost1
17815                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17816         done
17817         kill -9 $pid
17818         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17819                 rm $TMP/sanity_276_pid"
17820 }
17821 run_test 276 "Race between mount and obd_statfs"
17822
17823 cleanup_test_300() {
17824         trap 0
17825         umask $SAVE_UMASK
17826 }
17827 test_striped_dir() {
17828         local mdt_index=$1
17829         local stripe_count
17830         local stripe_index
17831
17832         mkdir -p $DIR/$tdir
17833
17834         SAVE_UMASK=$(umask)
17835         trap cleanup_test_300 RETURN EXIT
17836
17837         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17838                                                 $DIR/$tdir/striped_dir ||
17839                 error "set striped dir error"
17840
17841         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17842         [ "$mode" = "755" ] || error "expect 755 got $mode"
17843
17844         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17845                 error "getdirstripe failed"
17846         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17847         if [ "$stripe_count" != "2" ]; then
17848                 error "1:stripe_count is $stripe_count, expect 2"
17849         fi
17850         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17851         if [ "$stripe_count" != "2" ]; then
17852                 error "2:stripe_count is $stripe_count, expect 2"
17853         fi
17854
17855         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17856         if [ "$stripe_index" != "$mdt_index" ]; then
17857                 error "stripe_index is $stripe_index, expect $mdt_index"
17858         fi
17859
17860         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17861                 error "nlink error after create striped dir"
17862
17863         mkdir $DIR/$tdir/striped_dir/a
17864         mkdir $DIR/$tdir/striped_dir/b
17865
17866         stat $DIR/$tdir/striped_dir/a ||
17867                 error "create dir under striped dir failed"
17868         stat $DIR/$tdir/striped_dir/b ||
17869                 error "create dir under striped dir failed"
17870
17871         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17872                 error "nlink error after mkdir"
17873
17874         rmdir $DIR/$tdir/striped_dir/a
17875         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17876                 error "nlink error after rmdir"
17877
17878         rmdir $DIR/$tdir/striped_dir/b
17879         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17880                 error "nlink error after rmdir"
17881
17882         chattr +i $DIR/$tdir/striped_dir
17883         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17884                 error "immutable flags not working under striped dir!"
17885         chattr -i $DIR/$tdir/striped_dir
17886
17887         rmdir $DIR/$tdir/striped_dir ||
17888                 error "rmdir striped dir error"
17889
17890         cleanup_test_300
17891
17892         true
17893 }
17894
17895 test_300a() {
17896         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17897                 skip "skipped for lustre < 2.7.0"
17898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17900
17901         test_striped_dir 0 || error "failed on striped dir on MDT0"
17902         test_striped_dir 1 || error "failed on striped dir on MDT0"
17903 }
17904 run_test 300a "basic striped dir sanity test"
17905
17906 test_300b() {
17907         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17908                 skip "skipped for lustre < 2.7.0"
17909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17910         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17911
17912         local i
17913         local mtime1
17914         local mtime2
17915         local mtime3
17916
17917         test_mkdir $DIR/$tdir || error "mkdir fail"
17918         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17919                 error "set striped dir error"
17920         for i in {0..9}; do
17921                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17922                 sleep 1
17923                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17924                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17925                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17926                 sleep 1
17927                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17928                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17929                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17930         done
17931         true
17932 }
17933 run_test 300b "check ctime/mtime for striped dir"
17934
17935 test_300c() {
17936         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17937                 skip "skipped for lustre < 2.7.0"
17938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17940
17941         local file_count
17942
17943         mkdir -p $DIR/$tdir
17944         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17945                 error "set striped dir error"
17946
17947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17948                 error "chown striped dir failed"
17949
17950         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17951                 error "create 5k files failed"
17952
17953         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17954
17955         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17956
17957         rm -rf $DIR/$tdir
17958 }
17959 run_test 300c "chown && check ls under striped directory"
17960
17961 test_300d() {
17962         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17963                 skip "skipped for lustre < 2.7.0"
17964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17965         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17966
17967         local stripe_count
17968         local file
17969
17970         mkdir -p $DIR/$tdir
17971         $LFS setstripe -c 2 $DIR/$tdir
17972
17973         #local striped directory
17974         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17975                 error "set striped dir error"
17976         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17977                 error "create 10 files failed"
17978
17979         #remote striped directory
17980         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17981                 error "set striped dir error"
17982         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17983                 error "create 10 files failed"
17984
17985         for file in $(find $DIR/$tdir); do
17986                 stripe_count=$($LFS getstripe -c $file)
17987                 [ $stripe_count -eq 2 ] ||
17988                         error "wrong stripe $stripe_count for $file"
17989         done
17990
17991         rm -rf $DIR/$tdir
17992 }
17993 run_test 300d "check default stripe under striped directory"
17994
17995 test_300e() {
17996         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17997                 skip "Need MDS version at least 2.7.55"
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18000
18001         local stripe_count
18002         local file
18003
18004         mkdir -p $DIR/$tdir
18005
18006         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18007                 error "set striped dir error"
18008
18009         touch $DIR/$tdir/striped_dir/a
18010         touch $DIR/$tdir/striped_dir/b
18011         touch $DIR/$tdir/striped_dir/c
18012
18013         mkdir $DIR/$tdir/striped_dir/dir_a
18014         mkdir $DIR/$tdir/striped_dir/dir_b
18015         mkdir $DIR/$tdir/striped_dir/dir_c
18016
18017         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18018                 error "set striped adir under striped dir error"
18019
18020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18021                 error "set striped bdir under striped dir error"
18022
18023         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18024                 error "set striped cdir under striped dir error"
18025
18026         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18027                 error "rename dir under striped dir fails"
18028
18029         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18030                 error "rename dir under different stripes fails"
18031
18032         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18033                 error "rename file under striped dir should succeed"
18034
18035         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18036                 error "rename dir under striped dir should succeed"
18037
18038         rm -rf $DIR/$tdir
18039 }
18040 run_test 300e "check rename under striped directory"
18041
18042 test_300f() {
18043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18044         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18045         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18046                 skip "Need MDS version at least 2.7.55"
18047
18048         local stripe_count
18049         local file
18050
18051         rm -rf $DIR/$tdir
18052         mkdir -p $DIR/$tdir
18053
18054         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18055                 error "set striped dir error"
18056
18057         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18058                 error "set striped dir error"
18059
18060         touch $DIR/$tdir/striped_dir/a
18061         mkdir $DIR/$tdir/striped_dir/dir_a
18062         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18063                 error "create striped dir under striped dir fails"
18064
18065         touch $DIR/$tdir/striped_dir1/b
18066         mkdir $DIR/$tdir/striped_dir1/dir_b
18067         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18068                 error "create striped dir under striped dir fails"
18069
18070         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18071                 error "rename dir under different striped dir should fail"
18072
18073         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18074                 error "rename striped dir under diff striped dir should fail"
18075
18076         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18077                 error "rename file under diff striped dirs fails"
18078
18079         rm -rf $DIR/$tdir
18080 }
18081 run_test 300f "check rename cross striped directory"
18082
18083 test_300_check_default_striped_dir()
18084 {
18085         local dirname=$1
18086         local default_count=$2
18087         local default_index=$3
18088         local stripe_count
18089         local stripe_index
18090         local dir_stripe_index
18091         local dir
18092
18093         echo "checking $dirname $default_count $default_index"
18094         $LFS setdirstripe -D -c $default_count -i $default_index \
18095                                 -t all_char $DIR/$tdir/$dirname ||
18096                 error "set default stripe on striped dir error"
18097         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18098         [ $stripe_count -eq $default_count ] ||
18099                 error "expect $default_count get $stripe_count for $dirname"
18100
18101         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18102         [ $stripe_index -eq $default_index ] ||
18103                 error "expect $default_index get $stripe_index for $dirname"
18104
18105         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18106                                                 error "create dirs failed"
18107
18108         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18109         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18110         for dir in $(find $DIR/$tdir/$dirname/*); do
18111                 stripe_count=$($LFS getdirstripe -c $dir)
18112                 [ $stripe_count -eq $default_count ] ||
18113                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18114                 error "stripe count $default_count != $stripe_count for $dir"
18115
18116                 stripe_index=$($LFS getdirstripe -i $dir)
18117                 [ $default_index -eq -1 ] ||
18118                         [ $stripe_index -eq $default_index ] ||
18119                         error "$stripe_index != $default_index for $dir"
18120
18121                 #check default stripe
18122                 stripe_count=$($LFS getdirstripe -D -c $dir)
18123                 [ $stripe_count -eq $default_count ] ||
18124                 error "default count $default_count != $stripe_count for $dir"
18125
18126                 stripe_index=$($LFS getdirstripe -D -i $dir)
18127                 [ $stripe_index -eq $default_index ] ||
18128                 error "default index $default_index != $stripe_index for $dir"
18129         done
18130         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18131 }
18132
18133 test_300g() {
18134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18135         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18136                 skip "Need MDS version at least 2.7.55"
18137
18138         local dir
18139         local stripe_count
18140         local stripe_index
18141
18142         mkdir $DIR/$tdir
18143         mkdir $DIR/$tdir/normal_dir
18144
18145         #Checking when client cache stripe index
18146         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18147         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18148                 error "create striped_dir failed"
18149
18150         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18151                 error "create dir0 fails"
18152         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18153         [ $stripe_index -eq 0 ] ||
18154                 error "dir0 expect index 0 got $stripe_index"
18155
18156         mkdir $DIR/$tdir/striped_dir/dir1 ||
18157                 error "create dir1 fails"
18158         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18159         [ $stripe_index -eq 1 ] ||
18160                 error "dir1 expect index 1 got $stripe_index"
18161
18162         #check default stripe count/stripe index
18163         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18164         test_300_check_default_striped_dir normal_dir 1 0
18165         test_300_check_default_striped_dir normal_dir 2 1
18166         test_300_check_default_striped_dir normal_dir 2 -1
18167
18168         #delete default stripe information
18169         echo "delete default stripeEA"
18170         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18171                 error "set default stripe on striped dir error"
18172
18173         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18174         for dir in $(find $DIR/$tdir/normal_dir/*); do
18175                 stripe_count=$($LFS getdirstripe -c $dir)
18176                 [ $stripe_count -eq 0 ] ||
18177                         error "expect 1 get $stripe_count for $dir"
18178                 stripe_index=$($LFS getdirstripe -i $dir)
18179                 [ $stripe_index -eq 0 ] ||
18180                         error "expect 0 get $stripe_index for $dir"
18181         done
18182 }
18183 run_test 300g "check default striped directory for normal directory"
18184
18185 test_300h() {
18186         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18187         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18188                 skip "Need MDS version at least 2.7.55"
18189
18190         local dir
18191         local stripe_count
18192
18193         mkdir $DIR/$tdir
18194         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18195                 error "set striped dir error"
18196
18197         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18198         test_300_check_default_striped_dir striped_dir 1 0
18199         test_300_check_default_striped_dir striped_dir 2 1
18200         test_300_check_default_striped_dir striped_dir 2 -1
18201
18202         #delete default stripe information
18203         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18204                 error "set default stripe on striped dir error"
18205
18206         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18207         for dir in $(find $DIR/$tdir/striped_dir/*); do
18208                 stripe_count=$($LFS getdirstripe -c $dir)
18209                 [ $stripe_count -eq 0 ] ||
18210                         error "expect 1 get $stripe_count for $dir"
18211         done
18212 }
18213 run_test 300h "check default striped directory for striped directory"
18214
18215 test_300i() {
18216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18217         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18218         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18219                 skip "Need MDS version at least 2.7.55"
18220
18221         local stripe_count
18222         local file
18223
18224         mkdir $DIR/$tdir
18225
18226         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18227                 error "set striped dir error"
18228
18229         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18230                 error "create files under striped dir failed"
18231
18232         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18233                 error "set striped hashdir error"
18234
18235         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18236                 error "create dir0 under hash dir failed"
18237         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18238                 error "create dir1 under hash dir failed"
18239
18240         # unfortunately, we need to umount to clear dir layout cache for now
18241         # once we fully implement dir layout, we can drop this
18242         umount_client $MOUNT || error "umount failed"
18243         mount_client $MOUNT || error "mount failed"
18244
18245         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18246         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18247         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18248
18249         #set the stripe to be unknown hash type
18250         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18251         $LCTL set_param fail_loc=0x1901
18252         for ((i = 0; i < 10; i++)); do
18253                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18254                         error "stat f-$i failed"
18255                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18256         done
18257
18258         touch $DIR/$tdir/striped_dir/f0 &&
18259                 error "create under striped dir with unknown hash should fail"
18260
18261         $LCTL set_param fail_loc=0
18262
18263         umount_client $MOUNT || error "umount failed"
18264         mount_client $MOUNT || error "mount failed"
18265
18266         return 0
18267 }
18268 run_test 300i "client handle unknown hash type striped directory"
18269
18270 test_300j() {
18271         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18273         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18274                 skip "Need MDS version at least 2.7.55"
18275
18276         local stripe_count
18277         local file
18278
18279         mkdir $DIR/$tdir
18280
18281         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18282         $LCTL set_param fail_loc=0x1702
18283         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18284                 error "set striped dir error"
18285
18286         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18287                 error "create files under striped dir failed"
18288
18289         $LCTL set_param fail_loc=0
18290
18291         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18292
18293         return 0
18294 }
18295 run_test 300j "test large update record"
18296
18297 test_300k() {
18298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18300         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18301                 skip "Need MDS version at least 2.7.55"
18302
18303         # this test needs a huge transaction
18304         local kb
18305         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18306         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18307
18308         local stripe_count
18309         local file
18310
18311         mkdir $DIR/$tdir
18312
18313         #define OBD_FAIL_LARGE_STRIPE   0x1703
18314         $LCTL set_param fail_loc=0x1703
18315         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18316                 error "set striped dir error"
18317         $LCTL set_param fail_loc=0
18318
18319         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18320                 error "getstripeddir fails"
18321         rm -rf $DIR/$tdir/striped_dir ||
18322                 error "unlink striped dir fails"
18323
18324         return 0
18325 }
18326 run_test 300k "test large striped directory"
18327
18328 test_300l() {
18329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18331         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18332                 skip "Need MDS version at least 2.7.55"
18333
18334         local stripe_index
18335
18336         test_mkdir -p $DIR/$tdir/striped_dir
18337         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18338                         error "chown $RUNAS_ID failed"
18339         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18340                 error "set default striped dir failed"
18341
18342         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18343         $LCTL set_param fail_loc=0x80000158
18344         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18345
18346         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18347         [ $stripe_index -eq 1 ] ||
18348                 error "expect 1 get $stripe_index for $dir"
18349 }
18350 run_test 300l "non-root user to create dir under striped dir with stale layout"
18351
18352 test_300m() {
18353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18354         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18355         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18356                 skip "Need MDS version at least 2.7.55"
18357
18358         mkdir -p $DIR/$tdir/striped_dir
18359         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18360                 error "set default stripes dir error"
18361
18362         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18363
18364         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18365         [ $stripe_count -eq 0 ] ||
18366                         error "expect 0 get $stripe_count for a"
18367
18368         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18369                 error "set default stripes dir error"
18370
18371         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18372
18373         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18374         [ $stripe_count -eq 0 ] ||
18375                         error "expect 0 get $stripe_count for b"
18376
18377         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18378                 error "set default stripes dir error"
18379
18380         mkdir $DIR/$tdir/striped_dir/c &&
18381                 error "default stripe_index is invalid, mkdir c should fails"
18382
18383         rm -rf $DIR/$tdir || error "rmdir fails"
18384 }
18385 run_test 300m "setstriped directory on single MDT FS"
18386
18387 cleanup_300n() {
18388         local list=$(comma_list $(mdts_nodes))
18389
18390         trap 0
18391         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18392 }
18393
18394 test_300n() {
18395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18398                 skip "Need MDS version at least 2.7.55"
18399         remote_mds_nodsh && skip "remote MDS with nodsh"
18400
18401         local stripe_index
18402         local list=$(comma_list $(mdts_nodes))
18403
18404         trap cleanup_300n RETURN EXIT
18405         mkdir -p $DIR/$tdir
18406         chmod 777 $DIR/$tdir
18407         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18408                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18409                 error "create striped dir succeeds with gid=0"
18410
18411         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18412         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18413                 error "create striped dir fails with gid=-1"
18414
18415         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18416         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18417                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18418                 error "set default striped dir succeeds with gid=0"
18419
18420
18421         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18422         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18423                 error "set default striped dir fails with gid=-1"
18424
18425
18426         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18427         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18428                                         error "create test_dir fails"
18429         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18430                                         error "create test_dir1 fails"
18431         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18432                                         error "create test_dir2 fails"
18433         cleanup_300n
18434 }
18435 run_test 300n "non-root user to create dir under striped dir with default EA"
18436
18437 test_300o() {
18438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18439         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18440         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18441                 skip "Need MDS version at least 2.7.55"
18442
18443         local numfree1
18444         local numfree2
18445
18446         mkdir -p $DIR/$tdir
18447
18448         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18449         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18450         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18451                 skip "not enough free inodes $numfree1 $numfree2"
18452         fi
18453
18454         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18455         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18456         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18457                 skip "not enough free space $numfree1 $numfree2"
18458         fi
18459
18460         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18461                 error "setdirstripe fails"
18462
18463         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18464                 error "create dirs fails"
18465
18466         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18467         ls $DIR/$tdir/striped_dir > /dev/null ||
18468                 error "ls striped dir fails"
18469         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18470                 error "unlink big striped dir fails"
18471 }
18472 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18473
18474 test_300p() {
18475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18477         remote_mds_nodsh && skip "remote MDS with nodsh"
18478
18479         mkdir -p $DIR/$tdir
18480
18481         #define OBD_FAIL_OUT_ENOSPC     0x1704
18482         do_facet mds2 lctl set_param fail_loc=0x80001704
18483         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18484                  && error "create striped directory should fail"
18485
18486         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18487
18488         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18489         true
18490 }
18491 run_test 300p "create striped directory without space"
18492
18493 test_300q() {
18494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18496
18497         local fd=$(free_fd)
18498         local cmd="exec $fd<$tdir"
18499         cd $DIR
18500         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18501         eval $cmd
18502         cmd="exec $fd<&-"
18503         trap "eval $cmd" EXIT
18504         cd $tdir || error "cd $tdir fails"
18505         rmdir  ../$tdir || error "rmdir $tdir fails"
18506         mkdir local_dir && error "create dir succeeds"
18507         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18508         eval $cmd
18509         return 0
18510 }
18511 run_test 300q "create remote directory under orphan directory"
18512
18513 test_300r() {
18514         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18515                 skip "Need MDS version at least 2.7.55" && return
18516         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18517
18518         mkdir $DIR/$tdir
18519
18520         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18521                 error "set striped dir error"
18522
18523         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18524                 error "getstripeddir fails"
18525
18526         local stripe_count
18527         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18528                       awk '/lmv_stripe_count:/ { print $2 }')
18529
18530         [ $MDSCOUNT -ne $stripe_count ] &&
18531                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18532
18533         rm -rf $DIR/$tdir/striped_dir ||
18534                 error "unlink striped dir fails"
18535 }
18536 run_test 300r "test -1 striped directory"
18537
18538 prepare_remote_file() {
18539         mkdir $DIR/$tdir/src_dir ||
18540                 error "create remote source failed"
18541
18542         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18543                  error "cp to remote source failed"
18544         touch $DIR/$tdir/src_dir/a
18545
18546         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18547                 error "create remote target dir failed"
18548
18549         touch $DIR/$tdir/tgt_dir/b
18550
18551         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18552                 error "rename dir cross MDT failed!"
18553
18554         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18555                 error "src_child still exists after rename"
18556
18557         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18558                 error "missing file(a) after rename"
18559
18560         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18561                 error "diff after rename"
18562 }
18563
18564 test_310a() {
18565         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18567
18568         local remote_file=$DIR/$tdir/tgt_dir/b
18569
18570         mkdir -p $DIR/$tdir
18571
18572         prepare_remote_file || error "prepare remote file failed"
18573
18574         #open-unlink file
18575         $OPENUNLINK $remote_file $remote_file ||
18576                 error "openunlink $remote_file failed"
18577         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18578 }
18579 run_test 310a "open unlink remote file"
18580
18581 test_310b() {
18582         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18584
18585         local remote_file=$DIR/$tdir/tgt_dir/b
18586
18587         mkdir -p $DIR/$tdir
18588
18589         prepare_remote_file || error "prepare remote file failed"
18590
18591         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18592         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18593         $CHECKSTAT -t file $remote_file || error "check file failed"
18594 }
18595 run_test 310b "unlink remote file with multiple links while open"
18596
18597 test_310c() {
18598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18599         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18600
18601         local remote_file=$DIR/$tdir/tgt_dir/b
18602
18603         mkdir -p $DIR/$tdir
18604
18605         prepare_remote_file || error "prepare remote file failed"
18606
18607         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18608         multiop_bg_pause $remote_file O_uc ||
18609                         error "mulitop failed for remote file"
18610         MULTIPID=$!
18611         $MULTIOP $DIR/$tfile Ouc
18612         kill -USR1 $MULTIPID
18613         wait $MULTIPID
18614 }
18615 run_test 310c "open-unlink remote file with multiple links"
18616
18617 #LU-4825
18618 test_311() {
18619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18620         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18621         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18622                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18623         remote_mds_nodsh && skip "remote MDS with nodsh"
18624
18625         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18626         local mdts=$(comma_list $(mdts_nodes))
18627
18628         mkdir -p $DIR/$tdir
18629         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18630         createmany -o $DIR/$tdir/$tfile. 1000
18631
18632         # statfs data is not real time, let's just calculate it
18633         old_iused=$((old_iused + 1000))
18634
18635         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18636                         osp.*OST0000*MDT0000.create_count")
18637         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18638                                 osp.*OST0000*MDT0000.max_create_count")
18639         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18640
18641         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18642         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18643         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18644
18645         unlinkmany $DIR/$tdir/$tfile. 1000
18646
18647         do_nodes $mdts "$LCTL set_param -n \
18648                         osp.*OST0000*.max_create_count=$max_count"
18649         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18650                 do_nodes $mdts "$LCTL set_param -n \
18651                                 osp.*OST0000*.create_count=$count"
18652         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18653                         grep "=0" && error "create_count is zero"
18654
18655         local new_iused
18656         for i in $(seq 120); do
18657                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18658                 # system may be too busy to destroy all objs in time, use
18659                 # a somewhat small value to not fail autotest
18660                 [ $((old_iused - new_iused)) -gt 400 ] && break
18661                 sleep 1
18662         done
18663
18664         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18665         [ $((old_iused - new_iused)) -gt 400 ] ||
18666                 error "objs not destroyed after unlink"
18667 }
18668 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18669
18670 zfs_oid_to_objid()
18671 {
18672         local ost=$1
18673         local objid=$2
18674
18675         local vdevdir=$(dirname $(facet_vdevice $ost))
18676         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18677         local zfs_zapid=$(do_facet $ost $cmd |
18678                           grep -w "/O/0/d$((objid%32))" -C 5 |
18679                           awk '/Object/{getline; print $1}')
18680         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18681                           awk "/$objid = /"'{printf $3}')
18682
18683         echo $zfs_objid
18684 }
18685
18686 zfs_object_blksz() {
18687         local ost=$1
18688         local objid=$2
18689
18690         local vdevdir=$(dirname $(facet_vdevice $ost))
18691         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18692         local blksz=$(do_facet $ost $cmd $objid |
18693                       awk '/dblk/{getline; printf $4}')
18694
18695         case "${blksz: -1}" in
18696                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18697                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18698                 *) ;;
18699         esac
18700
18701         echo $blksz
18702 }
18703
18704 test_312() { # LU-4856
18705         remote_ost_nodsh && skip "remote OST with nodsh"
18706         [ "$ost1_FSTYPE" = "zfs" ] ||
18707                 skip_env "the test only applies to zfs"
18708
18709         local max_blksz=$(do_facet ost1 \
18710                           $ZFS get -p recordsize $(facet_device ost1) |
18711                           awk '!/VALUE/{print $3}')
18712
18713         # to make life a little bit easier
18714         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18715         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18716
18717         local tf=$DIR/$tdir/$tfile
18718         touch $tf
18719         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18720
18721         # Get ZFS object id
18722         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18723         # block size change by sequential overwrite
18724         local bs
18725
18726         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18727                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18728
18729                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18730                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18731         done
18732         rm -f $tf
18733
18734         # block size change by sequential append write
18735         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18736         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18737         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18738         local count
18739
18740         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18741                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18742                         oflag=sync conv=notrunc
18743
18744                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18745                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18746                         error "blksz error, actual $blksz, " \
18747                                 "expected: 2 * $count * $PAGE_SIZE"
18748         done
18749         rm -f $tf
18750
18751         # random write
18752         touch $tf
18753         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18754         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18755
18756         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18757         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18758         [ $blksz -eq $PAGE_SIZE ] ||
18759                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18760
18761         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18762         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18763         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18764
18765         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18766         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18767         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18768 }
18769 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18770
18771 test_313() {
18772         remote_ost_nodsh && skip "remote OST with nodsh"
18773
18774         local file=$DIR/$tfile
18775
18776         rm -f $file
18777         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18778
18779         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18780         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18781         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18782                 error "write should failed"
18783         do_facet ost1 "$LCTL set_param fail_loc=0"
18784         rm -f $file
18785 }
18786 run_test 313 "io should fail after last_rcvd update fail"
18787
18788 test_314() {
18789         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18790
18791         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18792         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18793         rm -f $DIR/$tfile
18794         wait_delete_completed
18795         do_facet ost1 "$LCTL set_param fail_loc=0"
18796 }
18797 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18798
18799 test_315() { # LU-618
18800         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18801
18802         local file=$DIR/$tfile
18803         rm -f $file
18804
18805         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18806                 error "multiop file write failed"
18807         $MULTIOP $file oO_RDONLY:r4063232_c &
18808         PID=$!
18809
18810         sleep 2
18811
18812         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18813         kill -USR1 $PID
18814
18815         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18816         rm -f $file
18817 }
18818 run_test 315 "read should be accounted"
18819
18820 test_316() {
18821         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18822         large_xattr_enabled || skip_env "ea_inode feature disabled"
18823
18824         rm -rf $DIR/$tdir/d
18825         mkdir -p $DIR/$tdir/d
18826         chown nobody $DIR/$tdir/d
18827         touch $DIR/$tdir/d/file
18828
18829         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18830 }
18831 run_test 316 "lfs mv"
18832
18833 test_317() {
18834         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18835                 skip "Need MDS version at least 2.11.53"
18836         local trunc_sz
18837         local grant_blk_size
18838
18839         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18840                 skip "LU-10370: no implementation for ZFS" && return
18841         fi
18842
18843         stack_trap "rm -f $DIR/$tfile" EXIT
18844         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18845                         awk '/grant_block_size:/ { print $2; exit; }')
18846         #
18847         # Create File of size 5M. Truncate it to below size's and verify
18848         # blocks count.
18849         #
18850         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18851                 error "Create file : $DIR/$tfile"
18852
18853         for trunc_sz in 2097152 4097 4000 509 0; do
18854                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18855                         error "truncate $tfile to $trunc_sz failed"
18856                 local sz=$(stat --format=%s $DIR/$tfile)
18857                 local blk=$(stat --format=%b $DIR/$tfile)
18858                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18859                                      grant_blk_size) * 8))
18860
18861                 if [[ $blk -ne $trunc_blk ]]; then
18862                         $(which stat) $DIR/$tfile
18863                         error "Expected Block $trunc_blk got $blk for $tfile"
18864                 fi
18865
18866                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18867                         error "Expected Size $trunc_sz got $sz for $tfile"
18868         done
18869
18870         #
18871         # sparse file test
18872         # Create file with a hole and write actual two blocks. Block count
18873         # must be 16.
18874         #
18875         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18876                 conv=fsync || error "Create file : $DIR/$tfile"
18877
18878         # Calculate the final truncate size.
18879         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18880
18881         #
18882         # truncate to size $trunc_sz bytes. Strip the last block
18883         # The block count must drop to 8
18884         #
18885         $TRUNCATE $DIR/$tfile $trunc_sz ||
18886                 error "truncate $tfile to $trunc_sz failed"
18887
18888         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18889         sz=$(stat --format=%s $DIR/$tfile)
18890         blk=$(stat --format=%b $DIR/$tfile)
18891
18892         if [[ $blk -ne $trunc_bsz ]]; then
18893                 $(which stat) $DIR/$tfile
18894                 error "Expected Block $trunc_bsz got $blk for $tfile"
18895         fi
18896
18897         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18898                 error "Expected Size $trunc_sz got $sz for $tfile"
18899 }
18900 run_test 317 "Verify blocks get correctly update after truncate"
18901
18902 test_319() {
18903         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18904
18905         local before=$(date +%s)
18906         local evict
18907         local mdir=$DIR/$tdir
18908         local file=$mdir/xxx
18909
18910         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18911         touch $file
18912
18913 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18914         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18915         $LFS mv -m1 $file &
18916
18917         sleep 1
18918         dd if=$file of=/dev/null
18919         wait
18920         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18921           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18922
18923         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18924 }
18925 run_test 319 "lost lease lock on migrate error"
18926
18927 test_fake_rw() {
18928         local read_write=$1
18929         if [ "$read_write" = "write" ]; then
18930                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18931         elif [ "$read_write" = "read" ]; then
18932                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18933         else
18934                 error "argument error"
18935         fi
18936
18937         # turn off debug for performance testing
18938         local saved_debug=$($LCTL get_param -n debug)
18939         $LCTL set_param debug=0
18940
18941         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18942
18943         # get ost1 size - lustre-OST0000
18944         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18945         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18946         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18947
18948         if [ "$read_write" = "read" ]; then
18949                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18950         fi
18951
18952         local start_time=$(date +%s.%N)
18953         $dd_cmd bs=1M count=$blocks oflag=sync ||
18954                 error "real dd $read_write error"
18955         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18956
18957         if [ "$read_write" = "write" ]; then
18958                 rm -f $DIR/$tfile
18959         fi
18960
18961         # define OBD_FAIL_OST_FAKE_RW           0x238
18962         do_facet ost1 $LCTL set_param fail_loc=0x238
18963
18964         local start_time=$(date +%s.%N)
18965         $dd_cmd bs=1M count=$blocks oflag=sync ||
18966                 error "fake dd $read_write error"
18967         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18968
18969         if [ "$read_write" = "write" ]; then
18970                 # verify file size
18971                 cancel_lru_locks osc
18972                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18973                         error "$tfile size not $blocks MB"
18974         fi
18975         do_facet ost1 $LCTL set_param fail_loc=0
18976
18977         echo "fake $read_write $duration_fake vs. normal $read_write" \
18978                 "$duration in seconds"
18979         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18980                 error_not_in_vm "fake write is slower"
18981
18982         $LCTL set_param -n debug="$saved_debug"
18983         rm -f $DIR/$tfile
18984 }
18985 test_399a() { # LU-7655 for OST fake write
18986         remote_ost_nodsh && skip "remote OST with nodsh"
18987
18988         test_fake_rw write
18989 }
18990 run_test 399a "fake write should not be slower than normal write"
18991
18992 test_399b() { # LU-8726 for OST fake read
18993         remote_ost_nodsh && skip "remote OST with nodsh"
18994         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18995                 skip_env "ldiskfs only test"
18996         fi
18997
18998         test_fake_rw read
18999 }
19000 run_test 399b "fake read should not be slower than normal read"
19001
19002 test_400a() { # LU-1606, was conf-sanity test_74
19003         if ! which $CC > /dev/null 2>&1; then
19004                 skip_env "$CC is not installed"
19005         fi
19006
19007         local extra_flags=''
19008         local out=$TMP/$tfile
19009         local prefix=/usr/include/lustre
19010         local prog
19011
19012         if ! [[ -d $prefix ]]; then
19013                 # Assume we're running in tree and fixup the include path.
19014                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19015                 extra_flags+=" -L$LUSTRE/utils/.lib"
19016         fi
19017
19018         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19019                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19020                         error "client api broken"
19021         done
19022         rm -f $out
19023 }
19024 run_test 400a "Lustre client api program can compile and link"
19025
19026 test_400b() { # LU-1606, LU-5011
19027         local header
19028         local out=$TMP/$tfile
19029         local prefix=/usr/include/linux/lustre
19030
19031         # We use a hard coded prefix so that this test will not fail
19032         # when run in tree. There are headers in lustre/include/lustre/
19033         # that are not packaged (like lustre_idl.h) and have more
19034         # complicated include dependencies (like config.h and lnet/types.h).
19035         # Since this test about correct packaging we just skip them when
19036         # they don't exist (see below) rather than try to fixup cppflags.
19037
19038         if ! which $CC > /dev/null 2>&1; then
19039                 skip_env "$CC is not installed"
19040         fi
19041
19042         for header in $prefix/*.h; do
19043                 if ! [[ -f "$header" ]]; then
19044                         continue
19045                 fi
19046
19047                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19048                         continue # lustre_ioctl.h is internal header
19049                 fi
19050
19051                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19052                         error "cannot compile '$header'"
19053         done
19054         rm -f $out
19055 }
19056 run_test 400b "packaged headers can be compiled"
19057
19058 test_401a() { #LU-7437
19059         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19060         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19061
19062         #count the number of parameters by "list_param -R"
19063         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19064         #count the number of parameters by listing proc files
19065         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19066         echo "proc_dirs='$proc_dirs'"
19067         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19068         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19069                       sort -u | wc -l)
19070
19071         [ $params -eq $procs ] ||
19072                 error "found $params parameters vs. $procs proc files"
19073
19074         # test the list_param -D option only returns directories
19075         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19076         #count the number of parameters by listing proc directories
19077         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19078                 sort -u | wc -l)
19079
19080         [ $params -eq $procs ] ||
19081                 error "found $params parameters vs. $procs proc files"
19082 }
19083 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19084
19085 test_401b() {
19086         local save=$($LCTL get_param -n jobid_var)
19087         local tmp=testing
19088
19089         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19090                 error "no error returned when setting bad parameters"
19091
19092         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19093         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19094
19095         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19096         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19097         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19098 }
19099 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19100
19101 test_401c() {
19102         local jobid_var_old=$($LCTL get_param -n jobid_var)
19103         local jobid_var_new
19104
19105         $LCTL set_param jobid_var= &&
19106                 error "no error returned for 'set_param a='"
19107
19108         jobid_var_new=$($LCTL get_param -n jobid_var)
19109         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19110                 error "jobid_var was changed by setting without value"
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 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19120
19121 test_401d() {
19122         local jobid_var_old=$($LCTL get_param -n jobid_var)
19123         local jobid_var_new
19124         local new_value="foo=bar"
19125
19126         $LCTL set_param jobid_var=$new_value ||
19127                 error "'set_param a=b' did not accept a value containing '='"
19128
19129         jobid_var_new=$($LCTL get_param -n jobid_var)
19130         [[ "$jobid_var_new" == "$new_value" ]] ||
19131                 error "'set_param a=b' failed on a value containing '='"
19132
19133         # Reset the jobid_var to test the other format
19134         $LCTL set_param jobid_var=$jobid_var_old
19135         jobid_var_new=$($LCTL get_param -n jobid_var)
19136         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19137                 error "failed to reset jobid_var"
19138
19139         $LCTL set_param jobid_var $new_value ||
19140                 error "'set_param a b' did not accept a value containing '='"
19141
19142         jobid_var_new=$($LCTL get_param -n jobid_var)
19143         [[ "$jobid_var_new" == "$new_value" ]] ||
19144                 error "'set_param a b' failed on a value containing '='"
19145
19146         $LCTL set_param jobid_var $jobid_var_old
19147         jobid_var_new=$($LCTL get_param -n jobid_var)
19148         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19149                 error "failed to reset jobid_var"
19150 }
19151 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19152
19153 test_402() {
19154         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19155         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19156                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19157         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19158                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19159                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19160         remote_mds_nodsh && skip "remote MDS with nodsh"
19161
19162         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19163 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19164         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19165         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19166                 echo "Touch failed - OK"
19167 }
19168 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19169
19170 test_403() {
19171         local file1=$DIR/$tfile.1
19172         local file2=$DIR/$tfile.2
19173         local tfile=$TMP/$tfile
19174
19175         rm -f $file1 $file2 $tfile
19176
19177         touch $file1
19178         ln $file1 $file2
19179
19180         # 30 sec OBD_TIMEOUT in ll_getattr()
19181         # right before populating st_nlink
19182         $LCTL set_param fail_loc=0x80001409
19183         stat -c %h $file1 > $tfile &
19184
19185         # create an alias, drop all locks and reclaim the dentry
19186         < $file2
19187         cancel_lru_locks mdc
19188         cancel_lru_locks osc
19189         sysctl -w vm.drop_caches=2
19190
19191         wait
19192
19193         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19194
19195         rm -f $tfile $file1 $file2
19196 }
19197 run_test 403 "i_nlink should not drop to zero due to aliasing"
19198
19199 test_404() { # LU-6601
19200         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19201                 skip "Need server version newer than 2.8.52"
19202         remote_mds_nodsh && skip "remote MDS with nodsh"
19203
19204         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19205                 awk '/osp .*-osc-MDT/ { print $4}')
19206
19207         local osp
19208         for osp in $mosps; do
19209                 echo "Deactivate: " $osp
19210                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19211                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19212                         awk -vp=$osp '$4 == p { print $2 }')
19213                 [ $stat = IN ] || {
19214                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19215                         error "deactivate error"
19216                 }
19217                 echo "Activate: " $osp
19218                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19219                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19220                         awk -vp=$osp '$4 == p { print $2 }')
19221                 [ $stat = UP ] || {
19222                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19223                         error "activate error"
19224                 }
19225         done
19226 }
19227 run_test 404 "validate manual {de}activated works properly for OSPs"
19228
19229 test_405() {
19230         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19231         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19232                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19233                         skip "Layout swap lock is not supported"
19234
19235         check_swap_layouts_support
19236
19237         test_mkdir $DIR/$tdir
19238         swap_lock_test -d $DIR/$tdir ||
19239                 error "One layout swap locked test failed"
19240 }
19241 run_test 405 "Various layout swap lock tests"
19242
19243 test_406() {
19244         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19245         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19246         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19248         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19249                 skip "Need MDS version at least 2.8.50"
19250
19251         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19252         local test_pool=$TESTNAME
19253
19254         if ! combined_mgs_mds ; then
19255                 mount_mgs_client
19256         fi
19257         pool_add $test_pool || error "pool_add failed"
19258         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19259                 error "pool_add_targets failed"
19260
19261         save_layout_restore_at_exit $MOUNT
19262
19263         # parent set default stripe count only, child will stripe from both
19264         # parent and fs default
19265         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19266                 error "setstripe $MOUNT failed"
19267         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19268         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19269         for i in $(seq 10); do
19270                 local f=$DIR/$tdir/$tfile.$i
19271                 touch $f || error "touch failed"
19272                 local count=$($LFS getstripe -c $f)
19273                 [ $count -eq $OSTCOUNT ] ||
19274                         error "$f stripe count $count != $OSTCOUNT"
19275                 local offset=$($LFS getstripe -i $f)
19276                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19277                 local size=$($LFS getstripe -S $f)
19278                 [ $size -eq $((def_stripe_size * 2)) ] ||
19279                         error "$f stripe size $size != $((def_stripe_size * 2))"
19280                 local pool=$($LFS getstripe -p $f)
19281                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19282         done
19283
19284         # change fs default striping, delete parent default striping, now child
19285         # will stripe from new fs default striping only
19286         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19287                 error "change $MOUNT default stripe failed"
19288         $LFS setstripe -c 0 $DIR/$tdir ||
19289                 error "delete $tdir default stripe failed"
19290         for i in $(seq 11 20); do
19291                 local f=$DIR/$tdir/$tfile.$i
19292                 touch $f || error "touch $f failed"
19293                 local count=$($LFS getstripe -c $f)
19294                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19295                 local offset=$($LFS getstripe -i $f)
19296                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19297                 local size=$($LFS getstripe -S $f)
19298                 [ $size -eq $def_stripe_size ] ||
19299                         error "$f stripe size $size != $def_stripe_size"
19300                 local pool=$($LFS getstripe -p $f)
19301                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19302         done
19303
19304         unlinkmany $DIR/$tdir/$tfile. 1 20
19305
19306         local f=$DIR/$tdir/$tfile
19307         pool_remove_all_targets $test_pool $f
19308         pool_remove $test_pool $f
19309
19310         if ! combined_mgs_mds ; then
19311                 umount_mgs_client
19312         fi
19313 }
19314 run_test 406 "DNE support fs default striping"
19315
19316 test_407() {
19317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19318         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19319                 skip "Need MDS version at least 2.8.55"
19320         remote_mds_nodsh && skip "remote MDS with nodsh"
19321
19322         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19323                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19324         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19325                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19326         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19327
19328         #define OBD_FAIL_DT_TXN_STOP    0x2019
19329         for idx in $(seq $MDSCOUNT); do
19330                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19331         done
19332         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19333         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19334                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19335         true
19336 }
19337 run_test 407 "transaction fail should cause operation fail"
19338
19339 test_408() {
19340         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19341
19342         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19343         lctl set_param fail_loc=0x8000040a
19344         # let ll_prepare_partial_page() fail
19345         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19346
19347         rm -f $DIR/$tfile
19348
19349         # create at least 100 unused inodes so that
19350         # shrink_icache_memory(0) should not return 0
19351         touch $DIR/$tfile-{0..100}
19352         rm -f $DIR/$tfile-{0..100}
19353         sync
19354
19355         echo 2 > /proc/sys/vm/drop_caches
19356 }
19357 run_test 408 "drop_caches should not hang due to page leaks"
19358
19359 test_409()
19360 {
19361         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19362
19363         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19364         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19365         touch $DIR/$tdir/guard || error "(2) Fail to create"
19366
19367         local PREFIX=$(str_repeat 'A' 128)
19368         echo "Create 1K hard links start at $(date)"
19369         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19370                 error "(3) Fail to hard link"
19371
19372         echo "Links count should be right although linkEA overflow"
19373         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19374         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19375         [ $linkcount -eq 1001 ] ||
19376                 error "(5) Unexpected hard links count: $linkcount"
19377
19378         echo "List all links start at $(date)"
19379         ls -l $DIR/$tdir/foo > /dev/null ||
19380                 error "(6) Fail to list $DIR/$tdir/foo"
19381
19382         echo "Unlink hard links start at $(date)"
19383         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19384                 error "(7) Fail to unlink"
19385         echo "Unlink hard links finished at $(date)"
19386 }
19387 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19388
19389 test_410()
19390 {
19391         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19392                 skip "Need client version at least 2.9.59"
19393
19394         # Create a file, and stat it from the kernel
19395         local testfile=$DIR/$tfile
19396         touch $testfile
19397
19398         local run_id=$RANDOM
19399         local my_ino=$(stat --format "%i" $testfile)
19400
19401         # Try to insert the module. This will always fail as the
19402         # module is designed to not be inserted.
19403         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19404             &> /dev/null
19405
19406         # Anything but success is a test failure
19407         dmesg | grep -q \
19408             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19409             error "no inode match"
19410 }
19411 run_test 410 "Test inode number returned from kernel thread"
19412
19413 cleanup_test411_cgroup() {
19414         trap 0
19415         rmdir "$1"
19416 }
19417
19418 test_411() {
19419         local cg_basedir=/sys/fs/cgroup/memory
19420         # LU-9966
19421         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19422                 skip "no setup for cgroup"
19423
19424         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19425                 error "test file creation failed"
19426         cancel_lru_locks osc
19427
19428         # Create a very small memory cgroup to force a slab allocation error
19429         local cgdir=$cg_basedir/osc_slab_alloc
19430         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19431         trap "cleanup_test411_cgroup $cgdir" EXIT
19432         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19433         echo 1M > $cgdir/memory.limit_in_bytes
19434
19435         # Should not LBUG, just be killed by oom-killer
19436         # dd will return 0 even allocation failure in some environment.
19437         # So don't check return value
19438         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19439         cleanup_test411_cgroup $cgdir
19440
19441         return 0
19442 }
19443 run_test 411 "Slab allocation error with cgroup does not LBUG"
19444
19445 test_412() {
19446         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19447         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19448                 skip "Need server version at least 2.10.55"
19449         fi
19450
19451         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19452                 error "mkdir failed"
19453         $LFS getdirstripe $DIR/$tdir
19454         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19455         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19456                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19457         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19458         [ $stripe_count -eq 2 ] ||
19459                 error "expect 2 get $stripe_count"
19460 }
19461 run_test 412 "mkdir on specific MDTs"
19462
19463 test_413() {
19464         [ $MDSCOUNT -lt 2 ] &&
19465                 skip "We need at least 2 MDTs for this test"
19466
19467         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19468                 skip "Need server version at least 2.10.55"
19469         fi
19470
19471         mkdir $DIR/$tdir || error "mkdir failed"
19472
19473         # find MDT that is the most full
19474         local max=$($LFS df | grep MDT |
19475                 awk 'BEGIN { a=0 }
19476                         { sub("%", "", $5)
19477                           if (0+$5 >= a)
19478                           {
19479                                 a = $5
19480                                 b = $6
19481                           }
19482                         }
19483                      END { split(b, c, ":")
19484                            sub("]", "", c[2])
19485                            print c[2]
19486                          }')
19487
19488         for i in $(seq $((MDSCOUNT - 1))); do
19489                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19490                         error "mkdir d$i failed"
19491                 $LFS getdirstripe $DIR/$tdir/d$i
19492                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19493                 [ $stripe_index -ne $max ] ||
19494                         error "don't expect $max"
19495         done
19496 }
19497 run_test 413 "mkdir on less full MDTs"
19498
19499 test_414() {
19500 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19501         $LCTL set_param fail_loc=0x80000521
19502         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19503         rm -f $DIR/$tfile
19504 }
19505 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19506
19507 test_415() {
19508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19509         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19510                 skip "Need server version at least 2.11.52"
19511
19512         # LU-11102
19513         local total
19514         local setattr_pid
19515         local start_time
19516         local end_time
19517         local duration
19518
19519         total=500
19520         # this test may be slow on ZFS
19521         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19522
19523         # though this test is designed for striped directory, let's test normal
19524         # directory too since lock is always saved as CoS lock.
19525         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19526         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19527
19528         (
19529                 while true; do
19530                         touch $DIR/$tdir
19531                 done
19532         ) &
19533         setattr_pid=$!
19534
19535         start_time=$(date +%s)
19536         for i in $(seq $total); do
19537                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19538                         > /dev/null
19539         done
19540         end_time=$(date +%s)
19541         duration=$((end_time - start_time))
19542
19543         kill -9 $setattr_pid
19544
19545         echo "rename $total files took $duration sec"
19546         [ $duration -lt 100 ] || error "rename took $duration sec"
19547 }
19548 run_test 415 "lock revoke is not missing"
19549
19550 test_416() {
19551         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19552                 skip "Need server version at least 2.11.55"
19553
19554         # define OBD_FAIL_OSD_TXN_START    0x19a
19555         do_facet mds1 lctl set_param fail_loc=0x19a
19556
19557         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19558
19559         true
19560 }
19561 run_test 416 "transaction start failure won't cause system hung"
19562
19563 cleanup_417() {
19564         trap 0
19565         do_nodes $(comma_list $(mdts_nodes)) \
19566                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19567         do_nodes $(comma_list $(mdts_nodes)) \
19568                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19569         do_nodes $(comma_list $(mdts_nodes)) \
19570                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19571 }
19572
19573 test_417() {
19574         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19575         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19576                 skip "Need MDS version at least 2.11.56"
19577
19578         trap cleanup_417 RETURN EXIT
19579
19580         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19581         do_nodes $(comma_list $(mdts_nodes)) \
19582                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19583         $LFS migrate -m 0 $DIR/$tdir.1 &&
19584                 error "migrate dir $tdir.1 should fail"
19585
19586         do_nodes $(comma_list $(mdts_nodes)) \
19587                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19588         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19589                 error "create remote dir $tdir.2 should fail"
19590
19591         do_nodes $(comma_list $(mdts_nodes)) \
19592                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19593         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19594                 error "create striped dir $tdir.3 should fail"
19595         true
19596 }
19597 run_test 417 "disable remote dir, striped dir and dir migration"
19598
19599 # Checks that the outputs of df [-i] and lfs df [-i] match
19600 #
19601 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19602 check_lfs_df() {
19603         local dir=$2
19604         local inodes
19605         local df_out
19606         local lfs_df_out
19607         local count
19608         local passed=false
19609
19610         # blocks or inodes
19611         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19612
19613         for count in {1..100}; do
19614                 cancel_lru_locks
19615                 sync; sleep 0.2
19616
19617                 # read the lines of interest
19618                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19619                         error "df $inodes $dir | tail -n +2 failed"
19620                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19621                         error "lfs df $inodes $dir | grep summary: failed"
19622
19623                 # skip first substrings of each output as they are different
19624                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19625                 # compare the two outputs
19626                 passed=true
19627                 for i in {1..5}; do
19628                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19629                 done
19630                 $passed && break
19631         done
19632
19633         if ! $passed; then
19634                 df -P $inodes $dir
19635                 echo
19636                 lfs df $inodes $dir
19637                 error "df and lfs df $1 output mismatch: "      \
19638                       "df ${inodes}: ${df_out[*]}, "            \
19639                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19640         fi
19641 }
19642
19643 test_418() {
19644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19645
19646         local dir=$DIR/$tdir
19647         local numfiles=$((RANDOM % 4096 + 2))
19648         local numblocks=$((RANDOM % 256 + 1))
19649
19650         wait_delete_completed
19651         test_mkdir $dir
19652
19653         # check block output
19654         check_lfs_df blocks $dir
19655         # check inode output
19656         check_lfs_df inodes $dir
19657
19658         # create a single file and retest
19659         echo "Creating a single file and testing"
19660         createmany -o $dir/$tfile- 1 &>/dev/null ||
19661                 error "creating 1 file in $dir failed"
19662         check_lfs_df blocks $dir
19663         check_lfs_df inodes $dir
19664
19665         # create a random number of files
19666         echo "Creating $((numfiles - 1)) files and testing"
19667         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19668                 error "creating $((numfiles - 1)) files in $dir failed"
19669
19670         # write a random number of blocks to the first test file
19671         echo "Writing $numblocks 4K blocks and testing"
19672         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19673                 count=$numblocks &>/dev/null ||
19674                 error "dd to $dir/${tfile}-0 failed"
19675
19676         # retest
19677         check_lfs_df blocks $dir
19678         check_lfs_df inodes $dir
19679
19680         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19681                 error "unlinking $numfiles files in $dir failed"
19682 }
19683 run_test 418 "df and lfs df outputs match"
19684
19685 test_419()
19686 {
19687         local dir=$DIR/$tdir
19688
19689         mkdir -p $dir
19690         touch $dir/file
19691
19692         cancel_lru_locks mdc
19693
19694         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
19695         $LCTL set_param fail_loc=0x1410
19696         cat $dir/file
19697         $LCTL set_param fail_loc=0
19698         rm -rf $dir
19699 }
19700 run_test 419 "Verify open file by name doesn't crash kernel"
19701
19702 prep_801() {
19703         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19704         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19705                 skip "Need server version at least 2.9.55"
19706
19707         start_full_debug_logging
19708 }
19709
19710 post_801() {
19711         stop_full_debug_logging
19712 }
19713
19714 barrier_stat() {
19715         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19716                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19717                            awk '/The barrier for/ { print $7 }')
19718                 echo $st
19719         else
19720                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19721                 echo \'$st\'
19722         fi
19723 }
19724
19725 barrier_expired() {
19726         local expired
19727
19728         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19729                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19730                           awk '/will be expired/ { print $7 }')
19731         else
19732                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19733         fi
19734
19735         echo $expired
19736 }
19737
19738 test_801a() {
19739         prep_801
19740
19741         echo "Start barrier_freeze at: $(date)"
19742         #define OBD_FAIL_BARRIER_DELAY          0x2202
19743         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19744         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19745
19746         sleep 2
19747         local b_status=$(barrier_stat)
19748         echo "Got barrier status at: $(date)"
19749         [ "$b_status" = "'freezing_p1'" ] ||
19750                 error "(1) unexpected barrier status $b_status"
19751
19752         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19753         wait
19754         b_status=$(barrier_stat)
19755         [ "$b_status" = "'frozen'" ] ||
19756                 error "(2) unexpected barrier status $b_status"
19757
19758         local expired=$(barrier_expired)
19759         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19760         sleep $((expired + 3))
19761
19762         b_status=$(barrier_stat)
19763         [ "$b_status" = "'expired'" ] ||
19764                 error "(3) unexpected barrier status $b_status"
19765
19766         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19767                 error "(4) fail to freeze barrier"
19768
19769         b_status=$(barrier_stat)
19770         [ "$b_status" = "'frozen'" ] ||
19771                 error "(5) unexpected barrier status $b_status"
19772
19773         echo "Start barrier_thaw at: $(date)"
19774         #define OBD_FAIL_BARRIER_DELAY          0x2202
19775         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19776         do_facet mgs $LCTL barrier_thaw $FSNAME &
19777
19778         sleep 2
19779         b_status=$(barrier_stat)
19780         echo "Got barrier status at: $(date)"
19781         [ "$b_status" = "'thawing'" ] ||
19782                 error "(6) unexpected barrier status $b_status"
19783
19784         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19785         wait
19786         b_status=$(barrier_stat)
19787         [ "$b_status" = "'thawed'" ] ||
19788                 error "(7) unexpected barrier status $b_status"
19789
19790         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19791         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19792         do_facet mgs $LCTL barrier_freeze $FSNAME
19793
19794         b_status=$(barrier_stat)
19795         [ "$b_status" = "'failed'" ] ||
19796                 error "(8) unexpected barrier status $b_status"
19797
19798         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19799         do_facet mgs $LCTL barrier_thaw $FSNAME
19800
19801         post_801
19802 }
19803 run_test 801a "write barrier user interfaces and stat machine"
19804
19805 test_801b() {
19806         prep_801
19807
19808         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19809         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19810         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19811         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19812         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19813
19814         cancel_lru_locks mdc
19815
19816         # 180 seconds should be long enough
19817         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19818
19819         local b_status=$(barrier_stat)
19820         [ "$b_status" = "'frozen'" ] ||
19821                 error "(6) unexpected barrier status $b_status"
19822
19823         mkdir $DIR/$tdir/d0/d10 &
19824         mkdir_pid=$!
19825
19826         touch $DIR/$tdir/d1/f13 &
19827         touch_pid=$!
19828
19829         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19830         ln_pid=$!
19831
19832         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19833         mv_pid=$!
19834
19835         rm -f $DIR/$tdir/d4/f12 &
19836         rm_pid=$!
19837
19838         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19839
19840         # To guarantee taht the 'stat' is not blocked
19841         b_status=$(barrier_stat)
19842         [ "$b_status" = "'frozen'" ] ||
19843                 error "(8) unexpected barrier status $b_status"
19844
19845         # let above commands to run at background
19846         sleep 5
19847
19848         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19849         ps -p $touch_pid || error "(10) touch should be blocked"
19850         ps -p $ln_pid || error "(11) link should be blocked"
19851         ps -p $mv_pid || error "(12) rename should be blocked"
19852         ps -p $rm_pid || error "(13) unlink should be blocked"
19853
19854         b_status=$(barrier_stat)
19855         [ "$b_status" = "'frozen'" ] ||
19856                 error "(14) unexpected barrier status $b_status"
19857
19858         do_facet mgs $LCTL barrier_thaw $FSNAME
19859         b_status=$(barrier_stat)
19860         [ "$b_status" = "'thawed'" ] ||
19861                 error "(15) unexpected barrier status $b_status"
19862
19863         wait $mkdir_pid || error "(16) mkdir should succeed"
19864         wait $touch_pid || error "(17) touch should succeed"
19865         wait $ln_pid || error "(18) link should succeed"
19866         wait $mv_pid || error "(19) rename should succeed"
19867         wait $rm_pid || error "(20) unlink should succeed"
19868
19869         post_801
19870 }
19871 run_test 801b "modification will be blocked by write barrier"
19872
19873 test_801c() {
19874         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19875
19876         prep_801
19877
19878         stop mds2 || error "(1) Fail to stop mds2"
19879
19880         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19881
19882         local b_status=$(barrier_stat)
19883         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
19884                 do_facet mgs $LCTL barrier_thaw $FSNAME
19885                 error "(2) unexpected barrier status $b_status"
19886         }
19887
19888         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19889                 error "(3) Fail to rescan barrier bitmap"
19890
19891         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19892
19893         b_status=$(barrier_stat)
19894         [ "$b_status" = "'frozen'" ] ||
19895                 error "(4) unexpected barrier status $b_status"
19896
19897         do_facet mgs $LCTL barrier_thaw $FSNAME
19898         b_status=$(barrier_stat)
19899         [ "$b_status" = "'thawed'" ] ||
19900                 error "(5) unexpected barrier status $b_status"
19901
19902         local devname=$(mdsdevname 2)
19903
19904         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19905
19906         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19907                 error "(7) Fail to rescan barrier bitmap"
19908
19909         post_801
19910 }
19911 run_test 801c "rescan barrier bitmap"
19912
19913 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19914 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19915 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19916
19917 cleanup_802a() {
19918         trap 0
19919
19920         stopall
19921         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19922         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19923         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19924         setupall
19925 }
19926
19927 test_802a() {
19928
19929         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19930         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19931                 skip "Need server version at least 2.9.55"
19932
19933         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19934
19935         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19936
19937         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19938                 error "(2) Fail to copy"
19939
19940         trap cleanup_802a EXIT
19941
19942         # sync by force before remount as readonly
19943         sync; sync_all_data; sleep 3; sync_all_data
19944
19945         stopall
19946
19947         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19948         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19949         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19950
19951         echo "Mount the server as read only"
19952         setupall server_only || error "(3) Fail to start servers"
19953
19954         echo "Mount client without ro should fail"
19955         mount_client $MOUNT &&
19956                 error "(4) Mount client without 'ro' should fail"
19957
19958         echo "Mount client with ro should succeed"
19959         mount_client $MOUNT ro ||
19960                 error "(5) Mount client with 'ro' should succeed"
19961
19962         echo "Modify should be refused"
19963         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19964
19965         echo "Read should be allowed"
19966         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19967                 error "(7) Read should succeed under ro mode"
19968
19969         cleanup_802a
19970 }
19971 run_test 802a "simulate readonly device"
19972
19973 test_802b() {
19974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19975         remote_mds_nodsh && skip "remote MDS with nodsh"
19976
19977         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19978                 skip "readonly option not available"
19979
19980         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19981
19982         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19983                 error "(2) Fail to copy"
19984
19985         # write back all cached data before setting MDT to readonly
19986         cancel_lru_locks
19987         sync_all_data
19988
19989         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19990         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19991
19992         echo "Modify should be refused"
19993         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19994
19995         echo "Read should be allowed"
19996         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19997                 error "(7) Read should succeed under ro mode"
19998
19999         # disable readonly
20000         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20001 }
20002 run_test 802b "be able to set MDTs to readonly"
20003
20004 test_803() {
20005         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20006         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20007                 skip "MDS needs to be newer than 2.10.54"
20008
20009         mkdir -p $DIR/$tdir
20010         # Create some objects on all MDTs to trigger related logs objects
20011         for idx in $(seq $MDSCOUNT); do
20012                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20013                         $DIR/$tdir/dir${idx} ||
20014                         error "Fail to create $DIR/$tdir/dir${idx}"
20015         done
20016
20017         sync; sleep 3
20018         wait_delete_completed # ensure old test cleanups are finished
20019         echo "before create:"
20020         $LFS df -i $MOUNT
20021         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20022
20023         for i in {1..10}; do
20024                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20025                         error "Fail to create $DIR/$tdir/foo$i"
20026         done
20027
20028         sync; sleep 3
20029         echo "after create:"
20030         $LFS df -i $MOUNT
20031         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20032
20033         # allow for an llog to be cleaned up during the test
20034         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20035                 error "before ($before_used) + 10 > after ($after_used)"
20036
20037         for i in {1..10}; do
20038                 rm -rf $DIR/$tdir/foo$i ||
20039                         error "Fail to remove $DIR/$tdir/foo$i"
20040         done
20041
20042         sleep 3 # avoid MDT return cached statfs
20043         wait_delete_completed
20044         echo "after unlink:"
20045         $LFS df -i $MOUNT
20046         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20047
20048         # allow for an llog to be created during the test
20049         [ $after_used -le $((before_used + 1)) ] ||
20050                 error "after ($after_used) > before ($before_used) + 1"
20051 }
20052 run_test 803 "verify agent object for remote object"
20053
20054 test_804() {
20055         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20056         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20057                 skip "MDS needs to be newer than 2.10.54"
20058         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20059
20060         mkdir -p $DIR/$tdir
20061         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20062                 error "Fail to create $DIR/$tdir/dir0"
20063
20064         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20065         local dev=$(mdsdevname 2)
20066
20067         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20068                 grep ${fid} || error "NOT found agent entry for dir0"
20069
20070         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20071                 error "Fail to create $DIR/$tdir/dir1"
20072
20073         touch $DIR/$tdir/dir1/foo0 ||
20074                 error "Fail to create $DIR/$tdir/dir1/foo0"
20075         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20076         local rc=0
20077
20078         for idx in $(seq $MDSCOUNT); do
20079                 dev=$(mdsdevname $idx)
20080                 do_facet mds${idx} \
20081                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20082                         grep ${fid} && rc=$idx
20083         done
20084
20085         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20086                 error "Fail to rename foo0 to foo1"
20087         if [ $rc -eq 0 ]; then
20088                 for idx in $(seq $MDSCOUNT); do
20089                         dev=$(mdsdevname $idx)
20090                         do_facet mds${idx} \
20091                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20092                         grep ${fid} && rc=$idx
20093                 done
20094         fi
20095
20096         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20097                 error "Fail to rename foo1 to foo2"
20098         if [ $rc -eq 0 ]; then
20099                 for idx in $(seq $MDSCOUNT); do
20100                         dev=$(mdsdevname $idx)
20101                         do_facet mds${idx} \
20102                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20103                         grep ${fid} && rc=$idx
20104                 done
20105         fi
20106
20107         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20108
20109         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20110                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20111         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20112                 error "Fail to rename foo2 to foo0"
20113         unlink $DIR/$tdir/dir1/foo0 ||
20114                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20115         rm -rf $DIR/$tdir/dir0 ||
20116                 error "Fail to rm $DIR/$tdir/dir0"
20117
20118         for idx in $(seq $MDSCOUNT); do
20119                 dev=$(mdsdevname $idx)
20120                 rc=0
20121
20122                 stop mds${idx}
20123                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20124                         rc=$?
20125                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20126                         error "mount mds$idx failed"
20127                 df $MOUNT > /dev/null 2>&1
20128
20129                 # e2fsck should not return error
20130                 [ $rc -eq 0 ] ||
20131                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20132         done
20133 }
20134 run_test 804 "verify agent entry for remote entry"
20135
20136 cleanup_805() {
20137         do_facet $SINGLEMDS zfs set quota=$old $fsset
20138         unlinkmany $DIR/$tdir/f- 1000000
20139         trap 0
20140 }
20141
20142 test_805() {
20143         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20144         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20145         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20146                 skip "netfree not implemented before 0.7"
20147         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20148                 skip "Need MDS version at least 2.10.57"
20149
20150         local fsset
20151         local freekb
20152         local usedkb
20153         local old
20154         local quota
20155         local pref="osd-zfs.lustre-MDT0000."
20156
20157         # limit available space on MDS dataset to meet nospace issue
20158         # quickly. then ZFS 0.7.2 can use reserved space if asked
20159         # properly (using netfree flag in osd_declare_destroy()
20160         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20161         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20162                 gawk '{print $3}')
20163         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20164         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20165         let "usedkb=usedkb-freekb"
20166         let "freekb=freekb/2"
20167         if let "freekb > 5000"; then
20168                 let "freekb=5000"
20169         fi
20170         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20171         trap cleanup_805 EXIT
20172         mkdir $DIR/$tdir
20173         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20174         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20175         rm -rf $DIR/$tdir || error "not able to remove"
20176         do_facet $SINGLEMDS zfs set quota=$old $fsset
20177         trap 0
20178 }
20179 run_test 805 "ZFS can remove from full fs"
20180
20181 # Size-on-MDS test
20182 check_lsom_data()
20183 {
20184         local file=$1
20185         local size=$($LFS getsom -s $file)
20186         local expect=$(stat -c %s $file)
20187
20188         [[ $size == $expect ]] ||
20189                 error "$file expected size: $expect, got: $size"
20190
20191         local blocks=$($LFS getsom -b $file)
20192         expect=$(stat -c %b $file)
20193         [[ $blocks == $expect ]] ||
20194                 error "$file expected blocks: $expect, got: $blocks"
20195 }
20196
20197 check_lsom_size()
20198 {
20199         local size=$($LFS getsom -s $1)
20200         local expect=$2
20201
20202         [[ $size == $expect ]] ||
20203                 error "$file expected size: $expect, got: $size"
20204 }
20205
20206 test_806() {
20207         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20208                 skip "Need MDS version at least 2.11.52"
20209
20210         local bs=1048576
20211
20212         touch $DIR/$tfile || error "touch $tfile failed"
20213
20214         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20215         save_lustre_params client "llite.*.xattr_cache" > $save
20216         lctl set_param llite.*.xattr_cache=0
20217         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20218
20219         # single-threaded write
20220         echo "Test SOM for single-threaded write"
20221         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20222                 error "write $tfile failed"
20223         check_lsom_size $DIR/$tfile $bs
20224
20225         local num=32
20226         local size=$(($num * $bs))
20227         local offset=0
20228         local i
20229
20230         echo "Test SOM for single client multi-threaded($num) write"
20231         $TRUNCATE $DIR/$tfile 0
20232         for ((i = 0; i < $num; i++)); do
20233                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20234                 local pids[$i]=$!
20235                 offset=$((offset + $bs))
20236         done
20237         for (( i=0; i < $num; i++ )); do
20238                 wait ${pids[$i]}
20239         done
20240         check_lsom_size $DIR/$tfile $size
20241
20242         $TRUNCATE $DIR/$tfile 0
20243         for ((i = 0; i < $num; i++)); do
20244                 offset=$((offset - $bs))
20245                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20246                 local pids[$i]=$!
20247         done
20248         for (( i=0; i < $num; i++ )); do
20249                 wait ${pids[$i]}
20250         done
20251         check_lsom_size $DIR/$tfile $size
20252
20253         # multi-client wirtes
20254         num=$(get_node_count ${CLIENTS//,/ })
20255         size=$(($num * $bs))
20256         offset=0
20257         i=0
20258
20259         echo "Test SOM for multi-client ($num) writes"
20260         $TRUNCATE $DIR/$tfile 0
20261         for client in ${CLIENTS//,/ }; do
20262                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20263                 local pids[$i]=$!
20264                 i=$((i + 1))
20265                 offset=$((offset + $bs))
20266         done
20267         for (( i=0; i < $num; i++ )); do
20268                 wait ${pids[$i]}
20269         done
20270         check_lsom_size $DIR/$tfile $offset
20271
20272         i=0
20273         $TRUNCATE $DIR/$tfile 0
20274         for client in ${CLIENTS//,/ }; do
20275                 offset=$((offset - $bs))
20276                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20277                 local pids[$i]=$!
20278                 i=$((i + 1))
20279         done
20280         for (( i=0; i < $num; i++ )); do
20281                 wait ${pids[$i]}
20282         done
20283         check_lsom_size $DIR/$tfile $size
20284
20285         # verify truncate
20286         echo "Test SOM for truncate"
20287         $TRUNCATE $DIR/$tfile 1048576
20288         check_lsom_size $DIR/$tfile 1048576
20289         $TRUNCATE $DIR/$tfile 1234
20290         check_lsom_size $DIR/$tfile 1234
20291
20292         # verify SOM blocks count
20293         echo "Verify SOM block count"
20294         $TRUNCATE $DIR/$tfile 0
20295         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20296                 error "failed to write file $tfile"
20297         check_lsom_data $DIR/$tfile
20298 }
20299 run_test 806 "Verify Lazy Size on MDS"
20300
20301 test_807() {
20302         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20303         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20304                 skip "Need MDS version at least 2.11.52"
20305
20306         # Registration step
20307         changelog_register || error "changelog_register failed"
20308         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20309         changelog_users $SINGLEMDS | grep -q $cl_user ||
20310                 error "User $cl_user not found in changelog_users"
20311
20312         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20313         save_lustre_params client "llite.*.xattr_cache" > $save
20314         lctl set_param llite.*.xattr_cache=0
20315         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20316
20317         rm -rf $DIR/$tdir || error "rm $tdir failed"
20318         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20319         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20320         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20321         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20322                 error "truncate $tdir/trunc failed"
20323
20324         local bs=1048576
20325         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20326                 error "write $tfile failed"
20327
20328         # multi-client wirtes
20329         local num=$(get_node_count ${CLIENTS//,/ })
20330         local offset=0
20331         local i=0
20332
20333         echo "Test SOM for multi-client ($num) writes"
20334         touch $DIR/$tfile || error "touch $tfile failed"
20335         $TRUNCATE $DIR/$tfile 0
20336         for client in ${CLIENTS//,/ }; do
20337                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20338                 local pids[$i]=$!
20339                 i=$((i + 1))
20340                 offset=$((offset + $bs))
20341         done
20342         for (( i=0; i < $num; i++ )); do
20343                 wait ${pids[$i]}
20344         done
20345
20346         sleep 5
20347         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20348         check_lsom_data $DIR/$tdir/trunc
20349         check_lsom_data $DIR/$tdir/single_dd
20350         check_lsom_data $DIR/$tfile
20351
20352         rm -rf $DIR/$tdir
20353         # Deregistration step
20354         changelog_deregister || error "changelog_deregister failed"
20355 }
20356 run_test 807 "verify LSOM syncing tool"
20357
20358 check_som_nologged()
20359 {
20360         local lines=$($LFS changelog $FSNAME-MDT0000 |
20361                 grep 'x=trusted.som' | wc -l)
20362         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20363 }
20364
20365 test_808() {
20366         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20367                 skip "Need MDS version at least 2.11.55"
20368
20369         # Registration step
20370         changelog_register || error "changelog_register failed"
20371
20372         touch $DIR/$tfile || error "touch $tfile failed"
20373         check_som_nologged
20374
20375         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20376                 error "write $tfile failed"
20377         check_som_nologged
20378
20379         $TRUNCATE $DIR/$tfile 1234
20380         check_som_nologged
20381
20382         $TRUNCATE $DIR/$tfile 1048576
20383         check_som_nologged
20384
20385         # Deregistration step
20386         changelog_deregister || error "changelog_deregister failed"
20387 }
20388 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20389
20390 check_som_nodata()
20391 {
20392         $LFS getsom $1
20393         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20394 }
20395
20396 test_809() {
20397         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20398                 skip "Need MDS version at least 2.11.56"
20399
20400         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20401                 error "failed to create DoM-only file $DIR/$tfile"
20402         touch $DIR/$tfile || error "touch $tfile failed"
20403         check_som_nodata $DIR/$tfile
20404
20405         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20406                 error "write $tfile failed"
20407         check_som_nodata $DIR/$tfile
20408
20409         $TRUNCATE $DIR/$tfile 1234
20410         check_som_nodata $DIR/$tfile
20411
20412         $TRUNCATE $DIR/$tfile 4097
20413         check_som_nodata $DIR/$file
20414 }
20415 run_test 809 "Verify no SOM xattr store for DoM-only files"
20416
20417 test_810() {
20418         local ORIG
20419         local CSUM
20420
20421         # t10 seem to dislike partial pages
20422         lctl set_param osc.*.checksum_type=adler
20423         lctl set_param fail_loc=0x411
20424         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20425         ORIG=$(md5sum $DIR/$tfile)
20426         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20427         CSUM=$(md5sum $DIR/$tfile)
20428         set_checksum_type adler
20429         if [ "$ORIG" != "$CSUM" ]; then
20430                 error "$ORIG != $CSUM"
20431         fi
20432 }
20433 run_test 810 "partial page writes on ZFS (LU-11663)"
20434
20435 test_811() {
20436         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20437                 skip "Need MDS version at least 2.11.56"
20438
20439         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20440         do_facet mds1 $LCTL set_param fail_loc=0x165
20441         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20442
20443         stop mds1
20444         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20445
20446         sleep 5
20447         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20448                 error "MDD orphan cleanup thread not quit"
20449 }
20450 run_test 811 "orphan name stub can be cleaned up in startup"
20451
20452 test_812() {
20453         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20454                 skip "OST < 2.12.51 doesn't support this fail_loc"
20455
20456         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20457         # ensure ost1 is connected
20458         stat $DIR/$tfile >/dev/null || error "can't stat"
20459         wait_osc_import_state client ost1 FULL
20460         # no locks, no reqs to let the connection idle
20461         cancel_lru_locks osc
20462
20463         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20464 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20465         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20466         wait_osc_import_state client ost1 CONNECTING
20467         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20468
20469         stat $DIR/$tfile >/dev/null || error "can't stat file"
20470 }
20471 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20472
20473 test_813() {
20474         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20475         [ -z "$file_heat_sav" ] && skip "no file heat support"
20476
20477         local readsample
20478         local writesample
20479         local readbyte
20480         local writebyte
20481         local readsample1
20482         local writesample1
20483         local readbyte1
20484         local writebyte1
20485
20486         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20487         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20488
20489         $LCTL set_param -n llite.*.file_heat=1
20490         echo "Turn on file heat"
20491         echo "Period second: $period_second, Decay percentage: $decay_pct"
20492
20493         echo "QQQQ" > $DIR/$tfile
20494         echo "QQQQ" > $DIR/$tfile
20495         echo "QQQQ" > $DIR/$tfile
20496         cat $DIR/$tfile > /dev/null
20497         cat $DIR/$tfile > /dev/null
20498         cat $DIR/$tfile > /dev/null
20499         cat $DIR/$tfile > /dev/null
20500
20501         local out=$($LFS heat_get $DIR/$tfile)
20502
20503         $LFS heat_get $DIR/$tfile
20504         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20505         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20506         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20507         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20508
20509         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20510         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20511         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20512         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20513
20514         sleep $((period_second + 3))
20515         echo "Sleep $((period_second + 3)) seconds..."
20516         # The recursion formula to calculate the heat of the file f is as
20517         # follow:
20518         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20519         # Where Hi is the heat value in the period between time points i*I and
20520         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20521         # to the weight of Ci.
20522         out=$($LFS heat_get $DIR/$tfile)
20523         $LFS heat_get $DIR/$tfile
20524         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20525         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20526         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20527         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20528
20529         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20530                 error "read sample ($readsample) is wrong"
20531         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20532                 error "write sample ($writesample) is wrong"
20533         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20534                 error "read bytes ($readbyte) is wrong"
20535         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20536                 error "write bytes ($writebyte) is wrong"
20537
20538         echo "QQQQ" > $DIR/$tfile
20539         echo "QQQQ" > $DIR/$tfile
20540         echo "QQQQ" > $DIR/$tfile
20541         cat $DIR/$tfile > /dev/null
20542         cat $DIR/$tfile > /dev/null
20543         cat $DIR/$tfile > /dev/null
20544         cat $DIR/$tfile > /dev/null
20545
20546         sleep $((period_second + 3))
20547         echo "Sleep $((period_second + 3)) seconds..."
20548
20549         out=$($LFS heat_get $DIR/$tfile)
20550         $LFS heat_get $DIR/$tfile
20551         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20552         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20553         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20554         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20555
20556         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20557                 4 * $decay_pct) / 100") -eq 1 ] ||
20558                 error "read sample ($readsample1) is wrong"
20559         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20560                 3 * $decay_pct) / 100") -eq 1 ] ||
20561                 error "write sample ($writesample1) is wrong"
20562         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20563                 20 * $decay_pct) / 100") -eq 1 ] ||
20564                 error "read bytes ($readbyte1) is wrong"
20565         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20566                 15 * $decay_pct) / 100") -eq 1 ] ||
20567                 error "write bytes ($writebyte1) is wrong"
20568
20569         echo "Turn off file heat for the file $DIR/$tfile"
20570         $LFS heat_set -o $DIR/$tfile
20571
20572         echo "QQQQ" > $DIR/$tfile
20573         echo "QQQQ" > $DIR/$tfile
20574         echo "QQQQ" > $DIR/$tfile
20575         cat $DIR/$tfile > /dev/null
20576         cat $DIR/$tfile > /dev/null
20577         cat $DIR/$tfile > /dev/null
20578         cat $DIR/$tfile > /dev/null
20579
20580         out=$($LFS heat_get $DIR/$tfile)
20581         $LFS heat_get $DIR/$tfile
20582         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20583         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20584         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20585         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20586
20587         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20588         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20589         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20590         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20591
20592         echo "Trun on file heat for the file $DIR/$tfile"
20593         $LFS heat_set -O $DIR/$tfile
20594
20595         echo "QQQQ" > $DIR/$tfile
20596         echo "QQQQ" > $DIR/$tfile
20597         echo "QQQQ" > $DIR/$tfile
20598         cat $DIR/$tfile > /dev/null
20599         cat $DIR/$tfile > /dev/null
20600         cat $DIR/$tfile > /dev/null
20601         cat $DIR/$tfile > /dev/null
20602
20603         out=$($LFS heat_get $DIR/$tfile)
20604         $LFS heat_get $DIR/$tfile
20605         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20606         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20607         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20608         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20609
20610         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20611         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20612         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20613         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20614
20615         $LFS heat_set -c $DIR/$tfile
20616         $LCTL set_param -n llite.*.file_heat=0
20617         echo "Turn off file heat support for the Lustre filesystem"
20618
20619         echo "QQQQ" > $DIR/$tfile
20620         echo "QQQQ" > $DIR/$tfile
20621         echo "QQQQ" > $DIR/$tfile
20622         cat $DIR/$tfile > /dev/null
20623         cat $DIR/$tfile > /dev/null
20624         cat $DIR/$tfile > /dev/null
20625         cat $DIR/$tfile > /dev/null
20626
20627         out=$($LFS heat_get $DIR/$tfile)
20628         $LFS heat_get $DIR/$tfile
20629         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20630         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20631         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20632         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20633
20634         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20635         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20636         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20637         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20638
20639         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20640         rm -f $DIR/$tfile
20641 }
20642 run_test 813 "File heat verfication"
20643
20644 #
20645 # tests that do cleanup/setup should be run at the end
20646 #
20647
20648 test_900() {
20649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20650         local ls
20651
20652         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20653         $LCTL set_param fail_loc=0x903
20654
20655         cancel_lru_locks MGC
20656
20657         FAIL_ON_ERROR=true cleanup
20658         FAIL_ON_ERROR=true setup
20659 }
20660 run_test 900 "umount should not race with any mgc requeue thread"
20661
20662 complete $SECONDS
20663 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20664 check_and_cleanup_lustre
20665 if [ "$I_MOUNTED" != "yes" ]; then
20666         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20667 fi
20668 exit_status