Whamcloud - gitweb
LU-11623 tests: Fix sanity 27E to ensure getattr RPC
[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 # 27c family tests specific striping, setstripe -o
1537 test_27ca() {
1538         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1539         test_mkdir -p $DIR/$tdir
1540         local osts="1"
1541
1542         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1543         $LFS getstripe -i $DIR/$tdir/$tfile
1544         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1545                 error "stripe not on specified OST"
1546
1547         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1548 }
1549 run_test 27ca "one stripe on specified OST"
1550
1551 test_27cb() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1553         test_mkdir -p $DIR/$tdir
1554         local osts="1,0"
1555         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1556         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1557         echo "$getstripe"
1558
1559         # Strip getstripe output to a space separated list of OSTs
1560         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1561                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1562         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1563                 error "stripes not on specified OSTs"
1564
1565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1566 }
1567 run_test 27cb "two stripes on specified OSTs"
1568
1569 test_27cc() {
1570         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1571         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1572                 skip "server does not support overstriping"
1573
1574         test_mkdir -p $DIR/$tdir
1575         local osts="0,0"
1576         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1577         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1578         echo "$getstripe"
1579
1580         # Strip getstripe output to a space separated list of OSTs
1581         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1582                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1583         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1584                 error "stripes not on specified OSTs"
1585
1586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1587 }
1588 run_test 27cc "two stripes on the same OST"
1589
1590 test_27cd() {
1591         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1592         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1593                 skip "server does not support overstriping"
1594         test_mkdir -p $DIR/$tdir
1595         local osts="0,1,1,0"
1596         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1597         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1598         echo "$getstripe"
1599
1600         # Strip getstripe output to a space separated list of OSTs
1601         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1602                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1603         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1604                 error "stripes not on specified OSTs"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27cd "four stripes on two OSTs"
1609
1610 test_27ce() {
1611         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1612                 skip_env "too many osts, skipping"
1613         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1614                 skip "server does not support overstriping"
1615         # We do one more stripe than we have OSTs
1616         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1617                 skip_env "ea_inode feature disabled"
1618
1619         test_mkdir -p $DIR/$tdir
1620         local osts=""
1621         for i in $(seq 0 $OSTCOUNT);
1622         do
1623                 osts=$osts"0"
1624                 if [ $i -ne $OSTCOUNT ]; then
1625                         osts=$osts","
1626                 fi
1627         done
1628         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1629         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1630         echo "$getstripe"
1631
1632         # Strip getstripe output to a space separated list of OSTs
1633         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1634                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1635         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1636                 error "stripes not on specified OSTs"
1637
1638         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1639 }
1640 run_test 27ce "more stripes than OSTs with -o"
1641
1642 test_27d() {
1643         test_mkdir $DIR/$tdir
1644         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1645                 error "setstripe failed"
1646         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1647         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1648 }
1649 run_test 27d "create file with default settings"
1650
1651 test_27e() {
1652         # LU-5839 adds check for existed layout before setting it
1653         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1654                 skip "Need MDS version at least 2.7.56"
1655
1656         test_mkdir $DIR/$tdir
1657         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1658         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1659         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1660 }
1661 run_test 27e "setstripe existing file (should return error)"
1662
1663 test_27f() {
1664         test_mkdir $DIR/$tdir
1665         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1666                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1667         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1668                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1669         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1670         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1671 }
1672 run_test 27f "setstripe with bad stripe size (should return error)"
1673
1674 test_27g() {
1675         test_mkdir $DIR/$tdir
1676         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1677         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1678                 error "$DIR/$tdir/$tfile has object"
1679 }
1680 run_test 27g "$LFS getstripe with no objects"
1681
1682 test_27ga() {
1683         test_mkdir $DIR/$tdir
1684         touch $DIR/$tdir/$tfile || error "touch failed"
1685         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1686         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1687         local rc=$?
1688         (( rc == 2 )) || error "getstripe did not return ENOENT"
1689 }
1690 run_test 27ga "$LFS getstripe with missing file (should return error)"
1691
1692 test_27i() {
1693         test_mkdir $DIR/$tdir
1694         touch $DIR/$tdir/$tfile || error "touch failed"
1695         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1696                 error "missing objects"
1697 }
1698 run_test 27i "$LFS getstripe with some objects"
1699
1700 test_27j() {
1701         test_mkdir $DIR/$tdir
1702         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1703                 error "setstripe failed" || true
1704 }
1705 run_test 27j "setstripe with bad stripe offset (should return error)"
1706
1707 test_27k() { # bug 2844
1708         test_mkdir $DIR/$tdir
1709         local file=$DIR/$tdir/$tfile
1710         local ll_max_blksize=$((4 * 1024 * 1024))
1711         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1712         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1713         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1714         dd if=/dev/zero of=$file bs=4k count=1
1715         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1716         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1717 }
1718 run_test 27k "limit i_blksize for broken user apps"
1719
1720 test_27l() {
1721         mcreate $DIR/$tfile || error "creating file"
1722         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1723                 error "setstripe should have failed" || true
1724 }
1725 run_test 27l "check setstripe permissions (should return error)"
1726
1727 test_27m() {
1728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1729
1730         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1731                 skip_env "multiple clients -- skipping"
1732
1733         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1734                    head -n1)
1735         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1736                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1737         fi
1738         trap simple_cleanup_common EXIT
1739         test_mkdir $DIR/$tdir
1740         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1741         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1742                 error "dd should fill OST0"
1743         i=2
1744         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1745                 i=$((i + 1))
1746                 [ $i -gt 256 ] && break
1747         done
1748         i=$((i + 1))
1749         touch $DIR/$tdir/$tfile.$i
1750         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1751             awk '{print $1}'| grep -w "0") ] &&
1752                 error "OST0 was full but new created file still use it"
1753         i=$((i + 1))
1754         touch $DIR/$tdir/$tfile.$i
1755         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1756             awk '{print $1}'| grep -w "0") ] &&
1757                 error "OST0 was full but new created file still use it"
1758         simple_cleanup_common
1759 }
1760 run_test 27m "create file while OST0 was full"
1761
1762 sleep_maxage() {
1763         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1764                       awk '{ print $1 * 2; exit; }')
1765         sleep $delay
1766 }
1767
1768 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1769 # if the OST isn't full anymore.
1770 reset_enospc() {
1771         local OSTIDX=${1:-""}
1772
1773         local list=$(comma_list $(osts_nodes))
1774         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1775
1776         do_nodes $list lctl set_param fail_loc=0
1777         sync    # initiate all OST_DESTROYs from MDS to OST
1778         sleep_maxage
1779 }
1780
1781 exhaust_precreations() {
1782         local OSTIDX=$1
1783         local FAILLOC=$2
1784         local FAILIDX=${3:-$OSTIDX}
1785         local ofacet=ost$((OSTIDX + 1))
1786
1787         test_mkdir -p -c1 $DIR/$tdir
1788         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1789         local mfacet=mds$((mdtidx + 1))
1790         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1791
1792         local OST=$(ostname_from_index $OSTIDX)
1793
1794         # on the mdt's osc
1795         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1796         local last_id=$(do_facet $mfacet lctl get_param -n \
1797                         osc.$mdtosc_proc1.prealloc_last_id)
1798         local next_id=$(do_facet $mfacet lctl get_param -n \
1799                         osc.$mdtosc_proc1.prealloc_next_id)
1800
1801         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1802         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1803
1804         test_mkdir -p $DIR/$tdir/${OST}
1805         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1806 #define OBD_FAIL_OST_ENOSPC              0x215
1807         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1808         echo "Creating to objid $last_id on ost $OST..."
1809         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1810         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1811         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1812         sleep_maxage
1813 }
1814
1815 exhaust_all_precreations() {
1816         local i
1817         for (( i=0; i < OSTCOUNT; i++ )) ; do
1818                 exhaust_precreations $i $1 -1
1819         done
1820 }
1821
1822 test_27n() {
1823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1825         remote_mds_nodsh && skip "remote MDS with nodsh"
1826         remote_ost_nodsh && skip "remote OST with nodsh"
1827
1828         reset_enospc
1829         rm -f $DIR/$tdir/$tfile
1830         exhaust_precreations 0 0x80000215
1831         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1832         touch $DIR/$tdir/$tfile || error "touch failed"
1833         $LFS getstripe $DIR/$tdir/$tfile
1834         reset_enospc
1835 }
1836 run_test 27n "create file with some full OSTs"
1837
1838 test_27o() {
1839         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1841         remote_mds_nodsh && skip "remote MDS with nodsh"
1842         remote_ost_nodsh && skip "remote OST with nodsh"
1843
1844         reset_enospc
1845         rm -f $DIR/$tdir/$tfile
1846         exhaust_all_precreations 0x215
1847
1848         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1849
1850         reset_enospc
1851         rm -rf $DIR/$tdir/*
1852 }
1853 run_test 27o "create file with all full OSTs (should error)"
1854
1855 test_27p() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863         test_mkdir $DIR/$tdir
1864
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1867         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1868
1869         exhaust_precreations 0 0x80000215
1870         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1871         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1872         $LFS getstripe $DIR/$tdir/$tfile
1873
1874         reset_enospc
1875 }
1876 run_test 27p "append to a truncated file with some full OSTs"
1877
1878 test_27q() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886
1887         test_mkdir $DIR/$tdir
1888         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1889         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1890                 error "truncate $DIR/$tdir/$tfile failed"
1891         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1892
1893         exhaust_all_precreations 0x215
1894
1895         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1896         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1897
1898         reset_enospc
1899 }
1900 run_test 27q "append to truncated file with all OSTs full (should error)"
1901
1902 test_27r() {
1903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1905         remote_mds_nodsh && skip "remote MDS with nodsh"
1906         remote_ost_nodsh && skip "remote OST with nodsh"
1907
1908         reset_enospc
1909         rm -f $DIR/$tdir/$tfile
1910         exhaust_precreations 0 0x80000215
1911
1912         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1913
1914         reset_enospc
1915 }
1916 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1917
1918 test_27s() { # bug 10725
1919         test_mkdir $DIR/$tdir
1920         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1921         local stripe_count=0
1922         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1923         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1924                 error "stripe width >= 2^32 succeeded" || true
1925
1926 }
1927 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1928
1929 test_27t() { # bug 10864
1930         WDIR=$(pwd)
1931         WLFS=$(which lfs)
1932         cd $DIR
1933         touch $tfile
1934         $WLFS getstripe $tfile
1935         cd $WDIR
1936 }
1937 run_test 27t "check that utils parse path correctly"
1938
1939 test_27u() { # bug 4900
1940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1941         remote_mds_nodsh && skip "remote MDS with nodsh"
1942
1943         local index
1944         local list=$(comma_list $(mdts_nodes))
1945
1946 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1947         do_nodes $list $LCTL set_param fail_loc=0x139
1948         test_mkdir -p $DIR/$tdir
1949         trap simple_cleanup_common EXIT
1950         createmany -o $DIR/$tdir/t- 1000
1951         do_nodes $list $LCTL set_param fail_loc=0
1952
1953         TLOG=$TMP/$tfile.getstripe
1954         $LFS getstripe $DIR/$tdir > $TLOG
1955         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1956         unlinkmany $DIR/$tdir/t- 1000
1957         trap 0
1958         [[ $OBJS -gt 0 ]] &&
1959                 error "$OBJS objects created on OST-0. See $TLOG" ||
1960                 rm -f $TLOG
1961 }
1962 run_test 27u "skip object creation on OSC w/o objects"
1963
1964 test_27v() { # bug 4900
1965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1967         remote_mds_nodsh && skip "remote MDS with nodsh"
1968         remote_ost_nodsh && skip "remote OST with nodsh"
1969
1970         exhaust_all_precreations 0x215
1971         reset_enospc
1972
1973         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1974
1975         touch $DIR/$tdir/$tfile
1976         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1977         # all except ost1
1978         for (( i=1; i < OSTCOUNT; i++ )); do
1979                 do_facet ost$i lctl set_param fail_loc=0x705
1980         done
1981         local START=`date +%s`
1982         createmany -o $DIR/$tdir/$tfile 32
1983
1984         local FINISH=`date +%s`
1985         local TIMEOUT=`lctl get_param -n timeout`
1986         local PROCESS=$((FINISH - START))
1987         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1988                error "$FINISH - $START >= $TIMEOUT / 2"
1989         sleep $((TIMEOUT / 2 - PROCESS))
1990         reset_enospc
1991 }
1992 run_test 27v "skip object creation on slow OST"
1993
1994 test_27w() { # bug 10997
1995         test_mkdir $DIR/$tdir
1996         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1997         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1998                 error "stripe size $size != 65536" || true
1999         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2000                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2001 }
2002 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2003
2004 test_27wa() {
2005         [[ $OSTCOUNT -lt 2 ]] &&
2006                 skip_env "skipping multiple stripe count/offset test"
2007
2008         test_mkdir $DIR/$tdir
2009         for i in $(seq 1 $OSTCOUNT); do
2010                 offset=$((i - 1))
2011                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2012                         error "setstripe -c $i -i $offset failed"
2013                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2014                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2015                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2016                 [ $index -ne $offset ] &&
2017                         error "stripe offset $index != $offset" || true
2018         done
2019 }
2020 run_test 27wa "check $LFS setstripe -c -i options"
2021
2022 test_27x() {
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2026
2027         OFFSET=$(($OSTCOUNT - 1))
2028         OSTIDX=0
2029         local OST=$(ostname_from_index $OSTIDX)
2030
2031         test_mkdir $DIR/$tdir
2032         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2033         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2034         sleep_maxage
2035         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2036         for i in $(seq 0 $OFFSET); do
2037                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2038                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2039                 error "OST0 was degraded but new created file still use it"
2040         done
2041         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2042 }
2043 run_test 27x "create files while OST0 is degraded"
2044
2045 test_27y() {
2046         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2047         remote_mds_nodsh && skip "remote MDS with nodsh"
2048         remote_ost_nodsh && skip "remote OST with nodsh"
2049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2050
2051         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2052         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2053                 osc.$mdtosc.prealloc_last_id)
2054         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2055                 osc.$mdtosc.prealloc_next_id)
2056         local fcount=$((last_id - next_id))
2057         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2058         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2059
2060         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2061                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2062         local OST_DEACTIVE_IDX=-1
2063         local OSC
2064         local OSTIDX
2065         local OST
2066
2067         for OSC in $MDS_OSCS; do
2068                 OST=$(osc_to_ost $OSC)
2069                 OSTIDX=$(index_from_ostuuid $OST)
2070                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2071                         OST_DEACTIVE_IDX=$OSTIDX
2072                 fi
2073                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2074                         echo $OSC "is Deactivated:"
2075                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2076                 fi
2077         done
2078
2079         OSTIDX=$(index_from_ostuuid $OST)
2080         test_mkdir $DIR/$tdir
2081         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2082
2083         for OSC in $MDS_OSCS; do
2084                 OST=$(osc_to_ost $OSC)
2085                 OSTIDX=$(index_from_ostuuid $OST)
2086                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2087                         echo $OST "is degraded:"
2088                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2089                                                 obdfilter.$OST.degraded=1
2090                 fi
2091         done
2092
2093         sleep_maxage
2094         createmany -o $DIR/$tdir/$tfile $fcount
2095
2096         for OSC in $MDS_OSCS; do
2097                 OST=$(osc_to_ost $OSC)
2098                 OSTIDX=$(index_from_ostuuid $OST)
2099                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2100                         echo $OST "is recovered from degraded:"
2101                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2102                                                 obdfilter.$OST.degraded=0
2103                 else
2104                         do_facet $SINGLEMDS lctl --device %$OSC activate
2105                 fi
2106         done
2107
2108         # all osp devices get activated, hence -1 stripe count restored
2109         local stripe_count=0
2110
2111         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2112         # devices get activated.
2113         sleep_maxage
2114         $LFS setstripe -c -1 $DIR/$tfile
2115         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2116         rm -f $DIR/$tfile
2117         [ $stripe_count -ne $OSTCOUNT ] &&
2118                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2119         return 0
2120 }
2121 run_test 27y "create files while OST0 is degraded and the rest inactive"
2122
2123 check_seq_oid()
2124 {
2125         log "check file $1"
2126
2127         lmm_count=$($LFS getstripe -c $1)
2128         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2129         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2130
2131         local old_ifs="$IFS"
2132         IFS=$'[:]'
2133         fid=($($LFS path2fid $1))
2134         IFS="$old_ifs"
2135
2136         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2137         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2138
2139         # compare lmm_seq and lu_fid->f_seq
2140         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2141         # compare lmm_object_id and lu_fid->oid
2142         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2143
2144         # check the trusted.fid attribute of the OST objects of the file
2145         local have_obdidx=false
2146         local stripe_nr=0
2147         $LFS getstripe $1 | while read obdidx oid hex seq; do
2148                 # skip lines up to and including "obdidx"
2149                 [ -z "$obdidx" ] && break
2150                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2151                 $have_obdidx || continue
2152
2153                 local ost=$((obdidx + 1))
2154                 local dev=$(ostdevname $ost)
2155                 local oid_hex
2156
2157                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2158
2159                 seq=$(echo $seq | sed -e "s/^0x//g")
2160                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2161                         oid_hex=$(echo $oid)
2162                 else
2163                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2164                 fi
2165                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2166
2167                 local ff=""
2168                 #
2169                 # Don't unmount/remount the OSTs if we don't need to do that.
2170                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2171                 # update too, until that use mount/ll_decode_filter_fid/mount.
2172                 # Re-enable when debugfs will understand new filter_fid.
2173                 #
2174                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2175                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2176                                 $dev 2>/dev/null" | grep "parent=")
2177                 fi
2178                 if [ -z "$ff" ]; then
2179                         stop ost$ost
2180                         mount_fstype ost$ost
2181                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2182                                 $(facet_mntpt ost$ost)/$obj_file)
2183                         unmount_fstype ost$ost
2184                         start ost$ost $dev $OST_MOUNT_OPTS
2185                         clients_up
2186                 fi
2187
2188                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2189
2190                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2191
2192                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2193                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2194                 #
2195                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2196                 #       stripe_size=1048576 component_id=1 component_start=0 \
2197                 #       component_end=33554432
2198                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2199                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2200                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2201                 local ff_pstripe
2202                 if grep -q 'stripe=' <<<$ff; then
2203                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2204                 else
2205                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2206                         # into f_ver in this case.  See comment on ff_parent.
2207                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2208                 fi
2209
2210                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2211                 [ $ff_pseq = $lmm_seq ] ||
2212                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2213                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2214                 [ $ff_poid = $lmm_oid ] ||
2215                         error "FF parent OID $ff_poid != $lmm_oid"
2216                 (($ff_pstripe == $stripe_nr)) ||
2217                         error "FF stripe $ff_pstripe != $stripe_nr"
2218
2219                 stripe_nr=$((stripe_nr + 1))
2220                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2221                         continue
2222                 if grep -q 'stripe_count=' <<<$ff; then
2223                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2224                                             -e 's/ .*//' <<<$ff)
2225                         [ $lmm_count = $ff_scnt ] ||
2226                                 error "FF stripe count $lmm_count != $ff_scnt"
2227                 fi
2228         done
2229 }
2230
2231 test_27z() {
2232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2233         remote_ost_nodsh && skip "remote OST with nodsh"
2234
2235         test_mkdir $DIR/$tdir
2236         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2237                 { error "setstripe -c -1 failed"; return 1; }
2238         # We need to send a write to every object to get parent FID info set.
2239         # This _should_ also work for setattr, but does not currently.
2240         # touch $DIR/$tdir/$tfile-1 ||
2241         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2242                 { error "dd $tfile-1 failed"; return 2; }
2243         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2244                 { error "setstripe -c -1 failed"; return 3; }
2245         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2246                 { error "dd $tfile-2 failed"; return 4; }
2247
2248         # make sure write RPCs have been sent to OSTs
2249         sync; sleep 5; sync
2250
2251         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2252         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2253 }
2254 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2255
2256 test_27A() { # b=19102
2257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2258
2259         save_layout_restore_at_exit $MOUNT
2260         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2261         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2262                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2263         local default_size=$($LFS getstripe -S $MOUNT)
2264         local default_offset=$($LFS getstripe -i $MOUNT)
2265         local dsize=$(do_facet $SINGLEMDS \
2266                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2267         [ $default_size -eq $dsize ] ||
2268                 error "stripe size $default_size != $dsize"
2269         [ $default_offset -eq -1 ] ||
2270                 error "stripe offset $default_offset != -1"
2271 }
2272 run_test 27A "check filesystem-wide default LOV EA values"
2273
2274 test_27B() { # LU-2523
2275         test_mkdir $DIR/$tdir
2276         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2277         touch $DIR/$tdir/f0
2278         # open f1 with O_LOV_DELAY_CREATE
2279         # rename f0 onto f1
2280         # call setstripe ioctl on open file descriptor for f1
2281         # close
2282         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2283                 $DIR/$tdir/f0
2284
2285         rm -f $DIR/$tdir/f1
2286         # open f1 with O_LOV_DELAY_CREATE
2287         # unlink f1
2288         # call setstripe ioctl on open file descriptor for f1
2289         # close
2290         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2291
2292         # Allow multiop to fail in imitation of NFS's busted semantics.
2293         true
2294 }
2295 run_test 27B "call setstripe on open unlinked file/rename victim"
2296
2297 # 27C family tests full striping and overstriping
2298 test_27Ca() { #LU-2871
2299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2300
2301         declare -a ost_idx
2302         local index
2303         local found
2304         local i
2305         local j
2306
2307         test_mkdir $DIR/$tdir
2308         cd $DIR/$tdir
2309         for i in $(seq 0 $((OSTCOUNT - 1))); do
2310                 # set stripe across all OSTs starting from OST$i
2311                 $LFS setstripe -i $i -c -1 $tfile$i
2312                 # get striping information
2313                 ost_idx=($($LFS getstripe $tfile$i |
2314                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2315                 echo ${ost_idx[@]}
2316
2317                 # check the layout
2318                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2319                         error "${#ost_idx[@]} != $OSTCOUNT"
2320
2321                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2322                         found=0
2323                         for j in $(echo ${ost_idx[@]}); do
2324                                 if [ $index -eq $j ]; then
2325                                         found=1
2326                                         break
2327                                 fi
2328                         done
2329                         [ $found = 1 ] ||
2330                                 error "Can not find $index in ${ost_idx[@]}"
2331                 done
2332         done
2333 }
2334 run_test 27Ca "check full striping across all OSTs"
2335
2336 test_27Cb() {
2337         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2338                 skip "server does not support overstriping"
2339         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2340                 skip_env "too many osts, skipping"
2341
2342         test_mkdir -p $DIR/$tdir
2343         local setcount=$(($OSTCOUNT * 2))
2344         [ $setcount -ge 160 ] || large_xattr_enabled ||
2345                 skip_env "ea_inode feature disabled"
2346
2347         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2348                 error "setstripe failed"
2349
2350         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2351         [ $count -eq $setcount ] ||
2352                 error "stripe count $count, should be $setcount"
2353
2354         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2355                 error "overstriped should be set in pattern"
2356
2357         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2358                 error "dd failed"
2359 }
2360 run_test 27Cb "more stripes than OSTs with -C"
2361
2362 test_27Cc() {
2363         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2364                 skip "server does not support overstriping"
2365         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2366
2367         test_mkdir -p $DIR/$tdir
2368         local setcount=$(($OSTCOUNT - 1))
2369
2370         [ $setcount -ge 160 ] || large_xattr_enabled ||
2371                 skip_env "ea_inode feature disabled"
2372
2373         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2374                 error "setstripe failed"
2375
2376         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2377         [ $count -eq $setcount ] ||
2378                 error "stripe count $count, should be $setcount"
2379
2380         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2381                 error "overstriped should not be set in pattern"
2382
2383         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2384                 error "dd failed"
2385 }
2386 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2387
2388 test_27Cd() {
2389         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2390                 skip "server does not support overstriping"
2391         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2392         large_xattr_enabled || skip_env "ea_inode feature disabled"
2393
2394         test_mkdir -p $DIR/$tdir
2395         local setcount=$LOV_MAX_STRIPE_COUNT
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2405                 error "overstriped should be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409
2410         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2411 }
2412 run_test 27Cd "test maximum stripe count"
2413
2414 test_27Ce() {
2415         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2416                 skip "server does not support overstriping"
2417         test_mkdir -p $DIR/$tdir
2418
2419         pool_add $TESTNAME || error "Pool creation failed"
2420         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2421
2422         local setcount=8
2423
2424         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2425                 error "setstripe failed"
2426
2427         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2428         [ $count -eq $setcount ] ||
2429                 error "stripe count $count, should be $setcount"
2430
2431         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2432                 error "overstriped should be set in pattern"
2433
2434         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2435                 error "dd failed"
2436
2437         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2438 }
2439 run_test 27Ce "test pool with overstriping"
2440
2441 test_27Cf() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2445                 skip_env "too many osts, skipping"
2446
2447         test_mkdir -p $DIR/$tdir
2448
2449         local setcount=$(($OSTCOUNT * 2))
2450         [ $setcount -ge 160 ] || large_xattr_enabled ||
2451                 skip_env "ea_inode feature disabled"
2452
2453         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2454                 error "setstripe failed"
2455
2456         echo 1 > $DIR/$tdir/$tfile
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Cf "test default inheritance with overstriping"
2471
2472 test_27D() {
2473         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2474         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2475         remote_mds_nodsh && skip "remote MDS with nodsh"
2476
2477         local POOL=${POOL:-testpool}
2478         local first_ost=0
2479         local last_ost=$(($OSTCOUNT - 1))
2480         local ost_step=1
2481         local ost_list=$(seq $first_ost $ost_step $last_ost)
2482         local ost_range="$first_ost $last_ost $ost_step"
2483
2484         if ! combined_mgs_mds ; then
2485                 mount_mgs_client
2486         fi
2487
2488         test_mkdir $DIR/$tdir
2489         pool_add $POOL || error "pool_add failed"
2490         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2491
2492         local skip27D
2493         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2494                 skip27D+="-s 29"
2495         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2496                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2497                         skip27D+=" -s 30,31"
2498         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2499           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2500                 skip27D+=" -s 32,33"
2501         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2502                 error "llapi_layout_test failed"
2503
2504         destroy_test_pools || error "destroy test pools failed"
2505
2506         if ! combined_mgs_mds ; then
2507                 umount_mgs_client
2508         fi
2509 }
2510 run_test 27D "validate llapi_layout API"
2511
2512 # Verify that default_easize is increased from its initial value after
2513 # accessing a widely striped file.
2514 test_27E() {
2515         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2516         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2517                 skip "client does not have LU-3338 fix"
2518
2519         # 72 bytes is the minimum space required to store striping
2520         # information for a file striped across one OST:
2521         # (sizeof(struct lov_user_md_v3) +
2522         #  sizeof(struct lov_user_ost_data_v1))
2523         local min_easize=72
2524         $LCTL set_param -n llite.*.default_easize $min_easize ||
2525                 error "lctl set_param failed"
2526         local easize=$($LCTL get_param -n llite.*.default_easize)
2527
2528         [ $easize -eq $min_easize ] ||
2529                 error "failed to set default_easize"
2530
2531         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2532                 error "setstripe failed"
2533         # In order to ensure stat() call actually talks to MDS we need to
2534         # do something drastic to this file to shake off all lock, e.g.
2535         # rename it (kills lookup lock forcing cache cleaning)
2536         mv $DIR/$tfile $DIR/${tfile}-1
2537         ls -l $DIR/${tfile}-1
2538         rm $DIR/${tfile}-1
2539
2540         easize=$($LCTL get_param -n llite.*.default_easize)
2541
2542         [ $easize -gt $min_easize ] ||
2543                 error "default_easize not updated"
2544 }
2545 run_test 27E "check that default extended attribute size properly increases"
2546
2547 test_27F() { # LU-5346/LU-7975
2548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2549         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2550         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2551                 skip "Need MDS version at least 2.8.51"
2552         remote_ost_nodsh && skip "remote OST with nodsh"
2553
2554         test_mkdir $DIR/$tdir
2555         rm -f $DIR/$tdir/f0
2556         $LFS setstripe -c 2 $DIR/$tdir
2557
2558         # stop all OSTs to reproduce situation for LU-7975 ticket
2559         for num in $(seq $OSTCOUNT); do
2560                 stop ost$num
2561         done
2562
2563         # open/create f0 with O_LOV_DELAY_CREATE
2564         # truncate f0 to a non-0 size
2565         # close
2566         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2567
2568         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2569         # open/write it again to force delayed layout creation
2570         cat /etc/hosts > $DIR/$tdir/f0 &
2571         catpid=$!
2572
2573         # restart OSTs
2574         for num in $(seq $OSTCOUNT); do
2575                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2576                         error "ost$num failed to start"
2577         done
2578
2579         wait $catpid || error "cat failed"
2580
2581         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2582         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2583                 error "wrong stripecount"
2584
2585 }
2586 run_test 27F "Client resend delayed layout creation with non-zero size"
2587
2588 test_27G() { #LU-10629
2589         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2590                 skip "Need MDS version at least 2.11.51"
2591         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2592         remote_mds_nodsh && skip "remote MDS with nodsh"
2593         local POOL=${POOL:-testpool}
2594         local ostrange="0 0 1"
2595
2596         test_mkdir $DIR/$tdir
2597         pool_add $POOL || error "pool_add failed"
2598         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2599         $LFS setstripe -p $POOL $DIR/$tdir
2600
2601         local pool=$($LFS getstripe -p $DIR/$tdir)
2602
2603         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2604
2605         $LFS setstripe -d $DIR/$tdir
2606
2607         pool=$($LFS getstripe -p $DIR/$tdir)
2608
2609         rmdir $DIR/$tdir
2610
2611         [ -z "$pool" ] || error "'$pool' is not empty"
2612 }
2613 run_test 27G "Clear OST pool from stripe"
2614
2615 test_27H() {
2616         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2617                 skip "Need MDS version newer than 2.11.54"
2618         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2619         test_mkdir $DIR/$tdir
2620         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2621         touch $DIR/$tdir/$tfile
2622         $LFS getstripe -c $DIR/$tdir/$tfile
2623         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2624                 error "two-stripe file doesn't have two stripes"
2625
2626         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2627         $LFS getstripe -y $DIR/$tdir/$tfile
2628         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2629              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2630                 error "expected l_ost_idx: [02]$ not matched"
2631
2632         # make sure ost list has been cleared
2633         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2634         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2635                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2636         touch $DIR/$tdir/f3
2637         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2638 }
2639 run_test 27H "Set specific OSTs stripe"
2640
2641 test_27I() {
2642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2643         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2644         local pool=$TESTNAME
2645         local ostrange="1 1 1"
2646
2647         save_layout_restore_at_exit $MOUNT
2648         $LFS setstripe -c 2 -i 0 $MOUNT
2649         pool_add $pool || error "pool_add failed"
2650         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2651         test_mkdir $DIR/$tdir
2652         $LFS setstripe -p $pool $DIR/$tdir
2653         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2654         $LFS getstripe $DIR/$tdir/$tfile
2655 }
2656 run_test 27I "check that root dir striping does not break parent dir one"
2657
2658 test_27J() {
2659         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2660                 skip "Need MDS version newer than 2.12.51"
2661
2662         test_mkdir $DIR/$tdir
2663         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2664         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2665
2666         # create foreign file (raw way)
2667         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2668                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2669
2670         # verify foreign file (raw way)
2671         parse_foreign_file -f $DIR/$tdir/$tfile |
2672                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2673                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2674         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2675                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2676         parse_foreign_file -f $DIR/$tdir/$tfile |
2677                 grep "lov_foreign_size: 73" ||
2678                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2679         parse_foreign_file -f $DIR/$tdir/$tfile |
2680                 grep "lov_foreign_type: 1" ||
2681                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2682         parse_foreign_file -f $DIR/$tdir/$tfile |
2683                 grep "lov_foreign_flags: 0x0000DA08" ||
2684                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2685         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2686                 grep "lov_foreign_value: 0x" |
2687                 sed -e 's/lov_foreign_value: 0x//')
2688         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2689         [[ $lov = ${lov2// /} ]] ||
2690                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2691
2692         # create foreign file (lfs + API)
2693         $LFS setstripe --foreign=daos --flags 0xda08 \
2694                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2695                 error "$DIR/$tdir/${tfile}2: create failed"
2696
2697         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2698                 grep "lfm_magic:.*0x0BD70BD0" ||
2699                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2700         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2701         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2702                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2703         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2704                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2705         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2706                 grep "lfm_flags:.*0x0000DA08" ||
2707                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2708         $LFS getstripe $DIR/$tdir/${tfile}2 |
2709                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2710                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2711
2712         # modify striping should fail
2713         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2714                 error "$DIR/$tdir/$tfile: setstripe should fail"
2715         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2716                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2717
2718         # R/W should fail
2719         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2720         cat $DIR/$tdir/${tfile}2 &&
2721                 error "$DIR/$tdir/${tfile}2: read should fail"
2722         cat /etc/passwd > $DIR/$tdir/$tfile &&
2723                 error "$DIR/$tdir/$tfile: write should fail"
2724         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2725                 error "$DIR/$tdir/${tfile}2: write should fail"
2726
2727         # chmod should work
2728         chmod 222 $DIR/$tdir/$tfile ||
2729                 error "$DIR/$tdir/$tfile: chmod failed"
2730         chmod 222 $DIR/$tdir/${tfile}2 ||
2731                 error "$DIR/$tdir/${tfile}2: chmod failed"
2732
2733         # chown should work
2734         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2735                 error "$DIR/$tdir/$tfile: chown failed"
2736         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2737                 error "$DIR/$tdir/${tfile}2: chown failed"
2738
2739         # rename should work
2740         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2741                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2742         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2743                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2744
2745         #remove foreign file
2746         rm $DIR/$tdir/${tfile}.new ||
2747                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2748         rm $DIR/$tdir/${tfile}2.new ||
2749                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2750 }
2751 run_test 27J "basic ops on file with foreign LOV"
2752
2753 test_27K() {
2754         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2755                 skip "Need MDS version newer than 2.12.49"
2756
2757         test_mkdir $DIR/$tdir
2758         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2759         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2760
2761         # create foreign dir (raw way)
2762         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2763                 error "create_foreign_dir FAILED"
2764
2765         # verify foreign dir (raw way)
2766         parse_foreign_dir -d $DIR/$tdir/$tdir |
2767                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2768                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2769         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2770                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2771         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2772                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2773         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2774                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2775         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2776                 grep "lmv_foreign_value: 0x" |
2777                 sed 's/lmv_foreign_value: 0x//')
2778         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2779                 sed 's/ //g')
2780         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2781
2782         # create foreign dir (lfs + API)
2783         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2784                 $DIR/$tdir/${tdir}2 ||
2785                 error "$DIR/$tdir/${tdir}2: create failed"
2786
2787         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2788                 grep "lfm_magic:.*0x0CD50CD0" ||
2789                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2790         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2791         # - sizeof(lfm_type) - sizeof(lfm_flags)
2792         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2793                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2794         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2795                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2796         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2797                 grep "lfm_flags:.*0x0000DA05" ||
2798                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2799         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2800                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2801                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2802
2803         # file create in dir should fail
2804         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2805         touch $DIR/$tdir/${tdir}2/$tfile &&
2806                 "$DIR/${tdir}2: file create should fail"
2807
2808         # chmod should work
2809         chmod 777 $DIR/$tdir/$tdir ||
2810                 error "$DIR/$tdir: chmod failed"
2811         chmod 777 $DIR/$tdir/${tdir}2 ||
2812                 error "$DIR/${tdir}2: chmod failed"
2813
2814         # chown should work
2815         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2816                 error "$DIR/$tdir: chown failed"
2817         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2818                 error "$DIR/${tdir}2: chown failed"
2819
2820         # rename should work
2821         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2822                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2823         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2824                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2825
2826         #remove foreign dir
2827         rmdir $DIR/$tdir/${tdir}.new ||
2828                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2829         rmdir $DIR/$tdir/${tdir}2.new ||
2830                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2831 }
2832 run_test 27K "basic ops on dir with foreign LMV"
2833
2834 # createtest also checks that device nodes are created and
2835 # then visible correctly (#2091)
2836 test_28() { # bug 2091
2837         test_mkdir $DIR/d28
2838         $CREATETEST $DIR/d28/ct || error "createtest failed"
2839 }
2840 run_test 28 "create/mknod/mkdir with bad file types ============"
2841
2842 test_29() {
2843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2844
2845         sync; sleep 1; sync # flush out any dirty pages from previous tests
2846         cancel_lru_locks
2847         test_mkdir $DIR/d29
2848         touch $DIR/d29/foo
2849         log 'first d29'
2850         ls -l $DIR/d29
2851
2852         declare -i LOCKCOUNTORIG=0
2853         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2854                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2855         done
2856         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2857
2858         declare -i LOCKUNUSEDCOUNTORIG=0
2859         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2860                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2861         done
2862
2863         log 'second d29'
2864         ls -l $DIR/d29
2865         log 'done'
2866
2867         declare -i LOCKCOUNTCURRENT=0
2868         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2869                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2870         done
2871
2872         declare -i LOCKUNUSEDCOUNTCURRENT=0
2873         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2874                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2875         done
2876
2877         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2878                 $LCTL set_param -n ldlm.dump_namespaces ""
2879                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2880                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2881                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2882                 return 2
2883         fi
2884         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2885                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2886                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2887                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2888                 return 3
2889         fi
2890 }
2891 run_test 29 "IT_GETATTR regression  ============================"
2892
2893 test_30a() { # was test_30
2894         cp $(which ls) $DIR || cp /bin/ls $DIR
2895         $DIR/ls / || error "Can't execute binary from lustre"
2896         rm $DIR/ls
2897 }
2898 run_test 30a "execute binary from Lustre (execve) =============="
2899
2900 test_30b() {
2901         cp `which ls` $DIR || cp /bin/ls $DIR
2902         chmod go+rx $DIR/ls
2903         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2904         rm $DIR/ls
2905 }
2906 run_test 30b "execute binary from Lustre as non-root ==========="
2907
2908 test_30c() { # b=22376
2909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2910
2911         cp `which ls` $DIR || cp /bin/ls $DIR
2912         chmod a-rw $DIR/ls
2913         cancel_lru_locks mdc
2914         cancel_lru_locks osc
2915         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2916         rm -f $DIR/ls
2917 }
2918 run_test 30c "execute binary from Lustre without read perms ===="
2919
2920 test_31a() {
2921         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2922         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2923 }
2924 run_test 31a "open-unlink file =================================="
2925
2926 test_31b() {
2927         touch $DIR/f31 || error "touch $DIR/f31 failed"
2928         ln $DIR/f31 $DIR/f31b || error "ln failed"
2929         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2930         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2931 }
2932 run_test 31b "unlink file with multiple links while open ======="
2933
2934 test_31c() {
2935         touch $DIR/f31 || error "touch $DIR/f31 failed"
2936         ln $DIR/f31 $DIR/f31c || error "ln failed"
2937         multiop_bg_pause $DIR/f31 O_uc ||
2938                 error "multiop_bg_pause for $DIR/f31 failed"
2939         MULTIPID=$!
2940         $MULTIOP $DIR/f31c Ouc
2941         kill -USR1 $MULTIPID
2942         wait $MULTIPID
2943 }
2944 run_test 31c "open-unlink file with multiple links ============="
2945
2946 test_31d() {
2947         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2948         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2949 }
2950 run_test 31d "remove of open directory ========================="
2951
2952 test_31e() { # bug 2904
2953         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2954 }
2955 run_test 31e "remove of open non-empty directory ==============="
2956
2957 test_31f() { # bug 4554
2958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2959
2960         set -vx
2961         test_mkdir $DIR/d31f
2962         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2963         cp /etc/hosts $DIR/d31f
2964         ls -l $DIR/d31f
2965         $LFS getstripe $DIR/d31f/hosts
2966         multiop_bg_pause $DIR/d31f D_c || return 1
2967         MULTIPID=$!
2968
2969         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2970         test_mkdir $DIR/d31f
2971         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2972         cp /etc/hosts $DIR/d31f
2973         ls -l $DIR/d31f
2974         $LFS getstripe $DIR/d31f/hosts
2975         multiop_bg_pause $DIR/d31f D_c || return 1
2976         MULTIPID2=$!
2977
2978         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2979         wait $MULTIPID || error "first opendir $MULTIPID failed"
2980
2981         sleep 6
2982
2983         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2984         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2985         set +vx
2986 }
2987 run_test 31f "remove of open directory with open-unlink file ==="
2988
2989 test_31g() {
2990         echo "-- cross directory link --"
2991         test_mkdir -c1 $DIR/${tdir}ga
2992         test_mkdir -c1 $DIR/${tdir}gb
2993         touch $DIR/${tdir}ga/f
2994         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2995         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2996         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2997         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2998         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2999 }
3000 run_test 31g "cross directory link==============="
3001
3002 test_31h() {
3003         echo "-- cross directory link --"
3004         test_mkdir -c1 $DIR/${tdir}
3005         test_mkdir -c1 $DIR/${tdir}/dir
3006         touch $DIR/${tdir}/f
3007         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3008         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3009         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3010         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3011         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3012 }
3013 run_test 31h "cross directory link under child==============="
3014
3015 test_31i() {
3016         echo "-- cross directory link --"
3017         test_mkdir -c1 $DIR/$tdir
3018         test_mkdir -c1 $DIR/$tdir/dir
3019         touch $DIR/$tdir/dir/f
3020         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3021         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3022         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3023         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3024         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3025 }
3026 run_test 31i "cross directory link under parent==============="
3027
3028 test_31j() {
3029         test_mkdir -c1 -p $DIR/$tdir
3030         test_mkdir -c1 -p $DIR/$tdir/dir1
3031         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3032         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3033         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3034         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3035         return 0
3036 }
3037 run_test 31j "link for directory==============="
3038
3039 test_31k() {
3040         test_mkdir -c1 -p $DIR/$tdir
3041         touch $DIR/$tdir/s
3042         touch $DIR/$tdir/exist
3043         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3044         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3045         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3046         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3047         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3048         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3049         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3050         return 0
3051 }
3052 run_test 31k "link to file: the same, non-existing, dir==============="
3053
3054 test_31m() {
3055         mkdir $DIR/d31m
3056         touch $DIR/d31m/s
3057         mkdir $DIR/d31m2
3058         touch $DIR/d31m2/exist
3059         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3060         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3061         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3062         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3063         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3064         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3065         return 0
3066 }
3067 run_test 31m "link to file: the same, non-existing, dir==============="
3068
3069 test_31n() {
3070         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3071         nlink=$(stat --format=%h $DIR/$tfile)
3072         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3073         local fd=$(free_fd)
3074         local cmd="exec $fd<$DIR/$tfile"
3075         eval $cmd
3076         cmd="exec $fd<&-"
3077         trap "eval $cmd" EXIT
3078         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3079         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3080         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3081         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3082         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3083         eval $cmd
3084 }
3085 run_test 31n "check link count of unlinked file"
3086
3087 link_one() {
3088         local TEMPNAME=$(mktemp $1_XXXXXX)
3089         mlink $TEMPNAME $1 2> /dev/null &&
3090                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3091         munlink $TEMPNAME
3092 }
3093
3094 test_31o() { # LU-2901
3095         test_mkdir $DIR/$tdir
3096         for LOOP in $(seq 100); do
3097                 rm -f $DIR/$tdir/$tfile*
3098                 for THREAD in $(seq 8); do
3099                         link_one $DIR/$tdir/$tfile.$LOOP &
3100                 done
3101                 wait
3102                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3103                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3104                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3105                         break || true
3106         done
3107 }
3108 run_test 31o "duplicate hard links with same filename"
3109
3110 test_31p() {
3111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3112
3113         test_mkdir $DIR/$tdir
3114         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3115         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3116
3117         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3118                 error "open unlink test1 failed"
3119         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3120                 error "open unlink test2 failed"
3121
3122         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3123                 error "test1 still exists"
3124         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3125                 error "test2 still exists"
3126 }
3127 run_test 31p "remove of open striped directory"
3128
3129 cleanup_test32_mount() {
3130         local rc=0
3131         trap 0
3132         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3133         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3134         losetup -d $loopdev || true
3135         rm -rf $DIR/$tdir
3136         return $rc
3137 }
3138
3139 test_32a() {
3140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3141
3142         echo "== more mountpoints and symlinks ================="
3143         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3144         trap cleanup_test32_mount EXIT
3145         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3146         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3147                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3148         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3149                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3150         cleanup_test32_mount
3151 }
3152 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3153
3154 test_32b() {
3155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3156
3157         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3158         trap cleanup_test32_mount EXIT
3159         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3160         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3161                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3162         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3163                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3164         cleanup_test32_mount
3165 }
3166 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3167
3168 test_32c() {
3169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3170
3171         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3172         trap cleanup_test32_mount EXIT
3173         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3174         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3175                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3176         test_mkdir -p $DIR/$tdir/d2/test_dir
3177         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3178                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3179         cleanup_test32_mount
3180 }
3181 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3182
3183 test_32d() {
3184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3185
3186         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3187         trap cleanup_test32_mount EXIT
3188         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3189         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3190                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3191         test_mkdir -p $DIR/$tdir/d2/test_dir
3192         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3193                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3194         cleanup_test32_mount
3195 }
3196 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3197
3198 test_32e() {
3199         rm -fr $DIR/$tdir
3200         test_mkdir -p $DIR/$tdir/tmp
3201         local tmp_dir=$DIR/$tdir/tmp
3202         ln -s $DIR/$tdir $tmp_dir/symlink11
3203         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3204         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3205         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3206 }
3207 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3208
3209 test_32f() {
3210         rm -fr $DIR/$tdir
3211         test_mkdir -p $DIR/$tdir/tmp
3212         local tmp_dir=$DIR/$tdir/tmp
3213         ln -s $DIR/$tdir $tmp_dir/symlink11
3214         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3215         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3216         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3217 }
3218 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3219
3220 test_32g() {
3221         local tmp_dir=$DIR/$tdir/tmp
3222         test_mkdir -p $tmp_dir
3223         test_mkdir $DIR/${tdir}2
3224         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3225         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3226         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3227         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3228         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3229         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3230 }
3231 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3232
3233 test_32h() {
3234         rm -fr $DIR/$tdir $DIR/${tdir}2
3235         tmp_dir=$DIR/$tdir/tmp
3236         test_mkdir -p $tmp_dir
3237         test_mkdir $DIR/${tdir}2
3238         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3239         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3240         ls $tmp_dir/symlink12 || error "listing symlink12"
3241         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3242 }
3243 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3244
3245 test_32i() {
3246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3247
3248         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3249         trap cleanup_test32_mount EXIT
3250         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3251         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3252                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3253         touch $DIR/$tdir/test_file
3254         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3255                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3256         cleanup_test32_mount
3257 }
3258 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3259
3260 test_32j() {
3261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3262
3263         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3264         trap cleanup_test32_mount EXIT
3265         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3266         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3267                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3268         touch $DIR/$tdir/test_file
3269         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3270                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3271         cleanup_test32_mount
3272 }
3273 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3274
3275 test_32k() {
3276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3277
3278         rm -fr $DIR/$tdir
3279         trap cleanup_test32_mount EXIT
3280         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3281         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3282                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3283         test_mkdir -p $DIR/$tdir/d2
3284         touch $DIR/$tdir/d2/test_file || error "touch failed"
3285         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3286                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3287         cleanup_test32_mount
3288 }
3289 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3290
3291 test_32l() {
3292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3293
3294         rm -fr $DIR/$tdir
3295         trap cleanup_test32_mount EXIT
3296         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3297         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3298                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3299         test_mkdir -p $DIR/$tdir/d2
3300         touch $DIR/$tdir/d2/test_file || error "touch failed"
3301         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3302                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3303         cleanup_test32_mount
3304 }
3305 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3306
3307 test_32m() {
3308         rm -fr $DIR/d32m
3309         test_mkdir -p $DIR/d32m/tmp
3310         TMP_DIR=$DIR/d32m/tmp
3311         ln -s $DIR $TMP_DIR/symlink11
3312         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3313         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3314                 error "symlink11 not a link"
3315         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3316                 error "symlink01 not a link"
3317 }
3318 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3319
3320 test_32n() {
3321         rm -fr $DIR/d32n
3322         test_mkdir -p $DIR/d32n/tmp
3323         TMP_DIR=$DIR/d32n/tmp
3324         ln -s $DIR $TMP_DIR/symlink11
3325         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3326         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3327         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3328 }
3329 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3330
3331 test_32o() {
3332         touch $DIR/$tfile
3333         test_mkdir -p $DIR/d32o/tmp
3334         TMP_DIR=$DIR/d32o/tmp
3335         ln -s $DIR/$tfile $TMP_DIR/symlink12
3336         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3337         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3338                 error "symlink12 not a link"
3339         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3340         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3341                 error "$DIR/d32o/tmp/symlink12 not file type"
3342         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3343                 error "$DIR/d32o/symlink02 not file type"
3344 }
3345 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3346
3347 test_32p() {
3348         log 32p_1
3349         rm -fr $DIR/d32p
3350         log 32p_2
3351         rm -f $DIR/$tfile
3352         log 32p_3
3353         touch $DIR/$tfile
3354         log 32p_4
3355         test_mkdir -p $DIR/d32p/tmp
3356         log 32p_5
3357         TMP_DIR=$DIR/d32p/tmp
3358         log 32p_6
3359         ln -s $DIR/$tfile $TMP_DIR/symlink12
3360         log 32p_7
3361         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3362         log 32p_8
3363         cat $DIR/d32p/tmp/symlink12 ||
3364                 error "Can't open $DIR/d32p/tmp/symlink12"
3365         log 32p_9
3366         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3367         log 32p_10
3368 }
3369 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3370
3371 test_32q() {
3372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3373
3374         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3375         trap cleanup_test32_mount EXIT
3376         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3377         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3378         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3379                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3380         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3381         cleanup_test32_mount
3382 }
3383 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3384
3385 test_32r() {
3386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3387
3388         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3389         trap cleanup_test32_mount EXIT
3390         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3391         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3392         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3393                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3394         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3395         cleanup_test32_mount
3396 }
3397 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3398
3399 test_33aa() {
3400         rm -f $DIR/$tfile
3401         touch $DIR/$tfile
3402         chmod 444 $DIR/$tfile
3403         chown $RUNAS_ID $DIR/$tfile
3404         log 33_1
3405         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3406         log 33_2
3407 }
3408 run_test 33aa "write file with mode 444 (should return error)"
3409
3410 test_33a() {
3411         rm -fr $DIR/$tdir
3412         test_mkdir $DIR/$tdir
3413         chown $RUNAS_ID $DIR/$tdir
3414         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3415                 error "$RUNAS create $tdir/$tfile failed"
3416         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3417                 error "open RDWR" || true
3418 }
3419 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3420
3421 test_33b() {
3422         rm -fr $DIR/$tdir
3423         test_mkdir $DIR/$tdir
3424         chown $RUNAS_ID $DIR/$tdir
3425         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3426 }
3427 run_test 33b "test open file with malformed flags (No panic)"
3428
3429 test_33c() {
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431         remote_ost_nodsh && skip "remote OST with nodsh"
3432
3433         local ostnum
3434         local ostname
3435         local write_bytes
3436         local all_zeros
3437
3438         all_zeros=:
3439         rm -fr $DIR/$tdir
3440         test_mkdir $DIR/$tdir
3441         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3442
3443         sync
3444         for ostnum in $(seq $OSTCOUNT); do
3445                 # test-framework's OST numbering is one-based, while Lustre's
3446                 # is zero-based
3447                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3448                 # Parsing llobdstat's output sucks; we could grep the /proc
3449                 # path, but that's likely to not be as portable as using the
3450                 # llobdstat utility.  So we parse lctl output instead.
3451                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3452                         obdfilter/$ostname/stats |
3453                         awk '/^write_bytes/ {print $7}' )
3454                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3455                 if (( ${write_bytes:-0} > 0 ))
3456                 then
3457                         all_zeros=false
3458                         break;
3459                 fi
3460         done
3461
3462         $all_zeros || return 0
3463
3464         # Write four bytes
3465         echo foo > $DIR/$tdir/bar
3466         # Really write them
3467         sync
3468
3469         # Total up write_bytes after writing.  We'd better find non-zeros.
3470         for ostnum in $(seq $OSTCOUNT); do
3471                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3472                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3473                         obdfilter/$ostname/stats |
3474                         awk '/^write_bytes/ {print $7}' )
3475                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3476                 if (( ${write_bytes:-0} > 0 ))
3477                 then
3478                         all_zeros=false
3479                         break;
3480                 fi
3481         done
3482
3483         if $all_zeros
3484         then
3485                 for ostnum in $(seq $OSTCOUNT); do
3486                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3487                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3488                         do_facet ost$ostnum lctl get_param -n \
3489                                 obdfilter/$ostname/stats
3490                 done
3491                 error "OST not keeping write_bytes stats (b22312)"
3492         fi
3493 }
3494 run_test 33c "test llobdstat and write_bytes"
3495
3496 test_33d() {
3497         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3499
3500         local MDTIDX=1
3501         local remote_dir=$DIR/$tdir/remote_dir
3502
3503         test_mkdir $DIR/$tdir
3504         $LFS mkdir -i $MDTIDX $remote_dir ||
3505                 error "create remote directory failed"
3506
3507         touch $remote_dir/$tfile
3508         chmod 444 $remote_dir/$tfile
3509         chown $RUNAS_ID $remote_dir/$tfile
3510
3511         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3512
3513         chown $RUNAS_ID $remote_dir
3514         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3515                                         error "create" || true
3516         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3517                                     error "open RDWR" || true
3518         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3519 }
3520 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3521
3522 test_33e() {
3523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3524
3525         mkdir $DIR/$tdir
3526
3527         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3528         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3529         mkdir $DIR/$tdir/local_dir
3530
3531         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3532         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3533         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3534
3535         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3536                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3537
3538         rmdir $DIR/$tdir/* || error "rmdir failed"
3539
3540         umask 777
3541         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3542         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3543         mkdir $DIR/$tdir/local_dir
3544
3545         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3546         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3547         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3548
3549         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3550                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3551
3552         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3553
3554         umask 000
3555         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3556         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3557         mkdir $DIR/$tdir/local_dir
3558
3559         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3560         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3561         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3562
3563         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3564                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3565 }
3566 run_test 33e "mkdir and striped directory should have same mode"
3567
3568 cleanup_33f() {
3569         trap 0
3570         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3571 }
3572
3573 test_33f() {
3574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3575         remote_mds_nodsh && skip "remote MDS with nodsh"
3576
3577         mkdir $DIR/$tdir
3578         chmod go+rwx $DIR/$tdir
3579         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3580         trap cleanup_33f EXIT
3581
3582         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3583                 error "cannot create striped directory"
3584
3585         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3586                 error "cannot create files in striped directory"
3587
3588         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3589                 error "cannot remove files in striped directory"
3590
3591         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3592                 error "cannot remove striped directory"
3593
3594         cleanup_33f
3595 }
3596 run_test 33f "nonroot user can create, access, and remove a striped directory"
3597
3598 test_33g() {
3599         mkdir -p $DIR/$tdir/dir2
3600
3601         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3602         echo $err
3603         [[ $err =~ "exists" ]] || error "Not exists error"
3604 }
3605 run_test 33g "nonroot user create already existing root created file"
3606
3607 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3608 test_34a() {
3609         rm -f $DIR/f34
3610         $MCREATE $DIR/f34 || error "mcreate failed"
3611         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3612                 error "getstripe failed"
3613         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3614         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3615                 error "getstripe failed"
3616         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3617                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3618 }
3619 run_test 34a "truncate file that has not been opened ==========="
3620
3621 test_34b() {
3622         [ ! -f $DIR/f34 ] && test_34a
3623         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3624                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3625         $OPENFILE -f O_RDONLY $DIR/f34
3626         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3627                 error "getstripe failed"
3628         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3629                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3630 }
3631 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3632
3633 test_34c() {
3634         [ ! -f $DIR/f34 ] && test_34a
3635         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3636                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3637         $OPENFILE -f O_RDWR $DIR/f34
3638         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3639                 error "$LFS getstripe failed"
3640         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3641                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3642 }
3643 run_test 34c "O_RDWR opening file-with-size works =============="
3644
3645 test_34d() {
3646         [ ! -f $DIR/f34 ] && test_34a
3647         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3648                 error "dd failed"
3649         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3650                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3651         rm $DIR/f34
3652 }
3653 run_test 34d "write to sparse file ============================="
3654
3655 test_34e() {
3656         rm -f $DIR/f34e
3657         $MCREATE $DIR/f34e || error "mcreate failed"
3658         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3659         $CHECKSTAT -s 1000 $DIR/f34e ||
3660                 error "Size of $DIR/f34e not equal to 1000 bytes"
3661         $OPENFILE -f O_RDWR $DIR/f34e
3662         $CHECKSTAT -s 1000 $DIR/f34e ||
3663                 error "Size of $DIR/f34e not equal to 1000 bytes"
3664 }
3665 run_test 34e "create objects, some with size and some without =="
3666
3667 test_34f() { # bug 6242, 6243
3668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3669
3670         SIZE34F=48000
3671         rm -f $DIR/f34f
3672         $MCREATE $DIR/f34f || error "mcreate failed"
3673         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3674         dd if=$DIR/f34f of=$TMP/f34f
3675         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3676         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3677         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3678         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3679         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3680 }
3681 run_test 34f "read from a file with no objects until EOF ======="
3682
3683 test_34g() {
3684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3685
3686         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3687                 error "dd failed"
3688         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3689         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3690                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3691         cancel_lru_locks osc
3692         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3693                 error "wrong size after lock cancel"
3694
3695         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3696         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3697                 error "expanding truncate failed"
3698         cancel_lru_locks osc
3699         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3700                 error "wrong expanded size after lock cancel"
3701 }
3702 run_test 34g "truncate long file ==============================="
3703
3704 test_34h() {
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local gid=10
3708         local sz=1000
3709
3710         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3711         sync # Flush the cache so that multiop below does not block on cache
3712              # flush when getting the group lock
3713         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3714         MULTIPID=$!
3715
3716         # Since just timed wait is not good enough, let's do a sync write
3717         # that way we are sure enough time for a roundtrip + processing
3718         # passed + 2 seconds of extra margin.
3719         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3720         rm $DIR/${tfile}-1
3721         sleep 2
3722
3723         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3724                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3725                 kill -9 $MULTIPID
3726         fi
3727         wait $MULTIPID
3728         local nsz=`stat -c %s $DIR/$tfile`
3729         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3730 }
3731 run_test 34h "ftruncate file under grouplock should not block"
3732
3733 test_35a() {
3734         cp /bin/sh $DIR/f35a
3735         chmod 444 $DIR/f35a
3736         chown $RUNAS_ID $DIR/f35a
3737         $RUNAS $DIR/f35a && error || true
3738         rm $DIR/f35a
3739 }
3740 run_test 35a "exec file with mode 444 (should return and not leak)"
3741
3742 test_36a() {
3743         rm -f $DIR/f36
3744         utime $DIR/f36 || error "utime failed for MDS"
3745 }
3746 run_test 36a "MDS utime check (mknod, utime)"
3747
3748 test_36b() {
3749         echo "" > $DIR/f36
3750         utime $DIR/f36 || error "utime failed for OST"
3751 }
3752 run_test 36b "OST utime check (open, utime)"
3753
3754 test_36c() {
3755         rm -f $DIR/d36/f36
3756         test_mkdir $DIR/d36
3757         chown $RUNAS_ID $DIR/d36
3758         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3759 }
3760 run_test 36c "non-root MDS utime check (mknod, utime)"
3761
3762 test_36d() {
3763         [ ! -d $DIR/d36 ] && test_36c
3764         echo "" > $DIR/d36/f36
3765         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3766 }
3767 run_test 36d "non-root OST utime check (open, utime)"
3768
3769 test_36e() {
3770         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3771
3772         test_mkdir $DIR/$tdir
3773         touch $DIR/$tdir/$tfile
3774         $RUNAS utime $DIR/$tdir/$tfile &&
3775                 error "utime worked, expected failure" || true
3776 }
3777 run_test 36e "utime on non-owned file (should return error)"
3778
3779 subr_36fh() {
3780         local fl="$1"
3781         local LANG_SAVE=$LANG
3782         local LC_LANG_SAVE=$LC_LANG
3783         export LANG=C LC_LANG=C # for date language
3784
3785         DATESTR="Dec 20  2000"
3786         test_mkdir $DIR/$tdir
3787         lctl set_param fail_loc=$fl
3788         date; date +%s
3789         cp /etc/hosts $DIR/$tdir/$tfile
3790         sync & # write RPC generated with "current" inode timestamp, but delayed
3791         sleep 1
3792         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3793         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3794         cancel_lru_locks $OSC
3795         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3796         date; date +%s
3797         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3798                 echo "BEFORE: $LS_BEFORE" && \
3799                 echo "AFTER : $LS_AFTER" && \
3800                 echo "WANT  : $DATESTR" && \
3801                 error "$DIR/$tdir/$tfile timestamps changed" || true
3802
3803         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3804 }
3805
3806 test_36f() {
3807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3808
3809         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3810         subr_36fh "0x80000214"
3811 }
3812 run_test 36f "utime on file racing with OST BRW write =========="
3813
3814 test_36g() {
3815         remote_ost_nodsh && skip "remote OST with nodsh"
3816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3817         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3818                 skip "Need MDS version at least 2.12.51"
3819
3820         local fmd_max_age
3821         local fmd
3822         local facet="ost1"
3823         local tgt="obdfilter"
3824
3825         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3826
3827         test_mkdir $DIR/$tdir
3828         fmd_max_age=$(do_facet $facet \
3829                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3830                 head -n 1")
3831
3832         echo "FMD max age: ${fmd_max_age}s"
3833         touch $DIR/$tdir/$tfile
3834         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3835                 gawk '{cnt=cnt+$1}  END{print cnt}')
3836         echo "FMD before: $fmd"
3837         [[ $fmd == 0 ]] &&
3838                 error "FMD wasn't create by touch"
3839         sleep $((fmd_max_age + 12))
3840         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3841                 gawk '{cnt=cnt+$1}  END{print cnt}')
3842         echo "FMD after: $fmd"
3843         [[ $fmd == 0 ]] ||
3844                 error "FMD wasn't expired by ping"
3845 }
3846 run_test 36g "FMD cache expiry ====================="
3847
3848 test_36h() {
3849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3850
3851         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3852         subr_36fh "0x80000227"
3853 }
3854 run_test 36h "utime on file racing with OST BRW write =========="
3855
3856 test_36i() {
3857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3858
3859         test_mkdir $DIR/$tdir
3860         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3861
3862         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3863         local new_mtime=$((mtime + 200))
3864
3865         #change Modify time of striped dir
3866         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3867                         error "change mtime failed"
3868
3869         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3870
3871         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3872 }
3873 run_test 36i "change mtime on striped directory"
3874
3875 # test_37 - duplicate with tests 32q 32r
3876
3877 test_38() {
3878         local file=$DIR/$tfile
3879         touch $file
3880         openfile -f O_DIRECTORY $file
3881         local RC=$?
3882         local ENOTDIR=20
3883         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3884         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3885 }
3886 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3887
3888 test_39a() { # was test_39
3889         touch $DIR/$tfile
3890         touch $DIR/${tfile}2
3891 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3892 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3893 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3894         sleep 2
3895         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3896         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3897                 echo "mtime"
3898                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3899                 echo "atime"
3900                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3901                 echo "ctime"
3902                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3903                 error "O_TRUNC didn't change timestamps"
3904         fi
3905 }
3906 run_test 39a "mtime changed on create"
3907
3908 test_39b() {
3909         test_mkdir -c1 $DIR/$tdir
3910         cp -p /etc/passwd $DIR/$tdir/fopen
3911         cp -p /etc/passwd $DIR/$tdir/flink
3912         cp -p /etc/passwd $DIR/$tdir/funlink
3913         cp -p /etc/passwd $DIR/$tdir/frename
3914         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3915
3916         sleep 1
3917         echo "aaaaaa" >> $DIR/$tdir/fopen
3918         echo "aaaaaa" >> $DIR/$tdir/flink
3919         echo "aaaaaa" >> $DIR/$tdir/funlink
3920         echo "aaaaaa" >> $DIR/$tdir/frename
3921
3922         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3923         local link_new=`stat -c %Y $DIR/$tdir/flink`
3924         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3925         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3926
3927         cat $DIR/$tdir/fopen > /dev/null
3928         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3929         rm -f $DIR/$tdir/funlink2
3930         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3931
3932         for (( i=0; i < 2; i++ )) ; do
3933                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3934                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3935                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3936                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3937
3938                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3939                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3940                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3941                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3942
3943                 cancel_lru_locks $OSC
3944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3945         done
3946 }
3947 run_test 39b "mtime change on open, link, unlink, rename  ======"
3948
3949 # this should be set to past
3950 TEST_39_MTIME=`date -d "1 year ago" +%s`
3951
3952 # bug 11063
3953 test_39c() {
3954         touch $DIR1/$tfile
3955         sleep 2
3956         local mtime0=`stat -c %Y $DIR1/$tfile`
3957
3958         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3959         local mtime1=`stat -c %Y $DIR1/$tfile`
3960         [ "$mtime1" = $TEST_39_MTIME ] || \
3961                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3962
3963         local d1=`date +%s`
3964         echo hello >> $DIR1/$tfile
3965         local d2=`date +%s`
3966         local mtime2=`stat -c %Y $DIR1/$tfile`
3967         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3968                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3969
3970         mv $DIR1/$tfile $DIR1/$tfile-1
3971
3972         for (( i=0; i < 2; i++ )) ; do
3973                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3974                 [ "$mtime2" = "$mtime3" ] || \
3975                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3976
3977                 cancel_lru_locks $OSC
3978                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3979         done
3980 }
3981 run_test 39c "mtime change on rename ==========================="
3982
3983 # bug 21114
3984 test_39d() {
3985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3986
3987         touch $DIR1/$tfile
3988         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3989
3990         for (( i=0; i < 2; i++ )) ; do
3991                 local mtime=`stat -c %Y $DIR1/$tfile`
3992                 [ $mtime = $TEST_39_MTIME ] || \
3993                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3994
3995                 cancel_lru_locks $OSC
3996                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3997         done
3998 }
3999 run_test 39d "create, utime, stat =============================="
4000
4001 # bug 21114
4002 test_39e() {
4003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4004
4005         touch $DIR1/$tfile
4006         local mtime1=`stat -c %Y $DIR1/$tfile`
4007
4008         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4009
4010         for (( i=0; i < 2; i++ )) ; do
4011                 local mtime2=`stat -c %Y $DIR1/$tfile`
4012                 [ $mtime2 = $TEST_39_MTIME ] || \
4013                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4014
4015                 cancel_lru_locks $OSC
4016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4017         done
4018 }
4019 run_test 39e "create, stat, utime, stat ========================"
4020
4021 # bug 21114
4022 test_39f() {
4023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4024
4025         touch $DIR1/$tfile
4026         mtime1=`stat -c %Y $DIR1/$tfile`
4027
4028         sleep 2
4029         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4030
4031         for (( i=0; i < 2; i++ )) ; do
4032                 local mtime2=`stat -c %Y $DIR1/$tfile`
4033                 [ $mtime2 = $TEST_39_MTIME ] || \
4034                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4035
4036                 cancel_lru_locks $OSC
4037                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4038         done
4039 }
4040 run_test 39f "create, stat, sleep, utime, stat ================="
4041
4042 # bug 11063
4043 test_39g() {
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         echo hello >> $DIR1/$tfile
4047         local mtime1=`stat -c %Y $DIR1/$tfile`
4048
4049         sleep 2
4050         chmod o+r $DIR1/$tfile
4051
4052         for (( i=0; i < 2; i++ )) ; do
4053                 local mtime2=`stat -c %Y $DIR1/$tfile`
4054                 [ "$mtime1" = "$mtime2" ] || \
4055                         error "lost mtime: $mtime2, should be $mtime1"
4056
4057                 cancel_lru_locks $OSC
4058                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4059         done
4060 }
4061 run_test 39g "write, chmod, stat ==============================="
4062
4063 # bug 11063
4064 test_39h() {
4065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4066
4067         touch $DIR1/$tfile
4068         sleep 1
4069
4070         local d1=`date`
4071         echo hello >> $DIR1/$tfile
4072         local mtime1=`stat -c %Y $DIR1/$tfile`
4073
4074         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4075         local d2=`date`
4076         if [ "$d1" != "$d2" ]; then
4077                 echo "write and touch not within one second"
4078         else
4079                 for (( i=0; i < 2; i++ )) ; do
4080                         local mtime2=`stat -c %Y $DIR1/$tfile`
4081                         [ "$mtime2" = $TEST_39_MTIME ] || \
4082                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4083
4084                         cancel_lru_locks $OSC
4085                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4086                 done
4087         fi
4088 }
4089 run_test 39h "write, utime within one second, stat ============="
4090
4091 test_39i() {
4092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4093
4094         touch $DIR1/$tfile
4095         sleep 1
4096
4097         echo hello >> $DIR1/$tfile
4098         local mtime1=`stat -c %Y $DIR1/$tfile`
4099
4100         mv $DIR1/$tfile $DIR1/$tfile-1
4101
4102         for (( i=0; i < 2; i++ )) ; do
4103                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4104
4105                 [ "$mtime1" = "$mtime2" ] || \
4106                         error "lost mtime: $mtime2, should be $mtime1"
4107
4108                 cancel_lru_locks $OSC
4109                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4110         done
4111 }
4112 run_test 39i "write, rename, stat =============================="
4113
4114 test_39j() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         start_full_debug_logging
4118         touch $DIR1/$tfile
4119         sleep 1
4120
4121         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4122         lctl set_param fail_loc=0x80000412
4123         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4124                 error "multiop failed"
4125         local multipid=$!
4126         local mtime1=`stat -c %Y $DIR1/$tfile`
4127
4128         mv $DIR1/$tfile $DIR1/$tfile-1
4129
4130         kill -USR1 $multipid
4131         wait $multipid || error "multiop close failed"
4132
4133         for (( i=0; i < 2; i++ )) ; do
4134                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4135                 [ "$mtime1" = "$mtime2" ] ||
4136                         error "mtime is lost on close: $mtime2, " \
4137                               "should be $mtime1"
4138
4139                 cancel_lru_locks $OSC
4140                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4141         done
4142         lctl set_param fail_loc=0
4143         stop_full_debug_logging
4144 }
4145 run_test 39j "write, rename, close, stat ======================="
4146
4147 test_39k() {
4148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4149
4150         touch $DIR1/$tfile
4151         sleep 1
4152
4153         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4154         local multipid=$!
4155         local mtime1=`stat -c %Y $DIR1/$tfile`
4156
4157         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4158
4159         kill -USR1 $multipid
4160         wait $multipid || error "multiop close failed"
4161
4162         for (( i=0; i < 2; i++ )) ; do
4163                 local mtime2=`stat -c %Y $DIR1/$tfile`
4164
4165                 [ "$mtime2" = $TEST_39_MTIME ] || \
4166                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4167
4168                 cancel_lru_locks osc
4169                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4170         done
4171 }
4172 run_test 39k "write, utime, close, stat ========================"
4173
4174 # this should be set to future
4175 TEST_39_ATIME=`date -d "1 year" +%s`
4176
4177 test_39l() {
4178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4179         remote_mds_nodsh && skip "remote MDS with nodsh"
4180
4181         local atime_diff=$(do_facet $SINGLEMDS \
4182                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4183         rm -rf $DIR/$tdir
4184         mkdir -p $DIR/$tdir
4185
4186         # test setting directory atime to future
4187         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4188         local atime=$(stat -c %X $DIR/$tdir)
4189         [ "$atime" = $TEST_39_ATIME ] ||
4190                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4191
4192         # test setting directory atime from future to now
4193         local now=$(date +%s)
4194         touch -a -d @$now $DIR/$tdir
4195
4196         atime=$(stat -c %X $DIR/$tdir)
4197         [ "$atime" -eq "$now"  ] ||
4198                 error "atime is not updated from future: $atime, $now"
4199
4200         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4201         sleep 3
4202
4203         # test setting directory atime when now > dir atime + atime_diff
4204         local d1=$(date +%s)
4205         ls $DIR/$tdir
4206         local d2=$(date +%s)
4207         cancel_lru_locks mdc
4208         atime=$(stat -c %X $DIR/$tdir)
4209         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4210                 error "atime is not updated  : $atime, should be $d2"
4211
4212         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4213         sleep 3
4214
4215         # test not setting directory atime when now < dir atime + atime_diff
4216         ls $DIR/$tdir
4217         cancel_lru_locks mdc
4218         atime=$(stat -c %X $DIR/$tdir)
4219         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4220                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4221
4222         do_facet $SINGLEMDS \
4223                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4224 }
4225 run_test 39l "directory atime update ==========================="
4226
4227 test_39m() {
4228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4229
4230         touch $DIR1/$tfile
4231         sleep 2
4232         local far_past_mtime=$(date -d "May 29 1953" +%s)
4233         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4234
4235         touch -m -d @$far_past_mtime $DIR1/$tfile
4236         touch -a -d @$far_past_atime $DIR1/$tfile
4237
4238         for (( i=0; i < 2; i++ )) ; do
4239                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4240                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4241                         error "atime or mtime set incorrectly"
4242
4243                 cancel_lru_locks $OSC
4244                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4245         done
4246 }
4247 run_test 39m "test atime and mtime before 1970"
4248
4249 test_39n() { # LU-3832
4250         remote_mds_nodsh && skip "remote MDS with nodsh"
4251
4252         local atime_diff=$(do_facet $SINGLEMDS \
4253                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4254         local atime0
4255         local atime1
4256         local atime2
4257
4258         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4259
4260         rm -rf $DIR/$tfile
4261         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4262         atime0=$(stat -c %X $DIR/$tfile)
4263
4264         sleep 5
4265         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4266         atime1=$(stat -c %X $DIR/$tfile)
4267
4268         sleep 5
4269         cancel_lru_locks mdc
4270         cancel_lru_locks osc
4271         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4272         atime2=$(stat -c %X $DIR/$tfile)
4273
4274         do_facet $SINGLEMDS \
4275                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4276
4277         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4278         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4279 }
4280 run_test 39n "check that O_NOATIME is honored"
4281
4282 test_39o() {
4283         TESTDIR=$DIR/$tdir/$tfile
4284         [ -e $TESTDIR ] && rm -rf $TESTDIR
4285         mkdir -p $TESTDIR
4286         cd $TESTDIR
4287         links1=2
4288         ls
4289         mkdir a b
4290         ls
4291         links2=$(stat -c %h .)
4292         [ $(($links1 + 2)) != $links2 ] &&
4293                 error "wrong links count $(($links1 + 2)) != $links2"
4294         rmdir b
4295         links3=$(stat -c %h .)
4296         [ $(($links1 + 1)) != $links3 ] &&
4297                 error "wrong links count $links1 != $links3"
4298         return 0
4299 }
4300 run_test 39o "directory cached attributes updated after create"
4301
4302 test_39p() {
4303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4304
4305         local MDTIDX=1
4306         TESTDIR=$DIR/$tdir/$tdir
4307         [ -e $TESTDIR ] && rm -rf $TESTDIR
4308         test_mkdir -p $TESTDIR
4309         cd $TESTDIR
4310         links1=2
4311         ls
4312         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4313         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4314         ls
4315         links2=$(stat -c %h .)
4316         [ $(($links1 + 2)) != $links2 ] &&
4317                 error "wrong links count $(($links1 + 2)) != $links2"
4318         rmdir remote_dir2
4319         links3=$(stat -c %h .)
4320         [ $(($links1 + 1)) != $links3 ] &&
4321                 error "wrong links count $links1 != $links3"
4322         return 0
4323 }
4324 run_test 39p "remote directory cached attributes updated after create ========"
4325
4326
4327 test_39q() { # LU-8041
4328         local testdir=$DIR/$tdir
4329         mkdir -p $testdir
4330         multiop_bg_pause $testdir D_c || error "multiop failed"
4331         local multipid=$!
4332         cancel_lru_locks mdc
4333         kill -USR1 $multipid
4334         local atime=$(stat -c %X $testdir)
4335         [ "$atime" -ne 0 ] || error "atime is zero"
4336 }
4337 run_test 39q "close won't zero out atime"
4338
4339 test_40() {
4340         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4341         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4342                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4343         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4344                 error "$tfile is not 4096 bytes in size"
4345 }
4346 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4347
4348 test_41() {
4349         # bug 1553
4350         small_write $DIR/f41 18
4351 }
4352 run_test 41 "test small file write + fstat ====================="
4353
4354 count_ost_writes() {
4355         lctl get_param -n ${OSC}.*.stats |
4356                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4357                         END { printf("%0.0f", writes) }'
4358 }
4359
4360 # decent default
4361 WRITEBACK_SAVE=500
4362 DIRTY_RATIO_SAVE=40
4363 MAX_DIRTY_RATIO=50
4364 BG_DIRTY_RATIO_SAVE=10
4365 MAX_BG_DIRTY_RATIO=25
4366
4367 start_writeback() {
4368         trap 0
4369         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4370         # dirty_ratio, dirty_background_ratio
4371         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4372                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4373                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4374                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4375         else
4376                 # if file not here, we are a 2.4 kernel
4377                 kill -CONT `pidof kupdated`
4378         fi
4379 }
4380
4381 stop_writeback() {
4382         # setup the trap first, so someone cannot exit the test at the
4383         # exact wrong time and mess up a machine
4384         trap start_writeback EXIT
4385         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4386         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4387                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4388                 sysctl -w vm.dirty_writeback_centisecs=0
4389                 sysctl -w vm.dirty_writeback_centisecs=0
4390                 # save and increase /proc/sys/vm/dirty_ratio
4391                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4392                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4393                 # save and increase /proc/sys/vm/dirty_background_ratio
4394                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4395                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4396         else
4397                 # if file not here, we are a 2.4 kernel
4398                 kill -STOP `pidof kupdated`
4399         fi
4400 }
4401
4402 # ensure that all stripes have some grant before we test client-side cache
4403 setup_test42() {
4404         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4405                 dd if=/dev/zero of=$i bs=4k count=1
4406                 rm $i
4407         done
4408 }
4409
4410 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4411 # file truncation, and file removal.
4412 test_42a() {
4413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4414
4415         setup_test42
4416         cancel_lru_locks $OSC
4417         stop_writeback
4418         sync; sleep 1; sync # just to be safe
4419         BEFOREWRITES=`count_ost_writes`
4420         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4421         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4422         AFTERWRITES=`count_ost_writes`
4423         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4424                 error "$BEFOREWRITES < $AFTERWRITES"
4425         start_writeback
4426 }
4427 run_test 42a "ensure that we don't flush on close"
4428
4429 test_42b() {
4430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4431
4432         setup_test42
4433         cancel_lru_locks $OSC
4434         stop_writeback
4435         sync
4436         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4437         BEFOREWRITES=$(count_ost_writes)
4438         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4439         AFTERWRITES=$(count_ost_writes)
4440         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4441                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4442         fi
4443         BEFOREWRITES=$(count_ost_writes)
4444         sync || error "sync: $?"
4445         AFTERWRITES=$(count_ost_writes)
4446         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4447                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4448         fi
4449         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4450         start_writeback
4451         return 0
4452 }
4453 run_test 42b "test destroy of file with cached dirty data ======"
4454
4455 # if these tests just want to test the effect of truncation,
4456 # they have to be very careful.  consider:
4457 # - the first open gets a {0,EOF}PR lock
4458 # - the first write conflicts and gets a {0, count-1}PW
4459 # - the rest of the writes are under {count,EOF}PW
4460 # - the open for truncate tries to match a {0,EOF}PR
4461 #   for the filesize and cancels the PWs.
4462 # any number of fixes (don't get {0,EOF} on open, match
4463 # composite locks, do smarter file size management) fix
4464 # this, but for now we want these tests to verify that
4465 # the cancellation with truncate intent works, so we
4466 # start the file with a full-file pw lock to match against
4467 # until the truncate.
4468 trunc_test() {
4469         test=$1
4470         file=$DIR/$test
4471         offset=$2
4472         cancel_lru_locks $OSC
4473         stop_writeback
4474         # prime the file with 0,EOF PW to match
4475         touch $file
4476         $TRUNCATE $file 0
4477         sync; sync
4478         # now the real test..
4479         dd if=/dev/zero of=$file bs=1024 count=100
4480         BEFOREWRITES=`count_ost_writes`
4481         $TRUNCATE $file $offset
4482         cancel_lru_locks $OSC
4483         AFTERWRITES=`count_ost_writes`
4484         start_writeback
4485 }
4486
4487 test_42c() {
4488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4489
4490         trunc_test 42c 1024
4491         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4492                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4493         rm $file
4494 }
4495 run_test 42c "test partial truncate of file with cached dirty data"
4496
4497 test_42d() {
4498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4499
4500         trunc_test 42d 0
4501         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4502                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4503         rm $file
4504 }
4505 run_test 42d "test complete truncate of file with cached dirty data"
4506
4507 test_42e() { # bug22074
4508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4509
4510         local TDIR=$DIR/${tdir}e
4511         local pages=16 # hardcoded 16 pages, don't change it.
4512         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4513         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4514         local max_dirty_mb
4515         local warmup_files
4516
4517         test_mkdir $DIR/${tdir}e
4518         $LFS setstripe -c 1 $TDIR
4519         createmany -o $TDIR/f $files
4520
4521         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4522
4523         # we assume that with $OSTCOUNT files, at least one of them will
4524         # be allocated on OST0.
4525         warmup_files=$((OSTCOUNT * max_dirty_mb))
4526         createmany -o $TDIR/w $warmup_files
4527
4528         # write a large amount of data into one file and sync, to get good
4529         # avail_grant number from OST.
4530         for ((i=0; i<$warmup_files; i++)); do
4531                 idx=$($LFS getstripe -i $TDIR/w$i)
4532                 [ $idx -ne 0 ] && continue
4533                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4534                 break
4535         done
4536         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4537         sync
4538         $LCTL get_param $proc_osc0/cur_dirty_bytes
4539         $LCTL get_param $proc_osc0/cur_grant_bytes
4540
4541         # create as much dirty pages as we can while not to trigger the actual
4542         # RPCs directly. but depends on the env, VFS may trigger flush during this
4543         # period, hopefully we are good.
4544         for ((i=0; i<$warmup_files; i++)); do
4545                 idx=$($LFS getstripe -i $TDIR/w$i)
4546                 [ $idx -ne 0 ] && continue
4547                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4548         done
4549         $LCTL get_param $proc_osc0/cur_dirty_bytes
4550         $LCTL get_param $proc_osc0/cur_grant_bytes
4551
4552         # perform the real test
4553         $LCTL set_param $proc_osc0/rpc_stats 0
4554         for ((;i<$files; i++)); do
4555                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4556                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4557         done
4558         sync
4559         $LCTL get_param $proc_osc0/rpc_stats
4560
4561         local percent=0
4562         local have_ppr=false
4563         $LCTL get_param $proc_osc0/rpc_stats |
4564                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4565                         # skip lines until we are at the RPC histogram data
4566                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4567                         $have_ppr || continue
4568
4569                         # we only want the percent stat for < 16 pages
4570                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4571
4572                         percent=$((percent + WPCT))
4573                         if [[ $percent -gt 15 ]]; then
4574                                 error "less than 16-pages write RPCs" \
4575                                       "$percent% > 15%"
4576                                 break
4577                         fi
4578                 done
4579         rm -rf $TDIR
4580 }
4581 run_test 42e "verify sub-RPC writes are not done synchronously"
4582
4583 test_43A() { # was test_43
4584         test_mkdir $DIR/$tdir
4585         cp -p /bin/ls $DIR/$tdir/$tfile
4586         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4587         pid=$!
4588         # give multiop a chance to open
4589         sleep 1
4590
4591         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4592         kill -USR1 $pid
4593 }
4594 run_test 43A "execution of file opened for write should return -ETXTBSY"
4595
4596 test_43a() {
4597         test_mkdir $DIR/$tdir
4598         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4599         $DIR/$tdir/sleep 60 &
4600         SLEEP_PID=$!
4601         # Make sure exec of $tdir/sleep wins race with truncate
4602         sleep 1
4603         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4604         kill $SLEEP_PID
4605 }
4606 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4607
4608 test_43b() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         test_mkdir $DIR/$tdir
4612         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4613         $DIR/$tdir/sleep 60 &
4614         SLEEP_PID=$!
4615         # Make sure exec of $tdir/sleep wins race with truncate
4616         sleep 1
4617         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4618         kill $SLEEP_PID
4619 }
4620 run_test 43b "truncate of file being executed should return -ETXTBSY"
4621
4622 test_43c() {
4623         local testdir="$DIR/$tdir"
4624         test_mkdir $testdir
4625         cp $SHELL $testdir/
4626         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4627                 ( cd $testdir && md5sum -c )
4628 }
4629 run_test 43c "md5sum of copy into lustre"
4630
4631 test_44A() { # was test_44
4632         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4633
4634         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4635         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4636 }
4637 run_test 44A "zero length read from a sparse stripe"
4638
4639 test_44a() {
4640         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4641                 awk '{ print $2 }')
4642         [ -z "$nstripe" ] && skip "can't get stripe info"
4643         [[ $nstripe -gt $OSTCOUNT ]] &&
4644                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4645
4646         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4647                 awk '{ print $2 }')
4648         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4649                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4650                         awk '{ print $2 }')
4651         fi
4652
4653         OFFSETS="0 $((stride/2)) $((stride-1))"
4654         for offset in $OFFSETS; do
4655                 for i in $(seq 0 $((nstripe-1))); do
4656                         local GLOBALOFFSETS=""
4657                         # size in Bytes
4658                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4659                         local myfn=$DIR/d44a-$size
4660                         echo "--------writing $myfn at $size"
4661                         ll_sparseness_write $myfn $size ||
4662                                 error "ll_sparseness_write"
4663                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4664                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4665                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4666
4667                         for j in $(seq 0 $((nstripe-1))); do
4668                                 # size in Bytes
4669                                 size=$((((j + $nstripe )*$stride + $offset)))
4670                                 ll_sparseness_write $myfn $size ||
4671                                         error "ll_sparseness_write"
4672                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4673                         done
4674                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4675                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4676                         rm -f $myfn
4677                 done
4678         done
4679 }
4680 run_test 44a "test sparse pwrite ==============================="
4681
4682 dirty_osc_total() {
4683         tot=0
4684         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4685                 tot=$(($tot + $d))
4686         done
4687         echo $tot
4688 }
4689 do_dirty_record() {
4690         before=`dirty_osc_total`
4691         echo executing "\"$*\""
4692         eval $*
4693         after=`dirty_osc_total`
4694         echo before $before, after $after
4695 }
4696 test_45() {
4697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4698
4699         f="$DIR/f45"
4700         # Obtain grants from OST if it supports it
4701         echo blah > ${f}_grant
4702         stop_writeback
4703         sync
4704         do_dirty_record "echo blah > $f"
4705         [[ $before -eq $after ]] && error "write wasn't cached"
4706         do_dirty_record "> $f"
4707         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4708         do_dirty_record "echo blah > $f"
4709         [[ $before -eq $after ]] && error "write wasn't cached"
4710         do_dirty_record "sync"
4711         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4712         do_dirty_record "echo blah > $f"
4713         [[ $before -eq $after ]] && error "write wasn't cached"
4714         do_dirty_record "cancel_lru_locks osc"
4715         [[ $before -gt $after ]] ||
4716                 error "lock cancellation didn't lower dirty count"
4717         start_writeback
4718 }
4719 run_test 45 "osc io page accounting ============================"
4720
4721 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4722 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4723 # objects offset and an assert hit when an rpc was built with 1023's mapped
4724 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4725 test_46() {
4726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4727
4728         f="$DIR/f46"
4729         stop_writeback
4730         sync
4731         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4732         sync
4733         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4734         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4735         sync
4736         start_writeback
4737 }
4738 run_test 46 "dirtying a previously written page ================"
4739
4740 # test_47 is removed "Device nodes check" is moved to test_28
4741
4742 test_48a() { # bug 2399
4743         [ "$mds1_FSTYPE" = "zfs" ] &&
4744         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4745                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4746
4747         test_mkdir $DIR/$tdir
4748         cd $DIR/$tdir
4749         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4750         test_mkdir $DIR/$tdir
4751         touch foo || error "'touch foo' failed after recreating cwd"
4752         test_mkdir bar
4753         touch .foo || error "'touch .foo' failed after recreating cwd"
4754         test_mkdir .bar
4755         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4756         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4757         cd . || error "'cd .' failed after recreating cwd"
4758         mkdir . && error "'mkdir .' worked after recreating cwd"
4759         rmdir . && error "'rmdir .' worked after recreating cwd"
4760         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4761         cd .. || error "'cd ..' failed after recreating cwd"
4762 }
4763 run_test 48a "Access renamed working dir (should return errors)="
4764
4765 test_48b() { # bug 2399
4766         rm -rf $DIR/$tdir
4767         test_mkdir $DIR/$tdir
4768         cd $DIR/$tdir
4769         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4770         touch foo && error "'touch foo' worked after removing cwd"
4771         mkdir foo && error "'mkdir foo' worked after removing cwd"
4772         touch .foo && error "'touch .foo' worked after removing cwd"
4773         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4774         ls . > /dev/null && error "'ls .' worked after removing cwd"
4775         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4776         mkdir . && error "'mkdir .' worked after removing cwd"
4777         rmdir . && error "'rmdir .' worked after removing cwd"
4778         ln -s . foo && error "'ln -s .' worked after removing cwd"
4779         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4780 }
4781 run_test 48b "Access removed working dir (should return errors)="
4782
4783 test_48c() { # bug 2350
4784         #lctl set_param debug=-1
4785         #set -vx
4786         rm -rf $DIR/$tdir
4787         test_mkdir -p $DIR/$tdir/dir
4788         cd $DIR/$tdir/dir
4789         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4790         $TRACE touch foo && error "touch foo worked after removing cwd"
4791         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4792         touch .foo && error "touch .foo worked after removing cwd"
4793         mkdir .foo && error "mkdir .foo worked after removing cwd"
4794         $TRACE ls . && error "'ls .' worked after removing cwd"
4795         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4796         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4797         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4798         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4799         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4800 }
4801 run_test 48c "Access removed working subdir (should return errors)"
4802
4803 test_48d() { # bug 2350
4804         #lctl set_param debug=-1
4805         #set -vx
4806         rm -rf $DIR/$tdir
4807         test_mkdir -p $DIR/$tdir/dir
4808         cd $DIR/$tdir/dir
4809         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4810         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4811         $TRACE touch foo && error "'touch foo' worked after removing parent"
4812         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4813         touch .foo && error "'touch .foo' worked after removing parent"
4814         mkdir .foo && error "mkdir .foo worked after removing parent"
4815         $TRACE ls . && error "'ls .' worked after removing parent"
4816         $TRACE ls .. && error "'ls ..' worked after removing parent"
4817         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4818         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4819         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4820         true
4821 }
4822 run_test 48d "Access removed parent subdir (should return errors)"
4823
4824 test_48e() { # bug 4134
4825         #lctl set_param debug=-1
4826         #set -vx
4827         rm -rf $DIR/$tdir
4828         test_mkdir -p $DIR/$tdir/dir
4829         cd $DIR/$tdir/dir
4830         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4831         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4832         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4833         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4834         # On a buggy kernel addition of "touch foo" after cd .. will
4835         # produce kernel oops in lookup_hash_it
4836         touch ../foo && error "'cd ..' worked after recreate parent"
4837         cd $DIR
4838         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4839 }
4840 run_test 48e "Access to recreated parent subdir (should return errors)"
4841
4842 test_49() { # LU-1030
4843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4844         remote_ost_nodsh && skip "remote OST with nodsh"
4845
4846         # get ost1 size - lustre-OST0000
4847         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4848                 awk '{ print $4 }')
4849         # write 800M at maximum
4850         [[ $ost1_size -lt 2 ]] && ost1_size=2
4851         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4852
4853         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4854         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4855         local dd_pid=$!
4856
4857         # change max_pages_per_rpc while writing the file
4858         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4859         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4860         # loop until dd process exits
4861         while ps ax -opid | grep -wq $dd_pid; do
4862                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4863                 sleep $((RANDOM % 5 + 1))
4864         done
4865         # restore original max_pages_per_rpc
4866         $LCTL set_param $osc1_mppc=$orig_mppc
4867         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4868 }
4869 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4870
4871 test_50() {
4872         # bug 1485
4873         test_mkdir $DIR/$tdir
4874         cd $DIR/$tdir
4875         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4876 }
4877 run_test 50 "special situations: /proc symlinks  ==============="
4878
4879 test_51a() {    # was test_51
4880         # bug 1516 - create an empty entry right after ".." then split dir
4881         test_mkdir -c1 $DIR/$tdir
4882         touch $DIR/$tdir/foo
4883         $MCREATE $DIR/$tdir/bar
4884         rm $DIR/$tdir/foo
4885         createmany -m $DIR/$tdir/longfile 201
4886         FNUM=202
4887         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4888                 $MCREATE $DIR/$tdir/longfile$FNUM
4889                 FNUM=$(($FNUM + 1))
4890                 echo -n "+"
4891         done
4892         echo
4893         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4894 }
4895 run_test 51a "special situations: split htree with empty entry =="
4896
4897 cleanup_print_lfs_df () {
4898         trap 0
4899         $LFS df
4900         $LFS df -i
4901 }
4902
4903 test_51b() {
4904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4905
4906         local dir=$DIR/$tdir
4907         local nrdirs=$((65536 + 100))
4908
4909         # cleanup the directory
4910         rm -fr $dir
4911
4912         test_mkdir -c1 $dir
4913
4914         $LFS df
4915         $LFS df -i
4916         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4917         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4918         [[ $numfree -lt $nrdirs ]] &&
4919                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4920
4921         # need to check free space for the directories as well
4922         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4923         numfree=$(( blkfree / $(fs_inode_ksize) ))
4924         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4925
4926         trap cleanup_print_lfs_df EXIT
4927
4928         # create files
4929         createmany -d $dir/d $nrdirs || {
4930                 unlinkmany $dir/d $nrdirs
4931                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4932         }
4933
4934         # really created :
4935         nrdirs=$(ls -U $dir | wc -l)
4936
4937         # unlink all but 100 subdirectories, then check it still works
4938         local left=100
4939         local delete=$((nrdirs - left))
4940
4941         $LFS df
4942         $LFS df -i
4943
4944         # for ldiskfs the nlink count should be 1, but this is OSD specific
4945         # and so this is listed for informational purposes only
4946         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4947         unlinkmany -d $dir/d $delete ||
4948                 error "unlink of first $delete subdirs failed"
4949
4950         echo "nlink between: $(stat -c %h $dir)"
4951         local found=$(ls -U $dir | wc -l)
4952         [ $found -ne $left ] &&
4953                 error "can't find subdirs: found only $found, expected $left"
4954
4955         unlinkmany -d $dir/d $delete $left ||
4956                 error "unlink of second $left subdirs failed"
4957         # regardless of whether the backing filesystem tracks nlink accurately
4958         # or not, the nlink count shouldn't be more than "." and ".." here
4959         local after=$(stat -c %h $dir)
4960         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4961                 echo "nlink after: $after"
4962
4963         cleanup_print_lfs_df
4964 }
4965 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4966
4967 test_51d() {
4968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4969         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4970
4971         test_mkdir $DIR/$tdir
4972         createmany -o $DIR/$tdir/t- 1000
4973         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4974         for N in $(seq 0 $((OSTCOUNT - 1))); do
4975                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4976                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4977                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4978                         '($1 == '$N') { objs += 1 } \
4979                         END { printf("%0.0f", objs) }')
4980                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4981         done
4982         unlinkmany $DIR/$tdir/t- 1000
4983
4984         NLAST=0
4985         for N in $(seq 1 $((OSTCOUNT - 1))); do
4986                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4987                         error "OST $N has less objects vs OST $NLAST" \
4988                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4989                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4990                         error "OST $N has less objects vs OST $NLAST" \
4991                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4992
4993                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4994                         error "OST $N has less #0 objects vs OST $NLAST" \
4995                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4996                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4997                         error "OST $N has less #0 objects vs OST $NLAST" \
4998                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4999                 NLAST=$N
5000         done
5001         rm -f $TMP/$tfile
5002 }
5003 run_test 51d "check object distribution"
5004
5005 test_51e() {
5006         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5007                 skip_env "ldiskfs only test"
5008         fi
5009
5010         test_mkdir -c1 $DIR/$tdir
5011         test_mkdir -c1 $DIR/$tdir/d0
5012
5013         touch $DIR/$tdir/d0/foo
5014         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5015                 error "file exceed 65000 nlink limit!"
5016         unlinkmany $DIR/$tdir/d0/f- 65001
5017         return 0
5018 }
5019 run_test 51e "check file nlink limit"
5020
5021 test_51f() {
5022         test_mkdir $DIR/$tdir
5023
5024         local max=100000
5025         local ulimit_old=$(ulimit -n)
5026         local spare=20 # number of spare fd's for scripts/libraries, etc.
5027         local mdt=$($LFS getstripe -m $DIR/$tdir)
5028         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5029
5030         echo "MDT$mdt numfree=$numfree, max=$max"
5031         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5032         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5033                 while ! ulimit -n $((numfree + spare)); do
5034                         numfree=$((numfree * 3 / 4))
5035                 done
5036                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5037         else
5038                 echo "left ulimit at $ulimit_old"
5039         fi
5040
5041         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5042                 unlinkmany $DIR/$tdir/f $numfree
5043                 error "create+open $numfree files in $DIR/$tdir failed"
5044         }
5045         ulimit -n $ulimit_old
5046
5047         # if createmany exits at 120s there will be fewer than $numfree files
5048         unlinkmany $DIR/$tdir/f $numfree || true
5049 }
5050 run_test 51f "check many open files limit"
5051
5052 test_52a() {
5053         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5054         test_mkdir $DIR/$tdir
5055         touch $DIR/$tdir/foo
5056         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5057         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5058         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5059         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5060         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5061                                         error "link worked"
5062         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5063         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5064         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5065                                                      error "lsattr"
5066         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5067         cp -r $DIR/$tdir $TMP/
5068         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5069 }
5070 run_test 52a "append-only flag test (should return errors)"
5071
5072 test_52b() {
5073         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5074         test_mkdir $DIR/$tdir
5075         touch $DIR/$tdir/foo
5076         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5077         cat test > $DIR/$tdir/foo && error "cat test worked"
5078         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5079         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5080         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5081                                         error "link worked"
5082         echo foo >> $DIR/$tdir/foo && error "echo worked"
5083         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5084         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5085         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5086         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5087                                                         error "lsattr"
5088         chattr -i $DIR/$tdir/foo || error "chattr failed"
5089
5090         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5091 }
5092 run_test 52b "immutable flag test (should return errors) ======="
5093
5094 test_53() {
5095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5096         remote_mds_nodsh && skip "remote MDS with nodsh"
5097         remote_ost_nodsh && skip "remote OST with nodsh"
5098
5099         local param
5100         local param_seq
5101         local ostname
5102         local mds_last
5103         local mds_last_seq
5104         local ost_last
5105         local ost_last_seq
5106         local ost_last_id
5107         local ostnum
5108         local node
5109         local found=false
5110         local support_last_seq=true
5111
5112         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5113                 support_last_seq=false
5114
5115         # only test MDT0000
5116         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5117         local value
5118         for value in $(do_facet $SINGLEMDS \
5119                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
5120                 param=$(echo ${value[0]} | cut -d "=" -f1)
5121                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5122
5123                 if $support_last_seq; then
5124                         param_seq=$(echo $param |
5125                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5126                         mds_last_seq=$(do_facet $SINGLEMDS \
5127                                        $LCTL get_param -n $param_seq)
5128                 fi
5129                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5130
5131                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5132                 node=$(facet_active_host ost$((ostnum+1)))
5133                 param="obdfilter.$ostname.last_id"
5134                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5135                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5136                         ost_last_id=$ost_last
5137
5138                         if $support_last_seq; then
5139                                 ost_last_id=$(echo $ost_last |
5140                                               awk -F':' '{print $2}' |
5141                                               sed -e "s/^0x//g")
5142                                 ost_last_seq=$(echo $ost_last |
5143                                                awk -F':' '{print $1}')
5144                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5145                         fi
5146
5147                         if [[ $ost_last_id != $mds_last ]]; then
5148                                 error "$ost_last_id != $mds_last"
5149                         else
5150                                 found=true
5151                                 break
5152                         fi
5153                 done
5154         done
5155         $found || error "can not match last_seq/last_id for $mdtosc"
5156         return 0
5157 }
5158 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5159
5160 test_54a() {
5161         perl -MSocket -e ';' || skip "no Socket perl module installed"
5162
5163         $SOCKETSERVER $DIR/socket ||
5164                 error "$SOCKETSERVER $DIR/socket failed: $?"
5165         $SOCKETCLIENT $DIR/socket ||
5166                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5167         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5168 }
5169 run_test 54a "unix domain socket test =========================="
5170
5171 test_54b() {
5172         f="$DIR/f54b"
5173         mknod $f c 1 3
5174         chmod 0666 $f
5175         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5176 }
5177 run_test 54b "char device works in lustre ======================"
5178
5179 find_loop_dev() {
5180         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5181         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5182         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5183
5184         for i in $(seq 3 7); do
5185                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5186                 LOOPDEV=$LOOPBASE$i
5187                 LOOPNUM=$i
5188                 break
5189         done
5190 }
5191
5192 cleanup_54c() {
5193         local rc=0
5194         loopdev="$DIR/loop54c"
5195
5196         trap 0
5197         $UMOUNT $DIR/$tdir || rc=$?
5198         losetup -d $loopdev || true
5199         losetup -d $LOOPDEV || true
5200         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5201         return $rc
5202 }
5203
5204 test_54c() {
5205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5206
5207         loopdev="$DIR/loop54c"
5208
5209         find_loop_dev
5210         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5211         trap cleanup_54c EXIT
5212         mknod $loopdev b 7 $LOOPNUM
5213         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5214         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5215         losetup $loopdev $DIR/$tfile ||
5216                 error "can't set up $loopdev for $DIR/$tfile"
5217         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5218         test_mkdir $DIR/$tdir
5219         mount -t ext2 $loopdev $DIR/$tdir ||
5220                 error "error mounting $loopdev on $DIR/$tdir"
5221         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5222                 error "dd write"
5223         df $DIR/$tdir
5224         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5225                 error "dd read"
5226         cleanup_54c
5227 }
5228 run_test 54c "block device works in lustre ====================="
5229
5230 test_54d() {
5231         f="$DIR/f54d"
5232         string="aaaaaa"
5233         mknod $f p
5234         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5235 }
5236 run_test 54d "fifo device works in lustre ======================"
5237
5238 test_54e() {
5239         f="$DIR/f54e"
5240         string="aaaaaa"
5241         cp -aL /dev/console $f
5242         echo $string > $f || error "echo $string to $f failed"
5243 }
5244 run_test 54e "console/tty device works in lustre ======================"
5245
5246 test_56a() {
5247         local numfiles=3
5248         local dir=$DIR/$tdir
5249
5250         rm -rf $dir
5251         test_mkdir -p $dir/dir
5252         for i in $(seq $numfiles); do
5253                 touch $dir/file$i
5254                 touch $dir/dir/file$i
5255         done
5256
5257         local numcomp=$($LFS getstripe --component-count $dir)
5258
5259         [[ $numcomp == 0 ]] && numcomp=1
5260
5261         # test lfs getstripe with --recursive
5262         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5263
5264         [[ $filenum -eq $((numfiles * 2)) ]] ||
5265                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5266         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5267         [[ $filenum -eq $numfiles ]] ||
5268                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5269         echo "$LFS getstripe showed obdidx or l_ost_idx"
5270
5271         # test lfs getstripe with file instead of dir
5272         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5273         [[ $filenum -eq 1 ]] ||
5274                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5275         echo "$LFS getstripe file1 passed"
5276
5277         #test lfs getstripe with --verbose
5278         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5279         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5280                 error "$LFS getstripe --verbose $dir: "\
5281                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5282         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5283                 error "$LFS getstripe $dir: showed lmm_magic"
5284
5285         #test lfs getstripe with -v prints lmm_fid
5286         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5287         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5288                 error "$LFS getstripe -v $dir: "\
5289                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5290         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5291                 error "$LFS getstripe $dir: showed lmm_fid by default"
5292         echo "$LFS getstripe --verbose passed"
5293
5294         #check for FID information
5295         local fid1=$($LFS getstripe --fid $dir/file1)
5296         local fid2=$($LFS getstripe --verbose $dir/file1 |
5297                      awk '/lmm_fid: / { print $2; exit; }')
5298         local fid3=$($LFS path2fid $dir/file1)
5299
5300         [ "$fid1" != "$fid2" ] &&
5301                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5302         [ "$fid1" != "$fid3" ] &&
5303                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5304         echo "$LFS getstripe --fid passed"
5305
5306         #test lfs getstripe with --obd
5307         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5308                 error "$LFS getstripe --obd wrong_uuid: should return error"
5309
5310         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5311
5312         local ostidx=1
5313         local obduuid=$(ostuuid_from_index $ostidx)
5314         local found=$($LFS getstripe -r --obd $obduuid $dir |
5315                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5316
5317         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5318         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5319                 ((filenum--))
5320         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5321                 ((filenum--))
5322
5323         [[ $found -eq $filenum ]] ||
5324                 error "$LFS getstripe --obd: found $found expect $filenum"
5325         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5326                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5327                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5328                 error "$LFS getstripe --obd: should not show file on other obd"
5329         echo "$LFS getstripe --obd passed"
5330 }
5331 run_test 56a "check $LFS getstripe"
5332
5333 test_56b() {
5334         local dir=$DIR/$tdir
5335         local numdirs=3
5336
5337         test_mkdir $dir
5338         for i in $(seq $numdirs); do
5339                 test_mkdir $dir/dir$i
5340         done
5341
5342         # test lfs getdirstripe default mode is non-recursion, which is
5343         # different from lfs getstripe
5344         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5345
5346         [[ $dircnt -eq 1 ]] ||
5347                 error "$LFS getdirstripe: found $dircnt, not 1"
5348         dircnt=$($LFS getdirstripe --recursive $dir |
5349                 grep -c lmv_stripe_count)
5350         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5351                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5352 }
5353 run_test 56b "check $LFS getdirstripe"
5354
5355 test_56c() {
5356         remote_ost_nodsh && skip "remote OST with nodsh"
5357
5358         local ost_idx=0
5359         local ost_name=$(ostname_from_index $ost_idx)
5360         local old_status=$(ost_dev_status $ost_idx)
5361
5362         [[ -z "$old_status" ]] ||
5363                 skip_env "OST $ost_name is in $old_status status"
5364
5365         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5366         sleep_maxage
5367
5368         local new_status=$(ost_dev_status $ost_idx)
5369
5370         [[ "$new_status" = "D" ]] ||
5371                 error "OST $ost_name is in status of '$new_status', not 'D'"
5372
5373         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5374         sleep_maxage
5375
5376         new_status=$(ost_dev_status $ost_idx)
5377         [[ -z "$new_status" ]] ||
5378                 error "OST $ost_name is in status of '$new_status', not ''"
5379 }
5380 run_test 56c "check 'lfs df' showing device status"
5381
5382 NUMFILES=3
5383 NUMDIRS=3
5384 setup_56() {
5385         local local_tdir="$1"
5386         local local_numfiles="$2"
5387         local local_numdirs="$3"
5388         local dir_params="$4"
5389         local dir_stripe_params="$5"
5390
5391         if [ ! -d "$local_tdir" ] ; then
5392                 test_mkdir -p $dir_stripe_params $local_tdir
5393                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5394                 for i in $(seq $local_numfiles) ; do
5395                         touch $local_tdir/file$i
5396                 done
5397                 for i in $(seq $local_numdirs) ; do
5398                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5399                         for j in $(seq $local_numfiles) ; do
5400                                 touch $local_tdir/dir$i/file$j
5401                         done
5402                 done
5403         fi
5404 }
5405
5406 setup_56_special() {
5407         local local_tdir=$1
5408         local local_numfiles=$2
5409         local local_numdirs=$3
5410
5411         setup_56 $local_tdir $local_numfiles $local_numdirs
5412
5413         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5414                 for i in $(seq $local_numfiles) ; do
5415                         mknod $local_tdir/loop${i}b b 7 $i
5416                         mknod $local_tdir/null${i}c c 1 3
5417                         ln -s $local_tdir/file1 $local_tdir/link${i}
5418                 done
5419                 for i in $(seq $local_numdirs) ; do
5420                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5421                         mknod $local_tdir/dir$i/null${i}c c 1 3
5422                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5423                 done
5424         fi
5425 }
5426
5427 test_56g() {
5428         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5429         local expected=$(($NUMDIRS + 2))
5430
5431         setup_56 $dir $NUMFILES $NUMDIRS
5432
5433         # test lfs find with -name
5434         for i in $(seq $NUMFILES) ; do
5435                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5436
5437                 [ $nums -eq $expected ] ||
5438                         error "lfs find -name '*$i' $dir wrong: "\
5439                               "found $nums, expected $expected"
5440         done
5441 }
5442 run_test 56g "check lfs find -name"
5443
5444 test_56h() {
5445         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5446         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5447
5448         setup_56 $dir $NUMFILES $NUMDIRS
5449
5450         # test lfs find with ! -name
5451         for i in $(seq $NUMFILES) ; do
5452                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5453
5454                 [ $nums -eq $expected ] ||
5455                         error "lfs find ! -name '*$i' $dir wrong: "\
5456                               "found $nums, expected $expected"
5457         done
5458 }
5459 run_test 56h "check lfs find ! -name"
5460
5461 test_56i() {
5462         local dir=$DIR/$tdir
5463
5464         test_mkdir $dir
5465
5466         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5467         local out=$($cmd)
5468
5469         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5470 }
5471 run_test 56i "check 'lfs find -ost UUID' skips directories"
5472
5473 test_56j() {
5474         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5475
5476         setup_56_special $dir $NUMFILES $NUMDIRS
5477
5478         local expected=$((NUMDIRS + 1))
5479         local cmd="$LFS find -type d $dir"
5480         local nums=$($cmd | wc -l)
5481
5482         [ $nums -eq $expected ] ||
5483                 error "'$cmd' wrong: found $nums, expected $expected"
5484 }
5485 run_test 56j "check lfs find -type d"
5486
5487 test_56k() {
5488         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5489
5490         setup_56_special $dir $NUMFILES $NUMDIRS
5491
5492         local expected=$(((NUMDIRS + 1) * NUMFILES))
5493         local cmd="$LFS find -type f $dir"
5494         local nums=$($cmd | wc -l)
5495
5496         [ $nums -eq $expected ] ||
5497                 error "'$cmd' wrong: found $nums, expected $expected"
5498 }
5499 run_test 56k "check lfs find -type f"
5500
5501 test_56l() {
5502         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5503
5504         setup_56_special $dir $NUMFILES $NUMDIRS
5505
5506         local expected=$((NUMDIRS + NUMFILES))
5507         local cmd="$LFS find -type b $dir"
5508         local nums=$($cmd | wc -l)
5509
5510         [ $nums -eq $expected ] ||
5511                 error "'$cmd' wrong: found $nums, expected $expected"
5512 }
5513 run_test 56l "check lfs find -type b"
5514
5515 test_56m() {
5516         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5517
5518         setup_56_special $dir $NUMFILES $NUMDIRS
5519
5520         local expected=$((NUMDIRS + NUMFILES))
5521         local cmd="$LFS find -type c $dir"
5522         local nums=$($cmd | wc -l)
5523         [ $nums -eq $expected ] ||
5524                 error "'$cmd' wrong: found $nums, expected $expected"
5525 }
5526 run_test 56m "check lfs find -type c"
5527
5528 test_56n() {
5529         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5530         setup_56_special $dir $NUMFILES $NUMDIRS
5531
5532         local expected=$((NUMDIRS + NUMFILES))
5533         local cmd="$LFS find -type l $dir"
5534         local nums=$($cmd | wc -l)
5535
5536         [ $nums -eq $expected ] ||
5537                 error "'$cmd' wrong: found $nums, expected $expected"
5538 }
5539 run_test 56n "check lfs find -type l"
5540
5541 test_56o() {
5542         local dir=$DIR/$tdir
5543
5544         setup_56 $dir $NUMFILES $NUMDIRS
5545         utime $dir/file1 > /dev/null || error "utime (1)"
5546         utime $dir/file2 > /dev/null || error "utime (2)"
5547         utime $dir/dir1 > /dev/null || error "utime (3)"
5548         utime $dir/dir2 > /dev/null || error "utime (4)"
5549         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5550         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5551
5552         local expected=4
5553         local nums=$($LFS find -mtime +0 $dir | wc -l)
5554
5555         [ $nums -eq $expected ] ||
5556                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5557
5558         expected=12
5559         cmd="$LFS find -mtime 0 $dir"
5560         nums=$($cmd | wc -l)
5561         [ $nums -eq $expected ] ||
5562                 error "'$cmd' wrong: found $nums, expected $expected"
5563 }
5564 run_test 56o "check lfs find -mtime for old files"
5565
5566 test_56ob() {
5567         local dir=$DIR/$tdir
5568         local expected=1
5569         local count=0
5570
5571         # just to make sure there is something that won't be found
5572         test_mkdir $dir
5573         touch $dir/$tfile.now
5574
5575         for age in year week day hour min; do
5576                 count=$((count + 1))
5577
5578                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5579                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5580                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5581
5582                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5583                 local nums=$($cmd | wc -l)
5584                 [ $nums -eq $expected ] ||
5585                         error "'$cmd' wrong: found $nums, expected $expected"
5586
5587                 cmd="$LFS find $dir -atime $count${age:0:1}"
5588                 nums=$($cmd | wc -l)
5589                 [ $nums -eq $expected ] ||
5590                         error "'$cmd' wrong: found $nums, expected $expected"
5591         done
5592
5593         sleep 2
5594         cmd="$LFS find $dir -ctime +1s -type f"
5595         nums=$($cmd | wc -l)
5596         (( $nums == $count * 2 + 1)) ||
5597                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5598 }
5599 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5600
5601 test_56p() {
5602         [ $RUNAS_ID -eq $UID ] &&
5603                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5604
5605         local dir=$DIR/$tdir
5606
5607         setup_56 $dir $NUMFILES $NUMDIRS
5608         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5609
5610         local expected=$NUMFILES
5611         local cmd="$LFS find -uid $RUNAS_ID $dir"
5612         local nums=$($cmd | wc -l)
5613
5614         [ $nums -eq $expected ] ||
5615                 error "'$cmd' wrong: found $nums, expected $expected"
5616
5617         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5618         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5619         nums=$($cmd | wc -l)
5620         [ $nums -eq $expected ] ||
5621                 error "'$cmd' wrong: found $nums, expected $expected"
5622 }
5623 run_test 56p "check lfs find -uid and ! -uid"
5624
5625 test_56q() {
5626         [ $RUNAS_ID -eq $UID ] &&
5627                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5628
5629         local dir=$DIR/$tdir
5630
5631         setup_56 $dir $NUMFILES $NUMDIRS
5632         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5633
5634         local expected=$NUMFILES
5635         local cmd="$LFS find -gid $RUNAS_GID $dir"
5636         local nums=$($cmd | wc -l)
5637
5638         [ $nums -eq $expected ] ||
5639                 error "'$cmd' wrong: found $nums, expected $expected"
5640
5641         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5642         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5643         nums=$($cmd | wc -l)
5644         [ $nums -eq $expected ] ||
5645                 error "'$cmd' wrong: found $nums, expected $expected"
5646 }
5647 run_test 56q "check lfs find -gid and ! -gid"
5648
5649 test_56r() {
5650         local dir=$DIR/$tdir
5651
5652         setup_56 $dir $NUMFILES $NUMDIRS
5653
5654         local expected=12
5655         local cmd="$LFS find -size 0 -type f $dir"
5656         local nums=$($cmd | wc -l)
5657
5658         [ $nums -eq $expected ] ||
5659                 error "'$cmd' wrong: found $nums, expected $expected"
5660         expected=0
5661         cmd="$LFS find ! -size 0 -type f $dir"
5662         nums=$($cmd | wc -l)
5663         [ $nums -eq $expected ] ||
5664                 error "'$cmd' wrong: found $nums, expected $expected"
5665         echo "test" > $dir/$tfile
5666         echo "test2" > $dir/$tfile.2 && sync
5667         expected=1
5668         cmd="$LFS find -size 5 -type f $dir"
5669         nums=$($cmd | wc -l)
5670         [ $nums -eq $expected ] ||
5671                 error "'$cmd' wrong: found $nums, expected $expected"
5672         expected=1
5673         cmd="$LFS find -size +5 -type f $dir"
5674         nums=$($cmd | wc -l)
5675         [ $nums -eq $expected ] ||
5676                 error "'$cmd' wrong: found $nums, expected $expected"
5677         expected=2
5678         cmd="$LFS find -size +0 -type f $dir"
5679         nums=$($cmd | wc -l)
5680         [ $nums -eq $expected ] ||
5681                 error "'$cmd' wrong: found $nums, expected $expected"
5682         expected=2
5683         cmd="$LFS find ! -size -5 -type f $dir"
5684         nums=$($cmd | wc -l)
5685         [ $nums -eq $expected ] ||
5686                 error "'$cmd' wrong: found $nums, expected $expected"
5687         expected=12
5688         cmd="$LFS find -size -5 -type f $dir"
5689         nums=$($cmd | wc -l)
5690         [ $nums -eq $expected ] ||
5691                 error "'$cmd' wrong: found $nums, expected $expected"
5692 }
5693 run_test 56r "check lfs find -size works"
5694
5695 test_56s() { # LU-611 #LU-9369
5696         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5697
5698         local dir=$DIR/$tdir
5699         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5700
5701         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5702         for i in $(seq $NUMDIRS); do
5703                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5704         done
5705
5706         local expected=$NUMDIRS
5707         local cmd="$LFS find -c $OSTCOUNT $dir"
5708         local nums=$($cmd | wc -l)
5709
5710         [ $nums -eq $expected ] || {
5711                 $LFS getstripe -R $dir
5712                 error "'$cmd' wrong: found $nums, expected $expected"
5713         }
5714
5715         expected=$((NUMDIRS + onestripe))
5716         cmd="$LFS find -stripe-count +0 -type f $dir"
5717         nums=$($cmd | wc -l)
5718         [ $nums -eq $expected ] || {
5719                 $LFS getstripe -R $dir
5720                 error "'$cmd' wrong: found $nums, expected $expected"
5721         }
5722
5723         expected=$onestripe
5724         cmd="$LFS find -stripe-count 1 -type f $dir"
5725         nums=$($cmd | wc -l)
5726         [ $nums -eq $expected ] || {
5727                 $LFS getstripe -R $dir
5728                 error "'$cmd' wrong: found $nums, expected $expected"
5729         }
5730
5731         cmd="$LFS find -stripe-count -2 -type f $dir"
5732         nums=$($cmd | wc -l)
5733         [ $nums -eq $expected ] || {
5734                 $LFS getstripe -R $dir
5735                 error "'$cmd' wrong: found $nums, expected $expected"
5736         }
5737
5738         expected=0
5739         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5740         nums=$($cmd | wc -l)
5741         [ $nums -eq $expected ] || {
5742                 $LFS getstripe -R $dir
5743                 error "'$cmd' wrong: found $nums, expected $expected"
5744         }
5745 }
5746 run_test 56s "check lfs find -stripe-count works"
5747
5748 test_56t() { # LU-611 #LU-9369
5749         local dir=$DIR/$tdir
5750
5751         setup_56 $dir 0 $NUMDIRS
5752         for i in $(seq $NUMDIRS); do
5753                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5754         done
5755
5756         local expected=$NUMDIRS
5757         local cmd="$LFS find -S 8M $dir"
5758         local nums=$($cmd | wc -l)
5759
5760         [ $nums -eq $expected ] || {
5761                 $LFS getstripe -R $dir
5762                 error "'$cmd' wrong: found $nums, expected $expected"
5763         }
5764         rm -rf $dir
5765
5766         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5767
5768         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5769
5770         expected=$(((NUMDIRS + 1) * NUMFILES))
5771         cmd="$LFS find -stripe-size 512k -type f $dir"
5772         nums=$($cmd | wc -l)
5773         [ $nums -eq $expected ] ||
5774                 error "'$cmd' wrong: found $nums, expected $expected"
5775
5776         cmd="$LFS find -stripe-size +320k -type f $dir"
5777         nums=$($cmd | wc -l)
5778         [ $nums -eq $expected ] ||
5779                 error "'$cmd' wrong: found $nums, expected $expected"
5780
5781         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5782         cmd="$LFS find -stripe-size +200k -type f $dir"
5783         nums=$($cmd | wc -l)
5784         [ $nums -eq $expected ] ||
5785                 error "'$cmd' wrong: found $nums, expected $expected"
5786
5787         cmd="$LFS find -stripe-size -640k -type f $dir"
5788         nums=$($cmd | wc -l)
5789         [ $nums -eq $expected ] ||
5790                 error "'$cmd' wrong: found $nums, expected $expected"
5791
5792         expected=4
5793         cmd="$LFS find -stripe-size 256k -type f $dir"
5794         nums=$($cmd | wc -l)
5795         [ $nums -eq $expected ] ||
5796                 error "'$cmd' wrong: found $nums, expected $expected"
5797
5798         cmd="$LFS find -stripe-size -320k -type f $dir"
5799         nums=$($cmd | wc -l)
5800         [ $nums -eq $expected ] ||
5801                 error "'$cmd' wrong: found $nums, expected $expected"
5802
5803         expected=0
5804         cmd="$LFS find -stripe-size 1024k -type f $dir"
5805         nums=$($cmd | wc -l)
5806         [ $nums -eq $expected ] ||
5807                 error "'$cmd' wrong: found $nums, expected $expected"
5808 }
5809 run_test 56t "check lfs find -stripe-size works"
5810
5811 test_56u() { # LU-611
5812         local dir=$DIR/$tdir
5813
5814         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5815
5816         if [[ $OSTCOUNT -gt 1 ]]; then
5817                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5818                 onestripe=4
5819         else
5820                 onestripe=0
5821         fi
5822
5823         local expected=$(((NUMDIRS + 1) * NUMFILES))
5824         local cmd="$LFS find -stripe-index 0 -type f $dir"
5825         local nums=$($cmd | wc -l)
5826
5827         [ $nums -eq $expected ] ||
5828                 error "'$cmd' wrong: found $nums, expected $expected"
5829
5830         expected=$onestripe
5831         cmd="$LFS find -stripe-index 1 -type f $dir"
5832         nums=$($cmd | wc -l)
5833         [ $nums -eq $expected ] ||
5834                 error "'$cmd' wrong: found $nums, expected $expected"
5835
5836         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5837         nums=$($cmd | wc -l)
5838         [ $nums -eq $expected ] ||
5839                 error "'$cmd' wrong: found $nums, expected $expected"
5840
5841         expected=0
5842         # This should produce an error and not return any files
5843         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5844         nums=$($cmd 2>/dev/null | wc -l)
5845         [ $nums -eq $expected ] ||
5846                 error "'$cmd' wrong: found $nums, expected $expected"
5847
5848         if [[ $OSTCOUNT -gt 1 ]]; then
5849                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5850                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5851                 nums=$($cmd | wc -l)
5852                 [ $nums -eq $expected ] ||
5853                         error "'$cmd' wrong: found $nums, expected $expected"
5854         fi
5855 }
5856 run_test 56u "check lfs find -stripe-index works"
5857
5858 test_56v() {
5859         local mdt_idx=0
5860         local dir=$DIR/$tdir
5861
5862         setup_56 $dir $NUMFILES $NUMDIRS
5863
5864         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5865         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5866
5867         for file in $($LFS find -m $UUID $dir); do
5868                 file_midx=$($LFS getstripe -m $file)
5869                 [ $file_midx -eq $mdt_idx ] ||
5870                         error "lfs find -m $UUID != getstripe -m $file_midx"
5871         done
5872 }
5873 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5874
5875 test_56w() {
5876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5878
5879         local dir=$DIR/$tdir
5880
5881         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5882
5883         local stripe_size=$($LFS getstripe -S -d $dir) ||
5884                 error "$LFS getstripe -S -d $dir failed"
5885         stripe_size=${stripe_size%% *}
5886
5887         local file_size=$((stripe_size * OSTCOUNT))
5888         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5889         local required_space=$((file_num * file_size))
5890         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5891                            head -n1)
5892         [[ $free_space -le $((required_space / 1024)) ]] &&
5893                 skip_env "need $required_space, have $free_space kbytes"
5894
5895         local dd_bs=65536
5896         local dd_count=$((file_size / dd_bs))
5897
5898         # write data into the files
5899         local i
5900         local j
5901         local file
5902
5903         for i in $(seq $NUMFILES); do
5904                 file=$dir/file$i
5905                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5906                         error "write data into $file failed"
5907         done
5908         for i in $(seq $NUMDIRS); do
5909                 for j in $(seq $NUMFILES); do
5910                         file=$dir/dir$i/file$j
5911                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5912                                 error "write data into $file failed"
5913                 done
5914         done
5915
5916         # $LFS_MIGRATE will fail if hard link migration is unsupported
5917         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5918                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5919                         error "creating links to $dir/dir1/file1 failed"
5920         fi
5921
5922         local expected=-1
5923
5924         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5925
5926         # lfs_migrate file
5927         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5928
5929         echo "$cmd"
5930         eval $cmd || error "$cmd failed"
5931
5932         check_stripe_count $dir/file1 $expected
5933
5934         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5935         then
5936                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5937                 # OST 1 if it is on OST 0. This file is small enough to
5938                 # be on only one stripe.
5939                 file=$dir/migr_1_ost
5940                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5941                         error "write data into $file failed"
5942                 local obdidx=$($LFS getstripe -i $file)
5943                 local oldmd5=$(md5sum $file)
5944                 local newobdidx=0
5945
5946                 [[ $obdidx -eq 0 ]] && newobdidx=1
5947                 cmd="$LFS migrate -i $newobdidx $file"
5948                 echo $cmd
5949                 eval $cmd || error "$cmd failed"
5950
5951                 local realobdix=$($LFS getstripe -i $file)
5952                 local newmd5=$(md5sum $file)
5953
5954                 [[ $newobdidx -ne $realobdix ]] &&
5955                         error "new OST is different (was=$obdidx, "\
5956                               "wanted=$newobdidx, got=$realobdix)"
5957                 [[ "$oldmd5" != "$newmd5" ]] &&
5958                         error "md5sum differ: $oldmd5, $newmd5"
5959         fi
5960
5961         # lfs_migrate dir
5962         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5963         echo "$cmd"
5964         eval $cmd || error "$cmd failed"
5965
5966         for j in $(seq $NUMFILES); do
5967                 check_stripe_count $dir/dir1/file$j $expected
5968         done
5969
5970         # lfs_migrate works with lfs find
5971         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5972              $LFS_MIGRATE -y -c $expected"
5973         echo "$cmd"
5974         eval $cmd || error "$cmd failed"
5975
5976         for i in $(seq 2 $NUMFILES); do
5977                 check_stripe_count $dir/file$i $expected
5978         done
5979         for i in $(seq 2 $NUMDIRS); do
5980                 for j in $(seq $NUMFILES); do
5981                 check_stripe_count $dir/dir$i/file$j $expected
5982                 done
5983         done
5984 }
5985 run_test 56w "check lfs_migrate -c stripe_count works"
5986
5987 test_56wb() {
5988         local file1=$DIR/$tdir/file1
5989         local create_pool=false
5990         local initial_pool=$($LFS getstripe -p $DIR)
5991         local pool_list=()
5992         local pool=""
5993
5994         echo -n "Creating test dir..."
5995         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5996         echo "done."
5997
5998         echo -n "Creating test file..."
5999         touch $file1 || error "cannot create file"
6000         echo "done."
6001
6002         echo -n "Detecting existing pools..."
6003         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6004
6005         if [ ${#pool_list[@]} -gt 0 ]; then
6006                 echo "${pool_list[@]}"
6007                 for thispool in "${pool_list[@]}"; do
6008                         if [[ -z "$initial_pool" ||
6009                               "$initial_pool" != "$thispool" ]]; then
6010                                 pool="$thispool"
6011                                 echo "Using existing pool '$pool'"
6012                                 break
6013                         fi
6014                 done
6015         else
6016                 echo "none detected."
6017         fi
6018         if [ -z "$pool" ]; then
6019                 pool=${POOL:-testpool}
6020                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6021                 echo -n "Creating pool '$pool'..."
6022                 create_pool=true
6023                 pool_add $pool &> /dev/null ||
6024                         error "pool_add failed"
6025                 echo "done."
6026
6027                 echo -n "Adding target to pool..."
6028                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6029                         error "pool_add_targets failed"
6030                 echo "done."
6031         fi
6032
6033         echo -n "Setting pool using -p option..."
6034         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6035                 error "migrate failed rc = $?"
6036         echo "done."
6037
6038         echo -n "Verifying test file is in pool after migrating..."
6039         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6040                 error "file was not migrated to pool $pool"
6041         echo "done."
6042
6043         echo -n "Removing test file from pool '$pool'..."
6044         $LFS migrate $file1 &> /dev/null ||
6045                 error "cannot remove from pool"
6046         [ "$($LFS getstripe -p $file1)" ] &&
6047                 error "pool still set"
6048         echo "done."
6049
6050         echo -n "Setting pool using --pool option..."
6051         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6052                 error "migrate failed rc = $?"
6053         echo "done."
6054
6055         # Clean up
6056         rm -f $file1
6057         if $create_pool; then
6058                 destroy_test_pools 2> /dev/null ||
6059                         error "destroy test pools failed"
6060         fi
6061 }
6062 run_test 56wb "check lfs_migrate pool support"
6063
6064 test_56wc() {
6065         local file1="$DIR/$tdir/file1"
6066
6067         echo -n "Creating test dir..."
6068         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6069         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6070         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6071                 error "cannot set stripe"
6072         echo "done"
6073
6074         echo -n "Setting initial stripe for test file..."
6075         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6076                 error "cannot set stripe"
6077         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6078                 error "stripe size not set"
6079         echo "done."
6080
6081         # File currently set to -S 512K -c 1
6082
6083         # Ensure -c and -S options are rejected when -R is set
6084         echo -n "Verifying incompatible options are detected..."
6085         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6086                 error "incompatible -c and -R options not detected"
6087         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6088                 error "incompatible -S and -R options not detected"
6089         echo "done."
6090
6091         # Ensure unrecognized options are passed through to 'lfs migrate'
6092         echo -n "Verifying -S option is passed through to lfs migrate..."
6093         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6094                 error "migration failed"
6095         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6096                 error "file was not restriped"
6097         echo "done."
6098
6099         # File currently set to -S 1M -c 1
6100
6101         # Ensure long options are supported
6102         echo -n "Verifying long options supported..."
6103         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6104                 error "long option without argument not supported"
6105         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6106                 error "long option with argument not supported"
6107         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6108                 error "file not restriped with --stripe-size option"
6109         echo "done."
6110
6111         # File currently set to -S 512K -c 1
6112
6113         if [ "$OSTCOUNT" -gt 1 ]; then
6114                 echo -n "Verifying explicit stripe count can be set..."
6115                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6116                         error "migrate failed"
6117                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6118                         error "file not restriped to explicit count"
6119                 echo "done."
6120         fi
6121
6122         # File currently set to -S 512K -c 1 or -S 512K -c 2
6123
6124         # Ensure parent striping is used if -R is set, and no stripe
6125         # count or size is specified
6126         echo -n "Setting stripe for parent directory..."
6127         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6128                 error "cannot set stripe"
6129         echo "done."
6130
6131         echo -n "Verifying restripe option uses parent stripe settings..."
6132         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6133                 error "migrate failed"
6134         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6135                 error "file not restriped to parent settings"
6136         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6137                 error "file not restriped to parent settings"
6138         echo "done."
6139
6140         # File currently set to -S 1M -c 1
6141
6142         # Ensure striping is preserved if -R is not set, and no stripe
6143         # count or size is specified
6144         echo -n "Verifying striping size preserved when not specified..."
6145         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6146         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6147                 error "cannot set stripe on parent directory"
6148         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6149                 error "migrate failed"
6150         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6151                 error "file was restriped"
6152         echo "done."
6153
6154         # Ensure file name properly detected when final option has no argument
6155         echo -n "Verifying file name properly detected..."
6156         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6157                 error "file name interpreted as option argument"
6158         echo "done."
6159
6160         # Clean up
6161         rm -f "$file1"
6162 }
6163 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6164
6165 test_56wd() {
6166         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6167
6168         local file1=$DIR/$tdir/file1
6169
6170         echo -n "Creating test dir..."
6171         test_mkdir $DIR/$tdir || error "cannot create dir"
6172         echo "done."
6173
6174         echo -n "Creating test file..."
6175         touch $file1
6176         echo "done."
6177
6178         # Ensure 'lfs migrate' will fail by using a non-existent option,
6179         # and make sure rsync is not called to recover
6180         echo -n "Make sure --no-rsync option works..."
6181         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6182                 grep -q 'refusing to fall back to rsync' ||
6183                 error "rsync was called with --no-rsync set"
6184         echo "done."
6185
6186         # Ensure rsync is called without trying 'lfs migrate' first
6187         echo -n "Make sure --rsync option works..."
6188         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6189                 grep -q 'falling back to rsync' &&
6190                 error "lfs migrate was called with --rsync set"
6191         echo "done."
6192
6193         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6194         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6195                 grep -q 'at the same time' ||
6196                 error "--rsync and --no-rsync accepted concurrently"
6197         echo "done."
6198
6199         # Clean up
6200         rm -f $file1
6201 }
6202 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6203
6204 test_56x() {
6205         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6206         check_swap_layouts_support
6207
6208         local dir=$DIR/$tdir
6209         local ref1=/etc/passwd
6210         local file1=$dir/file1
6211
6212         test_mkdir $dir || error "creating dir $dir"
6213         $LFS setstripe -c 2 $file1
6214         cp $ref1 $file1
6215         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6216         stripe=$($LFS getstripe -c $file1)
6217         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6218         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6219
6220         # clean up
6221         rm -f $file1
6222 }
6223 run_test 56x "lfs migration support"
6224
6225 test_56xa() {
6226         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6227         check_swap_layouts_support
6228
6229         local dir=$DIR/$tdir/$testnum
6230
6231         test_mkdir -p $dir
6232
6233         local ref1=/etc/passwd
6234         local file1=$dir/file1
6235
6236         $LFS setstripe -c 2 $file1
6237         cp $ref1 $file1
6238         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6239
6240         local stripe=$($LFS getstripe -c $file1)
6241
6242         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6243         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6244
6245         # clean up
6246         rm -f $file1
6247 }
6248 run_test 56xa "lfs migration --block support"
6249
6250 check_migrate_links() {
6251         local dir="$1"
6252         local file1="$dir/file1"
6253         local begin="$2"
6254         local count="$3"
6255         local total_count=$(($begin + $count - 1))
6256         local symlink_count=10
6257         local uniq_count=10
6258
6259         if [ ! -f "$file1" ]; then
6260                 echo -n "creating initial file..."
6261                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6262                         error "cannot setstripe initial file"
6263                 echo "done"
6264
6265                 echo -n "creating symlinks..."
6266                 for s in $(seq 1 $symlink_count); do
6267                         ln -s "$file1" "$dir/slink$s" ||
6268                                 error "cannot create symlinks"
6269                 done
6270                 echo "done"
6271
6272                 echo -n "creating nonlinked files..."
6273                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6274                         error "cannot create nonlinked files"
6275                 echo "done"
6276         fi
6277
6278         # create hard links
6279         if [ ! -f "$dir/file$total_count" ]; then
6280                 echo -n "creating hard links $begin:$total_count..."
6281                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6282                         /dev/null || error "cannot create hard links"
6283                 echo "done"
6284         fi
6285
6286         echo -n "checking number of hard links listed in xattrs..."
6287         local fid=$($LFS getstripe -F "$file1")
6288         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6289
6290         echo "${#paths[*]}"
6291         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6292                         skip "hard link list has unexpected size, skipping test"
6293         fi
6294         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6295                         error "link names should exceed xattrs size"
6296         fi
6297
6298         echo -n "migrating files..."
6299         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6300         local rc=$?
6301         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6302         echo "done"
6303
6304         # make sure all links have been properly migrated
6305         echo -n "verifying files..."
6306         fid=$($LFS getstripe -F "$file1") ||
6307                 error "cannot get fid for file $file1"
6308         for i in $(seq 2 $total_count); do
6309                 local fid2=$($LFS getstripe -F $dir/file$i)
6310
6311                 [ "$fid2" == "$fid" ] ||
6312                         error "migrated hard link has mismatched FID"
6313         done
6314
6315         # make sure hard links were properly detected, and migration was
6316         # performed only once for the entire link set; nonlinked files should
6317         # also be migrated
6318         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6319         local expected=$(($uniq_count + 1))
6320
6321         [ "$actual" -eq  "$expected" ] ||
6322                 error "hard links individually migrated ($actual != $expected)"
6323
6324         # make sure the correct number of hard links are present
6325         local hardlinks=$(stat -c '%h' "$file1")
6326
6327         [ $hardlinks -eq $total_count ] ||
6328                 error "num hard links $hardlinks != $total_count"
6329         echo "done"
6330
6331         return 0
6332 }
6333
6334 test_56xb() {
6335         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6336                 skip "Need MDS version at least 2.10.55"
6337
6338         local dir="$DIR/$tdir"
6339
6340         test_mkdir "$dir" || error "cannot create dir $dir"
6341
6342         echo "testing lfs migrate mode when all links fit within xattrs"
6343         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6344
6345         echo "testing rsync mode when all links fit within xattrs"
6346         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6347
6348         echo "testing lfs migrate mode when all links do not fit within xattrs"
6349         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6350
6351         echo "testing rsync mode when all links do not fit within xattrs"
6352         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6353
6354
6355         # clean up
6356         rm -rf $dir
6357 }
6358 run_test 56xb "lfs migration hard link support"
6359
6360 test_56xc() {
6361         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6362
6363         local dir="$DIR/$tdir"
6364
6365         test_mkdir "$dir" || error "cannot create dir $dir"
6366
6367         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6368         echo -n "Setting initial stripe for 20MB test file..."
6369         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6370         echo "done"
6371         echo -n "Sizing 20MB test file..."
6372         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6373         echo "done"
6374         echo -n "Verifying small file autostripe count is 1..."
6375         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6376                 error "cannot migrate 20MB file"
6377         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6378                 error "cannot get stripe for $dir/20mb"
6379         [ $stripe_count -eq 1 ] ||
6380                 error "unexpected stripe count $stripe_count for 20MB file"
6381         rm -f "$dir/20mb"
6382         echo "done"
6383
6384         # Test 2: File is small enough to fit within the available space on
6385         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6386         # have at least an additional 1KB for each desired stripe for test 3
6387         echo -n "Setting stripe for 1GB test file..."
6388         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6389         echo "done"
6390         echo -n "Sizing 1GB test file..."
6391         # File size is 1GB + 3KB
6392         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6393                 error "cannot create 1GB test file"
6394         echo "done"
6395         echo -n "Migrating 1GB file..."
6396         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6397                 error "cannot migrate file"
6398         echo "done"
6399         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6400         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6401                 error "cannot get stripe for $dir/1gb"
6402         [ $stripe_count -eq 2 ] ||
6403                 error "unexpected stripe count $stripe_count (expected 2)"
6404         echo "done"
6405
6406         # Test 3: File is too large to fit within the available space on
6407         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6408         if [ $OSTCOUNT -ge 3 ]; then
6409                 # The required available space is calculated as
6410                 # file size (1GB + 3KB) / OST count (3).
6411                 local kb_per_ost=349526
6412
6413                 echo -n "Migrating 1GB file..."
6414                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6415                         /dev/null || error "cannot migrate file"
6416                 echo "done"
6417
6418                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6419                 echo -n "Verifying autostripe count with limited space..."
6420                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6421                         error "unexpected stripe count $stripe_count (wanted 3)"
6422                 echo "done"
6423         fi
6424
6425         # clean up
6426         rm -rf $dir
6427 }
6428 run_test 56xc "lfs migration autostripe"
6429
6430 test_56y() {
6431         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6432                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6433
6434         local res=""
6435         local dir=$DIR/$tdir
6436         local f1=$dir/file1
6437         local f2=$dir/file2
6438
6439         test_mkdir -p $dir || error "creating dir $dir"
6440         touch $f1 || error "creating std file $f1"
6441         $MULTIOP $f2 H2c || error "creating released file $f2"
6442
6443         # a directory can be raid0, so ask only for files
6444         res=$($LFS find $dir -L raid0 -type f | wc -l)
6445         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6446
6447         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6448         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6449
6450         # only files can be released, so no need to force file search
6451         res=$($LFS find $dir -L released)
6452         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6453
6454         res=$($LFS find $dir -type f \! -L released)
6455         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6456 }
6457 run_test 56y "lfs find -L raid0|released"
6458
6459 test_56z() { # LU-4824
6460         # This checks to make sure 'lfs find' continues after errors
6461         # There are two classes of errors that should be caught:
6462         # - If multiple paths are provided, all should be searched even if one
6463         #   errors out
6464         # - If errors are encountered during the search, it should not terminate
6465         #   early
6466         local dir=$DIR/$tdir
6467         local i
6468
6469         test_mkdir $dir
6470         for i in d{0..9}; do
6471                 test_mkdir $dir/$i
6472         done
6473         touch $dir/d{0..9}/$tfile
6474         $LFS find $DIR/non_existent_dir $dir &&
6475                 error "$LFS find did not return an error"
6476         # Make a directory unsearchable. This should NOT be the last entry in
6477         # directory order.  Arbitrarily pick the 6th entry
6478         chmod 700 $($LFS find $dir -type d | sed '6!d')
6479
6480         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6481
6482         # The user should be able to see 10 directories and 9 files
6483         [ $count == 19 ] || error "$LFS find did not continue after error"
6484 }
6485 run_test 56z "lfs find should continue after an error"
6486
6487 test_56aa() { # LU-5937
6488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6489
6490         local dir=$DIR/$tdir
6491
6492         mkdir $dir
6493         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6494
6495         createmany -o $dir/striped_dir/${tfile}- 1024
6496         local dirs=$($LFS find --size +8k $dir/)
6497
6498         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6499 }
6500 run_test 56aa "lfs find --size under striped dir"
6501
6502 test_56ab() { # LU-10705
6503         test_mkdir $DIR/$tdir
6504         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6505         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6506         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6507         # Flush writes to ensure valid blocks.  Need to be more thorough for
6508         # ZFS, since blocks are not allocated/returned to client immediately.
6509         sync_all_data
6510         wait_zfs_commit ost1 2
6511         cancel_lru_locks osc
6512         ls -ls $DIR/$tdir
6513
6514         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6515
6516         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6517
6518         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6519         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6520
6521         rm -f $DIR/$tdir/$tfile.[123]
6522 }
6523 run_test 56ab "lfs find --blocks"
6524
6525 test_56ba() {
6526         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6527                 skip "Need MDS version at least 2.10.50"
6528
6529         # Create composite files with one component
6530         local dir=$DIR/$tdir
6531
6532         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6533         # Create composite files with three components
6534         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6535         # Create non-composite files
6536         createmany -o $dir/${tfile}- 10
6537
6538         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6539
6540         [[ $nfiles == 10 ]] ||
6541                 error "lfs find -E 1M found $nfiles != 10 files"
6542
6543         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6544         [[ $nfiles == 25 ]] ||
6545                 error "lfs find ! -E 1M found $nfiles != 25 files"
6546
6547         # All files have a component that starts at 0
6548         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6549         [[ $nfiles == 35 ]] ||
6550                 error "lfs find --component-start 0 - $nfiles != 35 files"
6551
6552         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6553         [[ $nfiles == 15 ]] ||
6554                 error "lfs find --component-start 2M - $nfiles != 15 files"
6555
6556         # All files created here have a componenet that does not starts at 2M
6557         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6558         [[ $nfiles == 35 ]] ||
6559                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6560
6561         # Find files with a specified number of components
6562         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6563         [[ $nfiles == 15 ]] ||
6564                 error "lfs find --component-count 3 - $nfiles != 15 files"
6565
6566         # Remember non-composite files have a component count of zero
6567         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6568         [[ $nfiles == 10 ]] ||
6569                 error "lfs find --component-count 0 - $nfiles != 10 files"
6570
6571         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6572         [[ $nfiles == 20 ]] ||
6573                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6574
6575         # All files have a flag called "init"
6576         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6577         [[ $nfiles == 35 ]] ||
6578                 error "lfs find --component-flags init - $nfiles != 35 files"
6579
6580         # Multi-component files will have a component not initialized
6581         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6582         [[ $nfiles == 15 ]] ||
6583                 error "lfs find !--component-flags init - $nfiles != 15 files"
6584
6585         rm -rf $dir
6586
6587 }
6588 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6589
6590 test_56ca() {
6591         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6592                 skip "Need MDS version at least 2.10.57"
6593
6594         local td=$DIR/$tdir
6595         local tf=$td/$tfile
6596         local dir
6597         local nfiles
6598         local cmd
6599         local i
6600         local j
6601
6602         # create mirrored directories and mirrored files
6603         mkdir $td || error "mkdir $td failed"
6604         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6605         createmany -o $tf- 10 || error "create $tf- failed"
6606
6607         for i in $(seq 2); do
6608                 dir=$td/dir$i
6609                 mkdir $dir || error "mkdir $dir failed"
6610                 $LFS mirror create -N$((3 + i)) $dir ||
6611                         error "create mirrored dir $dir failed"
6612                 createmany -o $dir/$tfile- 10 ||
6613                         error "create $dir/$tfile- failed"
6614         done
6615
6616         # change the states of some mirrored files
6617         echo foo > $tf-6
6618         for i in $(seq 2); do
6619                 dir=$td/dir$i
6620                 for j in $(seq 4 9); do
6621                         echo foo > $dir/$tfile-$j
6622                 done
6623         done
6624
6625         # find mirrored files with specific mirror count
6626         cmd="$LFS find --mirror-count 3 --type f $td"
6627         nfiles=$($cmd | wc -l)
6628         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6629
6630         cmd="$LFS find ! --mirror-count 3 --type f $td"
6631         nfiles=$($cmd | wc -l)
6632         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6633
6634         cmd="$LFS find --mirror-count +2 --type f $td"
6635         nfiles=$($cmd | wc -l)
6636         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6637
6638         cmd="$LFS find --mirror-count -6 --type f $td"
6639         nfiles=$($cmd | wc -l)
6640         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6641
6642         # find mirrored files with specific file state
6643         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6644         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6645
6646         cmd="$LFS find --mirror-state=ro --type f $td"
6647         nfiles=$($cmd | wc -l)
6648         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6649
6650         cmd="$LFS find ! --mirror-state=ro --type f $td"
6651         nfiles=$($cmd | wc -l)
6652         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6653
6654         cmd="$LFS find --mirror-state=wp --type f $td"
6655         nfiles=$($cmd | wc -l)
6656         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6657
6658         cmd="$LFS find ! --mirror-state=sp --type f $td"
6659         nfiles=$($cmd | wc -l)
6660         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6661 }
6662 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6663
6664 test_57a() {
6665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6666         # note test will not do anything if MDS is not local
6667         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6668                 skip_env "ldiskfs only test"
6669         fi
6670         remote_mds_nodsh && skip "remote MDS with nodsh"
6671
6672         local MNTDEV="osd*.*MDT*.mntdev"
6673         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6674         [ -z "$DEV" ] && error "can't access $MNTDEV"
6675         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6676                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6677                         error "can't access $DEV"
6678                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6679                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6680                 rm $TMP/t57a.dump
6681         done
6682 }
6683 run_test 57a "verify MDS filesystem created with large inodes =="
6684
6685 test_57b() {
6686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6687         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6688                 skip_env "ldiskfs only test"
6689         fi
6690         remote_mds_nodsh && skip "remote MDS with nodsh"
6691
6692         local dir=$DIR/$tdir
6693         local filecount=100
6694         local file1=$dir/f1
6695         local fileN=$dir/f$filecount
6696
6697         rm -rf $dir || error "removing $dir"
6698         test_mkdir -c1 $dir
6699         local mdtidx=$($LFS getstripe -m $dir)
6700         local mdtname=MDT$(printf %04x $mdtidx)
6701         local facet=mds$((mdtidx + 1))
6702
6703         echo "mcreating $filecount files"
6704         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6705
6706         # verify that files do not have EAs yet
6707         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6708                 error "$file1 has an EA"
6709         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6710                 error "$fileN has an EA"
6711
6712         sync
6713         sleep 1
6714         df $dir  #make sure we get new statfs data
6715         local mdsfree=$(do_facet $facet \
6716                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6717         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6718         local file
6719
6720         echo "opening files to create objects/EAs"
6721         for file in $(seq -f $dir/f%g 1 $filecount); do
6722                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6723                         error "opening $file"
6724         done
6725
6726         # verify that files have EAs now
6727         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6728         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6729
6730         sleep 1  #make sure we get new statfs data
6731         df $dir
6732         local mdsfree2=$(do_facet $facet \
6733                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6734         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6735
6736         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6737                 if [ "$mdsfree" != "$mdsfree2" ]; then
6738                         error "MDC before $mdcfree != after $mdcfree2"
6739                 else
6740                         echo "MDC before $mdcfree != after $mdcfree2"
6741                         echo "unable to confirm if MDS has large inodes"
6742                 fi
6743         fi
6744         rm -rf $dir
6745 }
6746 run_test 57b "default LOV EAs are stored inside large inodes ==="
6747
6748 test_58() {
6749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6750         [ -z "$(which wiretest 2>/dev/null)" ] &&
6751                         skip_env "could not find wiretest"
6752
6753         wiretest
6754 }
6755 run_test 58 "verify cross-platform wire constants =============="
6756
6757 test_59() {
6758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6759
6760         echo "touch 130 files"
6761         createmany -o $DIR/f59- 130
6762         echo "rm 130 files"
6763         unlinkmany $DIR/f59- 130
6764         sync
6765         # wait for commitment of removal
6766         wait_delete_completed
6767 }
6768 run_test 59 "verify cancellation of llog records async ========="
6769
6770 TEST60_HEAD="test_60 run $RANDOM"
6771 test_60a() {
6772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6773         remote_mgs_nodsh && skip "remote MGS with nodsh"
6774         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6775                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6776                         skip_env "missing subtest run-llog.sh"
6777
6778         log "$TEST60_HEAD - from kernel mode"
6779         do_facet mgs "$LCTL dk > /dev/null"
6780         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6781         do_facet mgs $LCTL dk > $TMP/$tfile
6782
6783         # LU-6388: test llog_reader
6784         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6785         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6786         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6787                         skip_env "missing llog_reader"
6788         local fstype=$(facet_fstype mgs)
6789         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6790                 skip_env "Only for ldiskfs or zfs type mgs"
6791
6792         local mntpt=$(facet_mntpt mgs)
6793         local mgsdev=$(mgsdevname 1)
6794         local fid_list
6795         local fid
6796         local rec_list
6797         local rec
6798         local rec_type
6799         local obj_file
6800         local path
6801         local seq
6802         local oid
6803         local pass=true
6804
6805         #get fid and record list
6806         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6807                 tail -n 4))
6808         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6809                 tail -n 4))
6810         #remount mgs as ldiskfs or zfs type
6811         stop mgs || error "stop mgs failed"
6812         mount_fstype mgs || error "remount mgs failed"
6813         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6814                 fid=${fid_list[i]}
6815                 rec=${rec_list[i]}
6816                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6817                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6818                 oid=$((16#$oid))
6819
6820                 case $fstype in
6821                         ldiskfs )
6822                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6823                         zfs )
6824                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6825                 esac
6826                 echo "obj_file is $obj_file"
6827                 do_facet mgs $llog_reader $obj_file
6828
6829                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6830                         awk '{ print $3 }' | sed -e "s/^type=//g")
6831                 if [ $rec_type != $rec ]; then
6832                         echo "FAILED test_60a wrong record type $rec_type," \
6833                               "should be $rec"
6834                         pass=false
6835                         break
6836                 fi
6837
6838                 #check obj path if record type is LLOG_LOGID_MAGIC
6839                 if [ "$rec" == "1064553b" ]; then
6840                         path=$(do_facet mgs $llog_reader $obj_file |
6841                                 grep "path=" | awk '{ print $NF }' |
6842                                 sed -e "s/^path=//g")
6843                         if [ $obj_file != $mntpt/$path ]; then
6844                                 echo "FAILED test_60a wrong obj path" \
6845                                       "$montpt/$path, should be $obj_file"
6846                                 pass=false
6847                                 break
6848                         fi
6849                 fi
6850         done
6851         rm -f $TMP/$tfile
6852         #restart mgs before "error", otherwise it will block the next test
6853         stop mgs || error "stop mgs failed"
6854         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6855         $pass || error "test failed, see FAILED test_60a messages for specifics"
6856 }
6857 run_test 60a "llog_test run from kernel module and test llog_reader"
6858
6859 test_60b() { # bug 6411
6860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6861
6862         dmesg > $DIR/$tfile
6863         LLOG_COUNT=$(do_facet mgs dmesg |
6864                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6865                           /llog_[a-z]*.c:[0-9]/ {
6866                                 if (marker)
6867                                         from_marker++
6868                                 from_begin++
6869                           }
6870                           END {
6871                                 if (marker)
6872                                         print from_marker
6873                                 else
6874                                         print from_begin
6875                           }")
6876
6877         [[ $LLOG_COUNT -gt 120 ]] &&
6878                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6879 }
6880 run_test 60b "limit repeated messages from CERROR/CWARN"
6881
6882 test_60c() {
6883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6884
6885         echo "create 5000 files"
6886         createmany -o $DIR/f60c- 5000
6887 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6888         lctl set_param fail_loc=0x80000137
6889         unlinkmany $DIR/f60c- 5000
6890         lctl set_param fail_loc=0
6891 }
6892 run_test 60c "unlink file when mds full"
6893
6894 test_60d() {
6895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6896
6897         SAVEPRINTK=$(lctl get_param -n printk)
6898         # verify "lctl mark" is even working"
6899         MESSAGE="test message ID $RANDOM $$"
6900         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6901         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6902
6903         lctl set_param printk=0 || error "set lnet.printk failed"
6904         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6905         MESSAGE="new test message ID $RANDOM $$"
6906         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6907         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6908         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6909
6910         lctl set_param -n printk="$SAVEPRINTK"
6911 }
6912 run_test 60d "test printk console message masking"
6913
6914 test_60e() {
6915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6916         remote_mds_nodsh && skip "remote MDS with nodsh"
6917
6918         touch $DIR/$tfile
6919 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6920         do_facet mds1 lctl set_param fail_loc=0x15b
6921         rm $DIR/$tfile
6922 }
6923 run_test 60e "no space while new llog is being created"
6924
6925 test_60g() {
6926         local pid
6927
6928         test_mkdir -c $MDSCOUNT $DIR/$tdir
6929         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6930
6931         (
6932                 local index=0
6933                 while true; do
6934                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6935                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6936                         index=$((index + 1))
6937                 done
6938         ) &
6939
6940         pid=$!
6941
6942         for i in $(seq 100); do 
6943                 # define OBD_FAIL_OSD_TXN_START    0x19a
6944                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6945                 usleep 100
6946         done
6947
6948         kill -9 $pid
6949
6950         mkdir $DIR/$tdir/new || error "mkdir failed"
6951         rmdir $DIR/$tdir/new || error "rmdir failed"
6952 }
6953 run_test 60g "transaction abort won't cause MDT hung"
6954
6955 test_60h() {
6956         [ $MDS1_VERSION -le $(version_code 2.12.52) ] ||
6957                 skip "Need MDS version at least 2.12.52"
6958         [ $MDSCOUNT -le 2 ] || skip "Need >= 2 MDTs"
6959
6960         local f
6961
6962         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6963         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6964         for fail_loc in 0x80000188 0x80000189; do
6965                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6966                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6967                         error "mkdir $dir-$fail_loc failed"
6968                 for i in {0..10}; do
6969                         # create may fail on missing stripe
6970                         echo $i > $DIR/$tdir-$fail_loc/$i
6971                 done
6972                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6973                         error "getdirstripe $tdir-$fail_loc failed"
6974                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6975                         error "migrate $tdir-$fail_loc failed"
6976                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6977                         error "getdirstripe $tdir-$fail_loc failed"
6978                 pushd $DIR/$tdir-$fail_loc
6979                 for f in *; do
6980                         echo $f | cmp $f - || error "$f data mismatch"
6981                 done
6982                 popd
6983                 rm -rf $DIR/$tdir-$fail_loc
6984         done
6985 }
6986 run_test 60h "striped directory with missing stripes can be accessed"
6987
6988 test_61a() {
6989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6990
6991         f="$DIR/f61"
6992         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6993         cancel_lru_locks osc
6994         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6995         sync
6996 }
6997 run_test 61a "mmap() writes don't make sync hang ================"
6998
6999 test_61b() {
7000         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7001 }
7002 run_test 61b "mmap() of unstriped file is successful"
7003
7004 # bug 2330 - insufficient obd_match error checking causes LBUG
7005 test_62() {
7006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7007
7008         f="$DIR/f62"
7009         echo foo > $f
7010         cancel_lru_locks osc
7011         lctl set_param fail_loc=0x405
7012         cat $f && error "cat succeeded, expect -EIO"
7013         lctl set_param fail_loc=0
7014 }
7015 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7016 # match every page all of the time.
7017 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7018
7019 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7020 # Though this test is irrelevant anymore, it helped to reveal some
7021 # other grant bugs (LU-4482), let's keep it.
7022 test_63a() {   # was test_63
7023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7024
7025         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7026
7027         for i in `seq 10` ; do
7028                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7029                 sleep 5
7030                 kill $!
7031                 sleep 1
7032         done
7033
7034         rm -f $DIR/f63 || true
7035 }
7036 run_test 63a "Verify oig_wait interruption does not crash ======="
7037
7038 # bug 2248 - async write errors didn't return to application on sync
7039 # bug 3677 - async write errors left page locked
7040 test_63b() {
7041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7042
7043         debugsave
7044         lctl set_param debug=-1
7045
7046         # ensure we have a grant to do async writes
7047         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7048         rm $DIR/$tfile
7049
7050         sync    # sync lest earlier test intercept the fail_loc
7051
7052         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7053         lctl set_param fail_loc=0x80000406
7054         $MULTIOP $DIR/$tfile Owy && \
7055                 error "sync didn't return ENOMEM"
7056         sync; sleep 2; sync     # do a real sync this time to flush page
7057         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7058                 error "locked page left in cache after async error" || true
7059         debugrestore
7060 }
7061 run_test 63b "async write errors should be returned to fsync ==="
7062
7063 test_64a () {
7064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7065
7066         df $DIR
7067         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7068 }
7069 run_test 64a "verify filter grant calculations (in kernel) ====="
7070
7071 test_64b () {
7072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7073
7074         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7075 }
7076 run_test 64b "check out-of-space detection on client"
7077
7078 test_64c() {
7079         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7080 }
7081 run_test 64c "verify grant shrink"
7082
7083 # this does exactly what osc_request.c:osc_announce_cached() does in
7084 # order to calculate max amount of grants to ask from server
7085 want_grant() {
7086         local tgt=$1
7087
7088         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7089         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7090
7091         ((rpc_in_flight ++));
7092         nrpages=$((nrpages * rpc_in_flight))
7093
7094         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7095
7096         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7097
7098         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7099         local undirty=$((nrpages * PAGE_SIZE))
7100
7101         local max_extent_pages
7102         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7103             grep grant_max_extent_size | awk '{print $2}')
7104         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7105         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7106         local grant_extent_tax
7107         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7108             grep grant_extent_tax | awk '{print $2}')
7109
7110         undirty=$((undirty + nrextents * grant_extent_tax))
7111
7112         echo $undirty
7113 }
7114
7115 # this is size of unit for grant allocation. It should be equal to
7116 # what tgt_grant.c:tgt_grant_chunk() calculates
7117 grant_chunk() {
7118         local tgt=$1
7119         local max_brw_size
7120         local grant_extent_tax
7121
7122         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7123             grep max_brw_size | awk '{print $2}')
7124
7125         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7126             grep grant_extent_tax | awk '{print $2}')
7127
7128         echo $(((max_brw_size + grant_extent_tax) * 2))
7129 }
7130
7131 test_64d() {
7132         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7133                 skip "OST < 2.10.55 doesn't limit grants enough"
7134
7135         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7136         local file=$DIR/$tfile
7137
7138         [[ $($LCTL get_param osc.${tgt}.import |
7139              grep "connect_flags:.*grant_param") ]] ||
7140                 skip "no grant_param connect flag"
7141
7142         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7143
7144         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7145
7146         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7147         stack_trap "rm -f $file" EXIT
7148
7149         $LFS setstripe $file -i 0 -c 1
7150         dd if=/dev/zero of=$file bs=1M count=1000 &
7151         ddpid=$!
7152
7153         while true
7154         do
7155                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7156                 if [[ $cur_grant -gt $max_cur_granted ]]
7157                 then
7158                         kill $ddpid
7159                         error "cur_grant $cur_grant > $max_cur_granted"
7160                 fi
7161                 kill -0 $ddpid
7162                 [[ $? -ne 0 ]] && break;
7163                 sleep 2
7164         done
7165
7166         rm -f $DIR/$tfile
7167         wait_delete_completed
7168         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7169 }
7170 run_test 64d "check grant limit exceed"
7171
7172 # bug 1414 - set/get directories' stripe info
7173 test_65a() {
7174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7175
7176         test_mkdir $DIR/$tdir
7177         touch $DIR/$tdir/f1
7178         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7179 }
7180 run_test 65a "directory with no stripe info"
7181
7182 test_65b() {
7183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7184
7185         test_mkdir $DIR/$tdir
7186         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7187
7188         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7189                                                 error "setstripe"
7190         touch $DIR/$tdir/f2
7191         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7192 }
7193 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7194
7195 test_65c() {
7196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7197         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7198
7199         test_mkdir $DIR/$tdir
7200         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7201
7202         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7203                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7204         touch $DIR/$tdir/f3
7205         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7206 }
7207 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7208
7209 test_65d() {
7210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7211
7212         test_mkdir $DIR/$tdir
7213         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7214         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7215
7216         if [[ $STRIPECOUNT -le 0 ]]; then
7217                 sc=1
7218         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7219                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7220                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7221         else
7222                 sc=$(($STRIPECOUNT - 1))
7223         fi
7224         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7225         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7226         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7227                 error "lverify failed"
7228 }
7229 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7230
7231 test_65e() {
7232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7233
7234         test_mkdir $DIR/$tdir
7235
7236         $LFS setstripe $DIR/$tdir || error "setstripe"
7237         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7238                                         error "no stripe info failed"
7239         touch $DIR/$tdir/f6
7240         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7241 }
7242 run_test 65e "directory setstripe defaults"
7243
7244 test_65f() {
7245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7246
7247         test_mkdir $DIR/${tdir}f
7248         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7249                 error "setstripe succeeded" || true
7250 }
7251 run_test 65f "dir setstripe permission (should return error) ==="
7252
7253 test_65g() {
7254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7255
7256         test_mkdir $DIR/$tdir
7257         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7258
7259         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7260                 error "setstripe -S failed"
7261         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7262         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7263                 error "delete default stripe failed"
7264 }
7265 run_test 65g "directory setstripe -d"
7266
7267 test_65h() {
7268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7269
7270         test_mkdir $DIR/$tdir
7271         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7272
7273         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7274                 error "setstripe -S failed"
7275         test_mkdir $DIR/$tdir/dd1
7276         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7277                 error "stripe info inherit failed"
7278 }
7279 run_test 65h "directory stripe info inherit ===================="
7280
7281 test_65i() {
7282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7283
7284         save_layout_restore_at_exit $MOUNT
7285
7286         # bug6367: set non-default striping on root directory
7287         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7288
7289         # bug12836: getstripe on -1 default directory striping
7290         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7291
7292         # bug12836: getstripe -v on -1 default directory striping
7293         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7294
7295         # bug12836: new find on -1 default directory striping
7296         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7297 }
7298 run_test 65i "various tests to set root directory striping"
7299
7300 test_65j() { # bug6367
7301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7302
7303         sync; sleep 1
7304
7305         # if we aren't already remounting for each test, do so for this test
7306         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
7307                 cleanup || error "failed to unmount"
7308                 setup
7309         fi
7310
7311         save_layout_restore_at_exit $MOUNT
7312
7313         $LFS setstripe -d $MOUNT || error "setstripe failed"
7314 }
7315 run_test 65j "set default striping on root directory (bug 6367)="
7316
7317 cleanup_65k() {
7318         rm -rf $DIR/$tdir
7319         wait_delete_completed
7320         do_facet $SINGLEMDS "lctl set_param -n \
7321                 osp.$ost*MDT0000.max_create_count=$max_count"
7322         do_facet $SINGLEMDS "lctl set_param -n \
7323                 osp.$ost*MDT0000.create_count=$count"
7324         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7325         echo $INACTIVE_OSC "is Activate"
7326
7327         wait_osc_import_state mds ost$ostnum FULL
7328 }
7329
7330 test_65k() { # bug11679
7331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7332         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7333         remote_mds_nodsh && skip "remote MDS with nodsh"
7334
7335         local disable_precreate=true
7336         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7337                 disable_precreate=false
7338
7339         echo "Check OST status: "
7340         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7341                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7342
7343         for OSC in $MDS_OSCS; do
7344                 echo $OSC "is active"
7345                 do_facet $SINGLEMDS lctl --device %$OSC activate
7346         done
7347
7348         for INACTIVE_OSC in $MDS_OSCS; do
7349                 local ost=$(osc_to_ost $INACTIVE_OSC)
7350                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7351                                lov.*md*.target_obd |
7352                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7353
7354                 mkdir -p $DIR/$tdir
7355                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7356                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7357
7358                 echo "Deactivate: " $INACTIVE_OSC
7359                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7360
7361                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7362                               osp.$ost*MDT0000.create_count")
7363                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7364                                   osp.$ost*MDT0000.max_create_count")
7365                 $disable_precreate &&
7366                         do_facet $SINGLEMDS "lctl set_param -n \
7367                                 osp.$ost*MDT0000.max_create_count=0"
7368
7369                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7370                         [ -f $DIR/$tdir/$idx ] && continue
7371                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7372                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7373                                 { cleanup_65k;
7374                                   error "setstripe $idx should succeed"; }
7375                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7376                 done
7377                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7378                 rmdir $DIR/$tdir
7379
7380                 do_facet $SINGLEMDS "lctl set_param -n \
7381                         osp.$ost*MDT0000.max_create_count=$max_count"
7382                 do_facet $SINGLEMDS "lctl set_param -n \
7383                         osp.$ost*MDT0000.create_count=$count"
7384                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7385                 echo $INACTIVE_OSC "is Activate"
7386
7387                 wait_osc_import_state mds ost$ostnum FULL
7388         done
7389 }
7390 run_test 65k "validate manual striping works properly with deactivated OSCs"
7391
7392 test_65l() { # bug 12836
7393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7394
7395         test_mkdir -p $DIR/$tdir/test_dir
7396         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7397         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7398 }
7399 run_test 65l "lfs find on -1 stripe dir ========================"
7400
7401 test_65m() {
7402         local layout=$(save_layout $MOUNT)
7403         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7404                 restore_layout $MOUNT $layout
7405                 error "setstripe should fail by non-root users"
7406         }
7407         true
7408 }
7409 run_test 65m "normal user can't set filesystem default stripe"
7410
7411 test_65n() {
7412         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7413         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7414                 skip "Need MDS version at least 2.12.50"
7415         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7416
7417         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7418         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7419         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7420
7421         local root_layout=$(save_layout $MOUNT)
7422         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7423
7424         # new subdirectory under root directory should not inherit
7425         # the default layout from root
7426         local dir1=$MOUNT/$tdir-1
7427         mkdir $dir1 || error "mkdir $dir1 failed"
7428         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7429                 error "$dir1 shouldn't have LOV EA"
7430
7431         # delete the default layout on root directory
7432         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7433
7434         local dir2=$MOUNT/$tdir-2
7435         mkdir $dir2 || error "mkdir $dir2 failed"
7436         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7437                 error "$dir2 shouldn't have LOV EA"
7438
7439         # set a new striping pattern on root directory
7440         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7441         local new_def_stripe_size=$((def_stripe_size * 2))
7442         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7443                 error "set stripe size on $MOUNT failed"
7444
7445         # new file created in $dir2 should inherit the new stripe size from
7446         # the filesystem default
7447         local file2=$dir2/$tfile-2
7448         touch $file2 || error "touch $file2 failed"
7449
7450         local file2_stripe_size=$($LFS getstripe -S $file2)
7451         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7452                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7453
7454         local dir3=$MOUNT/$tdir-3
7455         mkdir $dir3 || error "mkdir $dir3 failed"
7456         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7457                 error "$dir3 shouldn't have LOV EA"
7458
7459         # set OST pool on root directory
7460         local pool=$TESTNAME
7461         pool_add $pool || error "add $pool failed"
7462         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7463                 error "add targets to $pool failed"
7464
7465         $LFS setstripe -p $pool $MOUNT ||
7466                 error "set OST pool on $MOUNT failed"
7467
7468         # new file created in $dir3 should inherit the pool from
7469         # the filesystem default
7470         local file3=$dir3/$tfile-3
7471         touch $file3 || error "touch $file3 failed"
7472
7473         local file3_pool=$($LFS getstripe -p $file3)
7474         [[ "$file3_pool" = "$pool" ]] ||
7475                 error "$file3 didn't inherit OST pool $pool"
7476
7477         local dir4=$MOUNT/$tdir-4
7478         mkdir $dir4 || error "mkdir $dir4 failed"
7479         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7480                 error "$dir4 shouldn't have LOV EA"
7481
7482         # new file created in $dir4 should inherit the pool from
7483         # the filesystem default
7484         local file4=$dir4/$tfile-4
7485         touch $file4 || error "touch $file4 failed"
7486
7487         local file4_pool=$($LFS getstripe -p $file4)
7488         [[ "$file4_pool" = "$pool" ]] ||
7489                 error "$file4 didn't inherit OST pool $pool"
7490
7491         # new subdirectory under non-root directory should inherit
7492         # the default layout from its parent directory
7493         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7494                 error "set directory layout on $dir4 failed"
7495
7496         local dir5=$dir4/$tdir-5
7497         mkdir $dir5 || error "mkdir $dir5 failed"
7498
7499         local dir4_layout=$(get_layout_param $dir4)
7500         local dir5_layout=$(get_layout_param $dir5)
7501         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7502                 error "$dir5 should inherit the default layout from $dir4"
7503 }
7504 run_test 65n "don't inherit default layout from root for new subdirectories"
7505
7506 # bug 2543 - update blocks count on client
7507 test_66() {
7508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7509
7510         COUNT=${COUNT:-8}
7511         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7512         sync; sync_all_data; sync; sync_all_data
7513         cancel_lru_locks osc
7514         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7515         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7516 }
7517 run_test 66 "update inode blocks count on client ==============="
7518
7519 meminfo() {
7520         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7521 }
7522
7523 swap_used() {
7524         swapon -s | awk '($1 == "'$1'") { print $4 }'
7525 }
7526
7527 # bug5265, obdfilter oa2dentry return -ENOENT
7528 # #define OBD_FAIL_SRV_ENOENT 0x217
7529 test_69() {
7530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7531         remote_ost_nodsh && skip "remote OST with nodsh"
7532
7533         f="$DIR/$tfile"
7534         $LFS setstripe -c 1 -i 0 $f
7535
7536         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7537
7538         do_facet ost1 lctl set_param fail_loc=0x217
7539         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7540         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7541
7542         do_facet ost1 lctl set_param fail_loc=0
7543         $DIRECTIO write $f 0 2 || error "write error"
7544
7545         cancel_lru_locks osc
7546         $DIRECTIO read $f 0 1 || error "read error"
7547
7548         do_facet ost1 lctl set_param fail_loc=0x217
7549         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7550
7551         do_facet ost1 lctl set_param fail_loc=0
7552         rm -f $f
7553 }
7554 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7555
7556 test_71() {
7557         test_mkdir $DIR/$tdir
7558         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7559         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7560 }
7561 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7562
7563 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7565         [ "$RUNAS_ID" = "$UID" ] &&
7566                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7567         # Check that testing environment is properly set up. Skip if not
7568         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7569                 skip_env "User $RUNAS_ID does not exist - skipping"
7570
7571         touch $DIR/$tfile
7572         chmod 777 $DIR/$tfile
7573         chmod ug+s $DIR/$tfile
7574         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7575                 error "$RUNAS dd $DIR/$tfile failed"
7576         # See if we are still setuid/sgid
7577         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7578                 error "S/gid is not dropped on write"
7579         # Now test that MDS is updated too
7580         cancel_lru_locks mdc
7581         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7582                 error "S/gid is not dropped on MDS"
7583         rm -f $DIR/$tfile
7584 }
7585 run_test 72a "Test that remove suid works properly (bug5695) ===="
7586
7587 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7588         local perm
7589
7590         [ "$RUNAS_ID" = "$UID" ] &&
7591                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7592         [ "$RUNAS_ID" -eq 0 ] &&
7593                 skip_env "RUNAS_ID = 0 -- skipping"
7594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7595         # Check that testing environment is properly set up. Skip if not
7596         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7597                 skip_env "User $RUNAS_ID does not exist - skipping"
7598
7599         touch $DIR/${tfile}-f{g,u}
7600         test_mkdir $DIR/${tfile}-dg
7601         test_mkdir $DIR/${tfile}-du
7602         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7603         chmod g+s $DIR/${tfile}-{f,d}g
7604         chmod u+s $DIR/${tfile}-{f,d}u
7605         for perm in 777 2777 4777; do
7606                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7607                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7608                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7609                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7610         done
7611         true
7612 }
7613 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7614
7615 # bug 3462 - multiple simultaneous MDC requests
7616 test_73() {
7617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7618
7619         test_mkdir $DIR/d73-1
7620         test_mkdir $DIR/d73-2
7621         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7622         pid1=$!
7623
7624         lctl set_param fail_loc=0x80000129
7625         $MULTIOP $DIR/d73-1/f73-2 Oc &
7626         sleep 1
7627         lctl set_param fail_loc=0
7628
7629         $MULTIOP $DIR/d73-2/f73-3 Oc &
7630         pid3=$!
7631
7632         kill -USR1 $pid1
7633         wait $pid1 || return 1
7634
7635         sleep 25
7636
7637         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7638         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7639         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7640
7641         rm -rf $DIR/d73-*
7642 }
7643 run_test 73 "multiple MDC requests (should not deadlock)"
7644
7645 test_74a() { # bug 6149, 6184
7646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7647
7648         touch $DIR/f74a
7649         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7650         #
7651         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7652         # will spin in a tight reconnection loop
7653         $LCTL set_param fail_loc=0x8000030e
7654         # get any lock that won't be difficult - lookup works.
7655         ls $DIR/f74a
7656         $LCTL set_param fail_loc=0
7657         rm -f $DIR/f74a
7658         true
7659 }
7660 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7661
7662 test_74b() { # bug 13310
7663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7664
7665         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7666         #
7667         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7668         # will spin in a tight reconnection loop
7669         $LCTL set_param fail_loc=0x8000030e
7670         # get a "difficult" lock
7671         touch $DIR/f74b
7672         $LCTL set_param fail_loc=0
7673         rm -f $DIR/f74b
7674         true
7675 }
7676 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7677
7678 test_74c() {
7679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7680
7681         #define OBD_FAIL_LDLM_NEW_LOCK
7682         $LCTL set_param fail_loc=0x319
7683         touch $DIR/$tfile && error "touch successful"
7684         $LCTL set_param fail_loc=0
7685         true
7686 }
7687 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7688
7689 num_inodes() {
7690         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7691 }
7692
7693 test_76() { # Now for bug 20433, added originally in bug 1443
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695
7696         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7697
7698         cancel_lru_locks osc
7699         BEFORE_INODES=$(num_inodes)
7700         echo "before inodes: $BEFORE_INODES"
7701         local COUNT=1000
7702         [ "$SLOW" = "no" ] && COUNT=100
7703         for i in $(seq $COUNT); do
7704                 touch $DIR/$tfile
7705                 rm -f $DIR/$tfile
7706         done
7707         cancel_lru_locks osc
7708         AFTER_INODES=$(num_inodes)
7709         echo "after inodes: $AFTER_INODES"
7710         local wait=0
7711         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7712                 sleep 2
7713                 AFTER_INODES=$(num_inodes)
7714                 wait=$((wait+2))
7715                 echo "wait $wait seconds inodes: $AFTER_INODES"
7716                 if [ $wait -gt 30 ]; then
7717                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7718                 fi
7719         done
7720 }
7721 run_test 76 "confirm clients recycle inodes properly ===="
7722
7723
7724 export ORIG_CSUM=""
7725 set_checksums()
7726 {
7727         # Note: in sptlrpc modes which enable its own bulk checksum, the
7728         # original crc32_le bulk checksum will be automatically disabled,
7729         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7730         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7731         # In this case set_checksums() will not be no-op, because sptlrpc
7732         # bulk checksum will be enabled all through the test.
7733
7734         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7735         lctl set_param -n osc.*.checksums $1
7736         return 0
7737 }
7738
7739 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7740                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7741 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7742                              tr -d [] | head -n1)}
7743 set_checksum_type()
7744 {
7745         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7746         log "set checksum type to $1"
7747         return 0
7748 }
7749 F77_TMP=$TMP/f77-temp
7750 F77SZ=8
7751 setup_f77() {
7752         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7753                 error "error writing to $F77_TMP"
7754 }
7755
7756 test_77a() { # bug 10889
7757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7758         $GSS && skip_env "could not run with gss"
7759
7760         [ ! -f $F77_TMP ] && setup_f77
7761         set_checksums 1
7762         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7763         set_checksums 0
7764         rm -f $DIR/$tfile
7765 }
7766 run_test 77a "normal checksum read/write operation"
7767
7768 test_77b() { # bug 10889
7769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7770         $GSS && skip_env "could not run with gss"
7771
7772         [ ! -f $F77_TMP ] && setup_f77
7773         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7774         $LCTL set_param fail_loc=0x80000409
7775         set_checksums 1
7776
7777         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7778                 error "dd error: $?"
7779         $LCTL set_param fail_loc=0
7780
7781         for algo in $CKSUM_TYPES; do
7782                 cancel_lru_locks osc
7783                 set_checksum_type $algo
7784                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7785                 $LCTL set_param fail_loc=0x80000408
7786                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7787                 $LCTL set_param fail_loc=0
7788         done
7789         set_checksums 0
7790         set_checksum_type $ORIG_CSUM_TYPE
7791         rm -f $DIR/$tfile
7792 }
7793 run_test 77b "checksum error on client write, read"
7794
7795 cleanup_77c() {
7796         trap 0
7797         set_checksums 0
7798         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7799         $check_ost &&
7800                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7801         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7802         $check_ost && [ -n "$ost_file_prefix" ] &&
7803                 do_facet ost1 rm -f ${ost_file_prefix}\*
7804 }
7805
7806 test_77c() {
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808         $GSS && skip_env "could not run with gss"
7809         remote_ost_nodsh && skip "remote OST with nodsh"
7810
7811         local bad1
7812         local osc_file_prefix
7813         local osc_file
7814         local check_ost=false
7815         local ost_file_prefix
7816         local ost_file
7817         local orig_cksum
7818         local dump_cksum
7819         local fid
7820
7821         # ensure corruption will occur on first OSS/OST
7822         $LFS setstripe -i 0 $DIR/$tfile
7823
7824         [ ! -f $F77_TMP ] && setup_f77
7825         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7826                 error "dd write error: $?"
7827         fid=$($LFS path2fid $DIR/$tfile)
7828
7829         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7830         then
7831                 check_ost=true
7832                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7833                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7834         else
7835                 echo "OSS do not support bulk pages dump upon error"
7836         fi
7837
7838         osc_file_prefix=$($LCTL get_param -n debug_path)
7839         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7840
7841         trap cleanup_77c EXIT
7842
7843         set_checksums 1
7844         # enable bulk pages dump upon error on Client
7845         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7846         # enable bulk pages dump upon error on OSS
7847         $check_ost &&
7848                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7849
7850         # flush Client cache to allow next read to reach OSS
7851         cancel_lru_locks osc
7852
7853         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7854         $LCTL set_param fail_loc=0x80000408
7855         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7856         $LCTL set_param fail_loc=0
7857
7858         rm -f $DIR/$tfile
7859
7860         # check cksum dump on Client
7861         osc_file=$(ls ${osc_file_prefix}*)
7862         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7863         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7864         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7865         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7866         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7867                      cksum)
7868         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7869         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7870                 error "dump content does not match on Client"
7871
7872         $check_ost || skip "No need to check cksum dump on OSS"
7873
7874         # check cksum dump on OSS
7875         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7876         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7877         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7878         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7879         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7880                 error "dump content does not match on OSS"
7881
7882         cleanup_77c
7883 }
7884 run_test 77c "checksum error on client read with debug"
7885
7886 test_77d() { # bug 10889
7887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7888         $GSS && skip_env "could not run with gss"
7889
7890         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7891         $LCTL set_param fail_loc=0x80000409
7892         set_checksums 1
7893         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7894                 error "direct write: rc=$?"
7895         $LCTL set_param fail_loc=0
7896         set_checksums 0
7897
7898         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7899         $LCTL set_param fail_loc=0x80000408
7900         set_checksums 1
7901         cancel_lru_locks osc
7902         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7903                 error "direct read: rc=$?"
7904         $LCTL set_param fail_loc=0
7905         set_checksums 0
7906 }
7907 run_test 77d "checksum error on OST direct write, read"
7908
7909 test_77f() { # bug 10889
7910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7911         $GSS && skip_env "could not run with gss"
7912
7913         set_checksums 1
7914         for algo in $CKSUM_TYPES; do
7915                 cancel_lru_locks osc
7916                 set_checksum_type $algo
7917                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7918                 $LCTL set_param fail_loc=0x409
7919                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7920                         error "direct write succeeded"
7921                 $LCTL set_param fail_loc=0
7922         done
7923         set_checksum_type $ORIG_CSUM_TYPE
7924         set_checksums 0
7925 }
7926 run_test 77f "repeat checksum error on write (expect error)"
7927
7928 test_77g() { # bug 10889
7929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7930         $GSS && skip_env "could not run with gss"
7931         remote_ost_nodsh && skip "remote OST with nodsh"
7932
7933         [ ! -f $F77_TMP ] && setup_f77
7934
7935         local file=$DIR/$tfile
7936         stack_trap "rm -f $file" EXIT
7937
7938         $LFS setstripe -c 1 -i 0 $file
7939         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7940         do_facet ost1 lctl set_param fail_loc=0x8000021a
7941         set_checksums 1
7942         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7943                 error "write error: rc=$?"
7944         do_facet ost1 lctl set_param fail_loc=0
7945         set_checksums 0
7946
7947         cancel_lru_locks osc
7948         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7949         do_facet ost1 lctl set_param fail_loc=0x8000021b
7950         set_checksums 1
7951         cmp $F77_TMP $file || error "file compare failed"
7952         do_facet ost1 lctl set_param fail_loc=0
7953         set_checksums 0
7954 }
7955 run_test 77g "checksum error on OST write, read"
7956
7957 test_77k() { # LU-10906
7958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7959         $GSS && skip_env "could not run with gss"
7960
7961         local cksum_param="osc.$FSNAME*.checksums"
7962         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7963         local checksum
7964         local i
7965
7966         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7967         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7968         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7969                 EXIT
7970
7971         for i in 0 1; do
7972                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7973                         error "failed to set checksum=$i on MGS"
7974                 wait_update $HOSTNAME "$get_checksum" $i
7975                 #remount
7976                 echo "remount client, checksum should be $i"
7977                 remount_client $MOUNT || "failed to remount client"
7978                 checksum=$(eval $get_checksum)
7979                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7980         done
7981         # remove persistent param to avoid races with checksum mountopt below
7982         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7983                 error "failed to delete checksum on MGS"
7984
7985         for opt in "checksum" "nochecksum"; do
7986                 #remount with mount option
7987                 echo "remount client with option $opt, checksum should be $i"
7988                 umount_client $MOUNT || "failed to umount client"
7989                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7990                         "failed to mount client with option '$opt'"
7991                 checksum=$(eval $get_checksum)
7992                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7993                 i=$((i - 1))
7994         done
7995
7996         remount_client $MOUNT || "failed to remount client"
7997 }
7998 run_test 77k "enable/disable checksum correctly"
7999
8000 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8001 rm -f $F77_TMP
8002 unset F77_TMP
8003
8004 cleanup_test_78() {
8005         trap 0
8006         rm -f $DIR/$tfile
8007 }
8008
8009 test_78() { # bug 10901
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011         remote_ost || skip_env "local OST"
8012
8013         NSEQ=5
8014         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8015         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8016         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8017         echo "MemTotal: $MEMTOTAL"
8018
8019         # reserve 256MB of memory for the kernel and other running processes,
8020         # and then take 1/2 of the remaining memory for the read/write buffers.
8021         if [ $MEMTOTAL -gt 512 ] ;then
8022                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8023         else
8024                 # for those poor memory-starved high-end clusters...
8025                 MEMTOTAL=$((MEMTOTAL / 2))
8026         fi
8027         echo "Mem to use for directio: $MEMTOTAL"
8028
8029         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8030         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8031         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8032         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8033                 head -n1)
8034         echo "Smallest OST: $SMALLESTOST"
8035         [[ $SMALLESTOST -lt 10240 ]] &&
8036                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8037
8038         trap cleanup_test_78 EXIT
8039
8040         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8041                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8042
8043         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8044         echo "File size: $F78SIZE"
8045         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8046         for i in $(seq 1 $NSEQ); do
8047                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8048                 echo directIO rdwr round $i of $NSEQ
8049                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8050         done
8051
8052         cleanup_test_78
8053 }
8054 run_test 78 "handle large O_DIRECT writes correctly ============"
8055
8056 test_79() { # bug 12743
8057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8058
8059         wait_delete_completed
8060
8061         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8062         BKFREE=$(calc_osc_kbytes kbytesfree)
8063         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8064
8065         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8066         DFTOTAL=`echo $STRING | cut -d, -f1`
8067         DFUSED=`echo $STRING  | cut -d, -f2`
8068         DFAVAIL=`echo $STRING | cut -d, -f3`
8069         DFFREE=$(($DFTOTAL - $DFUSED))
8070
8071         ALLOWANCE=$((64 * $OSTCOUNT))
8072
8073         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8074            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8075                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8076         fi
8077         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8078            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8079                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8080         fi
8081         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8082            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8083                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8084         fi
8085 }
8086 run_test 79 "df report consistency check ======================="
8087
8088 test_80() { # bug 10718
8089         remote_ost_nodsh && skip "remote OST with nodsh"
8090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8091
8092         # relax strong synchronous semantics for slow backends like ZFS
8093         local soc="obdfilter.*.sync_on_lock_cancel"
8094         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8095         local hosts=
8096         if [ "$soc_old" != "never" ] &&
8097                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8098                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8099                                 facet_active_host $host; done | sort -u)
8100                         do_nodes $hosts lctl set_param $soc=never
8101         fi
8102
8103         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8104         sync; sleep 1; sync
8105         local BEFORE=`date +%s`
8106         cancel_lru_locks osc
8107         local AFTER=`date +%s`
8108         local DIFF=$((AFTER-BEFORE))
8109         if [ $DIFF -gt 1 ] ; then
8110                 error "elapsed for 1M@1T = $DIFF"
8111         fi
8112
8113         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8114
8115         rm -f $DIR/$tfile
8116 }
8117 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8118
8119 test_81a() { # LU-456
8120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8121         remote_ost_nodsh && skip "remote OST with nodsh"
8122
8123         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8124         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8125         do_facet ost1 lctl set_param fail_loc=0x80000228
8126
8127         # write should trigger a retry and success
8128         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8129         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8130         RC=$?
8131         if [ $RC -ne 0 ] ; then
8132                 error "write should success, but failed for $RC"
8133         fi
8134 }
8135 run_test 81a "OST should retry write when get -ENOSPC ==============="
8136
8137 test_81b() { # LU-456
8138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8139         remote_ost_nodsh && skip "remote OST with nodsh"
8140
8141         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8142         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8143         do_facet ost1 lctl set_param fail_loc=0x228
8144
8145         # write should retry several times and return -ENOSPC finally
8146         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8147         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8148         RC=$?
8149         ENOSPC=28
8150         if [ $RC -ne $ENOSPC ] ; then
8151                 error "dd should fail for -ENOSPC, but succeed."
8152         fi
8153 }
8154 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8155
8156 test_82() { # LU-1031
8157         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8158         local gid1=14091995
8159         local gid2=16022000
8160
8161         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8162         local MULTIPID1=$!
8163         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8164         local MULTIPID2=$!
8165         kill -USR1 $MULTIPID2
8166         sleep 2
8167         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8168                 error "First grouplock does not block second one"
8169         else
8170                 echo "Second grouplock blocks first one"
8171         fi
8172         kill -USR1 $MULTIPID1
8173         wait $MULTIPID1
8174         wait $MULTIPID2
8175 }
8176 run_test 82 "Basic grouplock test"
8177
8178 test_99() {
8179         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8180
8181         test_mkdir $DIR/$tdir.cvsroot
8182         chown $RUNAS_ID $DIR/$tdir.cvsroot
8183
8184         cd $TMP
8185         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8186
8187         cd /etc/init.d
8188         # some versions of cvs import exit(1) when asked to import links or
8189         # files they can't read.  ignore those files.
8190         local toignore=$(find . -type l -printf '-I %f\n' -o \
8191                          ! -perm /4 -printf '-I %f\n')
8192         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8193                 $tdir.reposname vtag rtag
8194
8195         cd $DIR
8196         test_mkdir $DIR/$tdir.reposname
8197         chown $RUNAS_ID $DIR/$tdir.reposname
8198         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8199
8200         cd $DIR/$tdir.reposname
8201         $RUNAS touch foo99
8202         $RUNAS cvs add -m 'addmsg' foo99
8203         $RUNAS cvs update
8204         $RUNAS cvs commit -m 'nomsg' foo99
8205         rm -fr $DIR/$tdir.cvsroot
8206 }
8207 run_test 99 "cvs strange file/directory operations"
8208
8209 test_100() {
8210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8211         [[ "$NETTYPE" =~ tcp ]] ||
8212                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8213         remote_ost_nodsh && skip "remote OST with nodsh"
8214         remote_mds_nodsh && skip "remote MDS with nodsh"
8215         remote_servers ||
8216                 skip "useless for local single node setup"
8217
8218         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8219                 [ "$PROT" != "tcp" ] && continue
8220                 RPORT=$(echo $REMOTE | cut -d: -f2)
8221                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8222
8223                 rc=0
8224                 LPORT=`echo $LOCAL | cut -d: -f2`
8225                 if [ $LPORT -ge 1024 ]; then
8226                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8227                         netstat -tna
8228                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8229                 fi
8230         done
8231         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8232 }
8233 run_test 100 "check local port using privileged port ==========="
8234
8235 function get_named_value()
8236 {
8237     local tag
8238
8239     tag=$1
8240     while read ;do
8241         line=$REPLY
8242         case $line in
8243         $tag*)
8244             echo $line | sed "s/^$tag[ ]*//"
8245             break
8246             ;;
8247         esac
8248     done
8249 }
8250
8251 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8252                    awk '/^max_cached_mb/ { print $2 }')
8253
8254 cleanup_101a() {
8255         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8256         trap 0
8257 }
8258
8259 test_101a() {
8260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8261         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8262
8263         local s
8264         local discard
8265         local nreads=10000
8266         local cache_limit=32
8267
8268         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8269         trap cleanup_101a EXIT
8270         $LCTL set_param -n llite.*.read_ahead_stats 0
8271         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8272
8273         #
8274         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8275         #
8276         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8277         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8278
8279         discard=0
8280         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8281                 get_named_value 'read but discarded' | cut -d" " -f1); do
8282                         discard=$(($discard + $s))
8283         done
8284         cleanup_101a
8285
8286         if [[ $(($discard * 10)) -gt $nreads ]]; then
8287                 $LCTL get_param osc.*-osc*.rpc_stats
8288                 $LCTL get_param llite.*.read_ahead_stats
8289                 error "too many ($discard) discarded pages"
8290         fi
8291         rm -f $DIR/$tfile || true
8292 }
8293 run_test 101a "check read-ahead for random reads"
8294
8295 setup_test101bc() {
8296         test_mkdir $DIR/$tdir
8297         local ssize=$1
8298         local FILE_LENGTH=$2
8299         STRIPE_OFFSET=0
8300
8301         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8302
8303         local list=$(comma_list $(osts_nodes))
8304         set_osd_param $list '' read_cache_enable 0
8305         set_osd_param $list '' writethrough_cache_enable 0
8306
8307         trap cleanup_test101bc EXIT
8308         # prepare the read-ahead file
8309         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8310
8311         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8312                                 count=$FILE_SIZE_MB 2> /dev/null
8313
8314 }
8315
8316 cleanup_test101bc() {
8317         trap 0
8318         rm -rf $DIR/$tdir
8319         rm -f $DIR/$tfile
8320
8321         local list=$(comma_list $(osts_nodes))
8322         set_osd_param $list '' read_cache_enable 1
8323         set_osd_param $list '' writethrough_cache_enable 1
8324 }
8325
8326 calc_total() {
8327         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8328 }
8329
8330 ra_check_101() {
8331         local READ_SIZE=$1
8332         local STRIPE_SIZE=$2
8333         local FILE_LENGTH=$3
8334         local RA_INC=1048576
8335         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8336         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8337                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8338         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8339                         get_named_value 'read but discarded' |
8340                         cut -d" " -f1 | calc_total)
8341         if [[ $DISCARD -gt $discard_limit ]]; then
8342                 $LCTL get_param llite.*.read_ahead_stats
8343                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8344         else
8345                 echo "Read-ahead success for size ${READ_SIZE}"
8346         fi
8347 }
8348
8349 test_101b() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8352
8353         local STRIPE_SIZE=1048576
8354         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8355
8356         if [ $SLOW == "yes" ]; then
8357                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8358         else
8359                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8360         fi
8361
8362         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8363
8364         # prepare the read-ahead file
8365         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8366         cancel_lru_locks osc
8367         for BIDX in 2 4 8 16 32 64 128 256
8368         do
8369                 local BSIZE=$((BIDX*4096))
8370                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8371                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8372                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8373                 $LCTL set_param -n llite.*.read_ahead_stats 0
8374                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8375                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8376                 cancel_lru_locks osc
8377                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8378         done
8379         cleanup_test101bc
8380         true
8381 }
8382 run_test 101b "check stride-io mode read-ahead ================="
8383
8384 test_101c() {
8385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8386
8387         local STRIPE_SIZE=1048576
8388         local FILE_LENGTH=$((STRIPE_SIZE*100))
8389         local nreads=10000
8390         local rsize=65536
8391         local osc_rpc_stats
8392
8393         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8394
8395         cancel_lru_locks osc
8396         $LCTL set_param osc.*.rpc_stats 0
8397         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8398         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8399                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8400                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8401                 local size
8402
8403                 if [ $lines -le 20 ]; then
8404                         continue
8405                 fi
8406                 for size in 1 2 4 8; do
8407                         local rpc=$(echo "$stats" |
8408                                     awk '($1 == "'$size':") {print $2; exit; }')
8409                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8410                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8411                 done
8412                 echo "$osc_rpc_stats check passed!"
8413         done
8414         cleanup_test101bc
8415         true
8416 }
8417 run_test 101c "check stripe_size aligned read-ahead ================="
8418
8419 set_read_ahead() {
8420         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8421         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8422 }
8423
8424 test_101d() {
8425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8426
8427         local file=$DIR/$tfile
8428         local sz_MB=${FILESIZE_101d:-500}
8429         local ra_MB=${READAHEAD_MB:-40}
8430
8431         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8432         [ $free_MB -lt $sz_MB ] &&
8433                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8434
8435         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8436         $LFS setstripe -c -1 $file || error "setstripe failed"
8437
8438         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8439         echo Cancel LRU locks on lustre client to flush the client cache
8440         cancel_lru_locks osc
8441
8442         echo Disable read-ahead
8443         local old_READAHEAD=$(set_read_ahead 0)
8444
8445         echo Reading the test file $file with read-ahead disabled
8446         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8447
8448         echo Cancel LRU locks on lustre client to flush the client cache
8449         cancel_lru_locks osc
8450         echo Enable read-ahead with ${ra_MB}MB
8451         set_read_ahead $ra_MB
8452
8453         echo Reading the test file $file with read-ahead enabled
8454         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8455
8456         echo "read-ahead disabled time read $raOFF"
8457         echo "read-ahead enabled  time read $raON"
8458
8459         set_read_ahead $old_READAHEAD
8460         rm -f $file
8461         wait_delete_completed
8462
8463         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8464                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8465 }
8466 run_test 101d "file read with and without read-ahead enabled"
8467
8468 test_101e() {
8469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8470
8471         local file=$DIR/$tfile
8472         local size_KB=500  #KB
8473         local count=100
8474         local bsize=1024
8475
8476         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8477         local need_KB=$((count * size_KB))
8478         [[ $free_KB -le $need_KB ]] &&
8479                 skip_env "Need free space $need_KB, have $free_KB"
8480
8481         echo "Creating $count ${size_KB}K test files"
8482         for ((i = 0; i < $count; i++)); do
8483                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8484         done
8485
8486         echo "Cancel LRU locks on lustre client to flush the client cache"
8487         cancel_lru_locks $OSC
8488
8489         echo "Reset readahead stats"
8490         $LCTL set_param -n llite.*.read_ahead_stats 0
8491
8492         for ((i = 0; i < $count; i++)); do
8493                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8494         done
8495
8496         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8497                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8498
8499         for ((i = 0; i < $count; i++)); do
8500                 rm -rf $file.$i 2>/dev/null
8501         done
8502
8503         #10000 means 20% reads are missing in readahead
8504         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8505 }
8506 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8507
8508 test_101f() {
8509         which iozone || skip_env "no iozone installed"
8510
8511         local old_debug=$($LCTL get_param debug)
8512         old_debug=${old_debug#*=}
8513         $LCTL set_param debug="reada mmap"
8514
8515         # create a test file
8516         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8517
8518         echo Cancel LRU locks on lustre client to flush the client cache
8519         cancel_lru_locks osc
8520
8521         echo Reset readahead stats
8522         $LCTL set_param -n llite.*.read_ahead_stats 0
8523
8524         echo mmap read the file with small block size
8525         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8526                 > /dev/null 2>&1
8527
8528         echo checking missing pages
8529         $LCTL get_param llite.*.read_ahead_stats
8530         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8531                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8532
8533         $LCTL set_param debug="$old_debug"
8534         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8535         rm -f $DIR/$tfile
8536 }
8537 run_test 101f "check mmap read performance"
8538
8539 test_101g_brw_size_test() {
8540         local mb=$1
8541         local pages=$((mb * 1048576 / PAGE_SIZE))
8542         local file=$DIR/$tfile
8543
8544         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8545                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8546         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8547                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8548                         return 2
8549         done
8550
8551         stack_trap "rm -f $file" EXIT
8552         $LCTL set_param -n osc.*.rpc_stats=0
8553
8554         # 10 RPCs should be enough for the test
8555         local count=10
8556         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8557                 { error "dd write ${mb} MB blocks failed"; return 3; }
8558         cancel_lru_locks osc
8559         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8560                 { error "dd write ${mb} MB blocks failed"; return 4; }
8561
8562         # calculate number of full-sized read and write RPCs
8563         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8564                 sed -n '/pages per rpc/,/^$/p' |
8565                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8566                 END { print reads,writes }'))
8567         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8568                 return 5
8569         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8570                 return 6
8571
8572         return 0
8573 }
8574
8575 test_101g() {
8576         remote_ost_nodsh && skip "remote OST with nodsh"
8577
8578         local rpcs
8579         local osts=$(get_facets OST)
8580         local list=$(comma_list $(osts_nodes))
8581         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8582         local brw_size="obdfilter.*.brw_size"
8583
8584         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8585
8586         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8587
8588         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8589                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8590                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8591            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8592                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8593                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8594
8595                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8596                         suffix="M"
8597
8598                 if [[ $orig_mb -lt 16 ]]; then
8599                         save_lustre_params $osts "$brw_size" > $p
8600                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8601                                 error "set 16MB RPC size failed"
8602
8603                         echo "remount client to enable new RPC size"
8604                         remount_client $MOUNT || error "remount_client failed"
8605                 fi
8606
8607                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8608                 # should be able to set brw_size=12, but no rpc_stats for that
8609                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8610         fi
8611
8612         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8613
8614         if [[ $orig_mb -lt 16 ]]; then
8615                 restore_lustre_params < $p
8616                 remount_client $MOUNT || error "remount_client restore failed"
8617         fi
8618
8619         rm -f $p $DIR/$tfile
8620 }
8621 run_test 101g "Big bulk(4/16 MiB) readahead"
8622
8623 setup_test102() {
8624         test_mkdir $DIR/$tdir
8625         chown $RUNAS_ID $DIR/$tdir
8626         STRIPE_SIZE=65536
8627         STRIPE_OFFSET=1
8628         STRIPE_COUNT=$OSTCOUNT
8629         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8630
8631         trap cleanup_test102 EXIT
8632         cd $DIR
8633         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8634         cd $DIR/$tdir
8635         for num in 1 2 3 4; do
8636                 for count in $(seq 1 $STRIPE_COUNT); do
8637                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8638                                 local size=`expr $STRIPE_SIZE \* $num`
8639                                 local file=file"$num-$idx-$count"
8640                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8641                         done
8642                 done
8643         done
8644
8645         cd $DIR
8646         $1 tar cf $TMP/f102.tar $tdir --xattrs
8647 }
8648
8649 cleanup_test102() {
8650         trap 0
8651         rm -f $TMP/f102.tar
8652         rm -rf $DIR/d0.sanity/d102
8653 }
8654
8655 test_102a() {
8656         [ "$UID" != 0 ] && skip "must run as root"
8657         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8658                 skip_env "must have user_xattr"
8659
8660         [ -z "$(which setfattr 2>/dev/null)" ] &&
8661                 skip_env "could not find setfattr"
8662
8663         local testfile=$DIR/$tfile
8664
8665         touch $testfile
8666         echo "set/get xattr..."
8667         setfattr -n trusted.name1 -v value1 $testfile ||
8668                 error "setfattr -n trusted.name1=value1 $testfile failed"
8669         getfattr -n trusted.name1 $testfile 2> /dev/null |
8670           grep "trusted.name1=.value1" ||
8671                 error "$testfile missing trusted.name1=value1"
8672
8673         setfattr -n user.author1 -v author1 $testfile ||
8674                 error "setfattr -n user.author1=author1 $testfile failed"
8675         getfattr -n user.author1 $testfile 2> /dev/null |
8676           grep "user.author1=.author1" ||
8677                 error "$testfile missing trusted.author1=author1"
8678
8679         echo "listxattr..."
8680         setfattr -n trusted.name2 -v value2 $testfile ||
8681                 error "$testfile unable to set trusted.name2"
8682         setfattr -n trusted.name3 -v value3 $testfile ||
8683                 error "$testfile unable to set trusted.name3"
8684         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8685             grep "trusted.name" | wc -l) -eq 3 ] ||
8686                 error "$testfile missing 3 trusted.name xattrs"
8687
8688         setfattr -n user.author2 -v author2 $testfile ||
8689                 error "$testfile unable to set user.author2"
8690         setfattr -n user.author3 -v author3 $testfile ||
8691                 error "$testfile unable to set user.author3"
8692         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8693             grep "user.author" | wc -l) -eq 3 ] ||
8694                 error "$testfile missing 3 user.author xattrs"
8695
8696         echo "remove xattr..."
8697         setfattr -x trusted.name1 $testfile ||
8698                 error "$testfile error deleting trusted.name1"
8699         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8700                 error "$testfile did not delete trusted.name1 xattr"
8701
8702         setfattr -x user.author1 $testfile ||
8703                 error "$testfile error deleting user.author1"
8704         echo "set lustre special xattr ..."
8705         $LFS setstripe -c1 $testfile
8706         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8707                 awk -F "=" '/trusted.lov/ { print $2 }' )
8708         setfattr -n "trusted.lov" -v $lovea $testfile ||
8709                 error "$testfile doesn't ignore setting trusted.lov again"
8710         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8711                 error "$testfile allow setting invalid trusted.lov"
8712         rm -f $testfile
8713 }
8714 run_test 102a "user xattr test =================================="
8715
8716 test_102b() {
8717         [ -z "$(which setfattr 2>/dev/null)" ] &&
8718                 skip_env "could not find setfattr"
8719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8720
8721         # b10930: get/set/list trusted.lov xattr
8722         echo "get/set/list trusted.lov xattr ..."
8723         local testfile=$DIR/$tfile
8724         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8725                 error "setstripe failed"
8726         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8727                 error "getstripe failed"
8728         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8729                 error "can't get trusted.lov from $testfile"
8730
8731         local testfile2=${testfile}2
8732         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8733                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8734
8735         $MCREATE $testfile2
8736         setfattr -n trusted.lov -v $value $testfile2
8737         local stripe_size=$($LFS getstripe -S $testfile2)
8738         local stripe_count=$($LFS getstripe -c $testfile2)
8739         [[ $stripe_size -eq 65536 ]] ||
8740                 error "stripe size $stripe_size != 65536"
8741         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8742                 error "stripe count $stripe_count != $STRIPECOUNT"
8743         rm -f $DIR/$tfile
8744 }
8745 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8746
8747 test_102c() {
8748         [ -z "$(which setfattr 2>/dev/null)" ] &&
8749                 skip_env "could not find setfattr"
8750         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8751
8752         # b10930: get/set/list lustre.lov xattr
8753         echo "get/set/list lustre.lov xattr ..."
8754         test_mkdir $DIR/$tdir
8755         chown $RUNAS_ID $DIR/$tdir
8756         local testfile=$DIR/$tdir/$tfile
8757         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8758                 error "setstripe failed"
8759         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8760                 error "getstripe failed"
8761         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8762         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8763
8764         local testfile2=${testfile}2
8765         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8766                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8767
8768         $RUNAS $MCREATE $testfile2
8769         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8770         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8771         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8772         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8773         [ $stripe_count -eq $STRIPECOUNT ] ||
8774                 error "stripe count $stripe_count != $STRIPECOUNT"
8775 }
8776 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8777
8778 compare_stripe_info1() {
8779         local stripe_index_all_zero=true
8780
8781         for num in 1 2 3 4; do
8782                 for count in $(seq 1 $STRIPE_COUNT); do
8783                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8784                                 local size=$((STRIPE_SIZE * num))
8785                                 local file=file"$num-$offset-$count"
8786                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8787                                 [[ $stripe_size -ne $size ]] &&
8788                                     error "$file: size $stripe_size != $size"
8789                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8790                                 # allow fewer stripes to be created, ORI-601
8791                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8792                                     error "$file: count $stripe_count != $count"
8793                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8794                                 [[ $stripe_index -ne 0 ]] &&
8795                                         stripe_index_all_zero=false
8796                         done
8797                 done
8798         done
8799         $stripe_index_all_zero &&
8800                 error "all files are being extracted starting from OST index 0"
8801         return 0
8802 }
8803
8804 have_xattrs_include() {
8805         tar --help | grep -q xattrs-include &&
8806                 echo --xattrs-include="lustre.*"
8807 }
8808
8809 test_102d() {
8810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8811         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8812
8813         XINC=$(have_xattrs_include)
8814         setup_test102
8815         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8816         cd $DIR/$tdir/$tdir
8817         compare_stripe_info1
8818 }
8819 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8820
8821 test_102f() {
8822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8823         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8824
8825         XINC=$(have_xattrs_include)
8826         setup_test102
8827         test_mkdir $DIR/$tdir.restore
8828         cd $DIR
8829         tar cf - --xattrs $tdir | tar xf - \
8830                 -C $DIR/$tdir.restore --xattrs $XINC
8831         cd $DIR/$tdir.restore/$tdir
8832         compare_stripe_info1
8833 }
8834 run_test 102f "tar copy files, not keep osts"
8835
8836 grow_xattr() {
8837         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8838                 skip "must have user_xattr"
8839         [ -z "$(which setfattr 2>/dev/null)" ] &&
8840                 skip_env "could not find setfattr"
8841         [ -z "$(which getfattr 2>/dev/null)" ] &&
8842                 skip_env "could not find getfattr"
8843
8844         local xsize=${1:-1024}  # in bytes
8845         local file=$DIR/$tfile
8846         local value="$(generate_string $xsize)"
8847         local xbig=trusted.big
8848         local toobig=$2
8849
8850         touch $file
8851         log "save $xbig on $file"
8852         if [ -z "$toobig" ]
8853         then
8854                 setfattr -n $xbig -v $value $file ||
8855                         error "saving $xbig on $file failed"
8856         else
8857                 setfattr -n $xbig -v $value $file &&
8858                         error "saving $xbig on $file succeeded"
8859                 return 0
8860         fi
8861
8862         local orig=$(get_xattr_value $xbig $file)
8863         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8864
8865         local xsml=trusted.sml
8866         log "save $xsml on $file"
8867         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8868
8869         local new=$(get_xattr_value $xbig $file)
8870         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8871
8872         log "grow $xsml on $file"
8873         setfattr -n $xsml -v "$value" $file ||
8874                 error "growing $xsml on $file failed"
8875
8876         new=$(get_xattr_value $xbig $file)
8877         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8878         log "$xbig still valid after growing $xsml"
8879
8880         rm -f $file
8881 }
8882
8883 test_102h() { # bug 15777
8884         grow_xattr 1024
8885 }
8886 run_test 102h "grow xattr from inside inode to external block"
8887
8888 test_102ha() {
8889         large_xattr_enabled || skip_env "ea_inode feature disabled"
8890
8891         echo "setting xattr of max xattr size: $(max_xattr_size)"
8892         grow_xattr $(max_xattr_size)
8893
8894         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8895         echo "This should fail:"
8896         grow_xattr $(($(max_xattr_size) + 10)) 1
8897 }
8898 run_test 102ha "grow xattr from inside inode to external inode"
8899
8900 test_102i() { # bug 17038
8901         [ -z "$(which getfattr 2>/dev/null)" ] &&
8902                 skip "could not find getfattr"
8903
8904         touch $DIR/$tfile
8905         ln -s $DIR/$tfile $DIR/${tfile}link
8906         getfattr -n trusted.lov $DIR/$tfile ||
8907                 error "lgetxattr on $DIR/$tfile failed"
8908         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8909                 grep -i "no such attr" ||
8910                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8911         rm -f $DIR/$tfile $DIR/${tfile}link
8912 }
8913 run_test 102i "lgetxattr test on symbolic link ============"
8914
8915 test_102j() {
8916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8918
8919         XINC=$(have_xattrs_include)
8920         setup_test102 "$RUNAS"
8921         chown $RUNAS_ID $DIR/$tdir
8922         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8923         cd $DIR/$tdir/$tdir
8924         compare_stripe_info1 "$RUNAS"
8925 }
8926 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8927
8928 test_102k() {
8929         [ -z "$(which setfattr 2>/dev/null)" ] &&
8930                 skip "could not find setfattr"
8931
8932         touch $DIR/$tfile
8933         # b22187 just check that does not crash for regular file.
8934         setfattr -n trusted.lov $DIR/$tfile
8935         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8936         local test_kdir=$DIR/$tdir
8937         test_mkdir $test_kdir
8938         local default_size=$($LFS getstripe -S $test_kdir)
8939         local default_count=$($LFS getstripe -c $test_kdir)
8940         local default_offset=$($LFS getstripe -i $test_kdir)
8941         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8942                 error 'dir setstripe failed'
8943         setfattr -n trusted.lov $test_kdir
8944         local stripe_size=$($LFS getstripe -S $test_kdir)
8945         local stripe_count=$($LFS getstripe -c $test_kdir)
8946         local stripe_offset=$($LFS getstripe -i $test_kdir)
8947         [ $stripe_size -eq $default_size ] ||
8948                 error "stripe size $stripe_size != $default_size"
8949         [ $stripe_count -eq $default_count ] ||
8950                 error "stripe count $stripe_count != $default_count"
8951         [ $stripe_offset -eq $default_offset ] ||
8952                 error "stripe offset $stripe_offset != $default_offset"
8953         rm -rf $DIR/$tfile $test_kdir
8954 }
8955 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8956
8957 test_102l() {
8958         [ -z "$(which getfattr 2>/dev/null)" ] &&
8959                 skip "could not find getfattr"
8960
8961         # LU-532 trusted. xattr is invisible to non-root
8962         local testfile=$DIR/$tfile
8963
8964         touch $testfile
8965
8966         echo "listxattr as user..."
8967         chown $RUNAS_ID $testfile
8968         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8969             grep -q "trusted" &&
8970                 error "$testfile trusted xattrs are user visible"
8971
8972         return 0;
8973 }
8974 run_test 102l "listxattr size test =================================="
8975
8976 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8977         local path=$DIR/$tfile
8978         touch $path
8979
8980         listxattr_size_check $path || error "listattr_size_check $path failed"
8981 }
8982 run_test 102m "Ensure listxattr fails on small bufffer ========"
8983
8984 cleanup_test102
8985
8986 getxattr() { # getxattr path name
8987         # Return the base64 encoding of the value of xattr name on path.
8988         local path=$1
8989         local name=$2
8990
8991         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8992         # file: $path
8993         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8994         #
8995         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8996
8997         getfattr --absolute-names --encoding=base64 --name=$name $path |
8998                 awk -F= -v name=$name '$1 == name {
8999                         print substr($0, index($0, "=") + 1);
9000         }'
9001 }
9002
9003 test_102n() { # LU-4101 mdt: protect internal xattrs
9004         [ -z "$(which setfattr 2>/dev/null)" ] &&
9005                 skip "could not find setfattr"
9006         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9007         then
9008                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9009         fi
9010
9011         local file0=$DIR/$tfile.0
9012         local file1=$DIR/$tfile.1
9013         local xattr0=$TMP/$tfile.0
9014         local xattr1=$TMP/$tfile.1
9015         local namelist="lov lma lmv link fid version som hsm"
9016         local name
9017         local value
9018
9019         rm -rf $file0 $file1 $xattr0 $xattr1
9020         touch $file0 $file1
9021
9022         # Get 'before' xattrs of $file1.
9023         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9024
9025         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9026                 namelist+=" lfsck_namespace"
9027         for name in $namelist; do
9028                 # Try to copy xattr from $file0 to $file1.
9029                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9030
9031                 setfattr --name=trusted.$name --value="$value" $file1 ||
9032                         error "setxattr 'trusted.$name' failed"
9033
9034                 # Try to set a garbage xattr.
9035                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9036
9037                 if [[ x$name == "xlov" ]]; then
9038                         setfattr --name=trusted.lov --value="$value" $file1 &&
9039                         error "setxattr invalid 'trusted.lov' success"
9040                 else
9041                         setfattr --name=trusted.$name --value="$value" $file1 ||
9042                                 error "setxattr invalid 'trusted.$name' failed"
9043                 fi
9044
9045                 # Try to remove the xattr from $file1. We don't care if this
9046                 # appears to succeed or fail, we just don't want there to be
9047                 # any changes or crashes.
9048                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9049         done
9050
9051         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9052         then
9053                 name="lfsck_ns"
9054                 # Try to copy xattr from $file0 to $file1.
9055                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9056
9057                 setfattr --name=trusted.$name --value="$value" $file1 ||
9058                         error "setxattr 'trusted.$name' failed"
9059
9060                 # Try to set a garbage xattr.
9061                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9062
9063                 setfattr --name=trusted.$name --value="$value" $file1 ||
9064                         error "setxattr 'trusted.$name' failed"
9065
9066                 # Try to remove the xattr from $file1. We don't care if this
9067                 # appears to succeed or fail, we just don't want there to be
9068                 # any changes or crashes.
9069                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9070         fi
9071
9072         # Get 'after' xattrs of file1.
9073         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9074
9075         if ! diff $xattr0 $xattr1; then
9076                 error "before and after xattrs of '$file1' differ"
9077         fi
9078
9079         rm -rf $file0 $file1 $xattr0 $xattr1
9080
9081         return 0
9082 }
9083 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9084
9085 test_102p() { # LU-4703 setxattr did not check ownership
9086         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9087                 skip "MDS needs to be at least 2.5.56"
9088
9089         local testfile=$DIR/$tfile
9090
9091         touch $testfile
9092
9093         echo "setfacl as user..."
9094         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9095         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9096
9097         echo "setfattr as user..."
9098         setfacl -m "u:$RUNAS_ID:---" $testfile
9099         $RUNAS setfattr -x system.posix_acl_access $testfile
9100         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9101 }
9102 run_test 102p "check setxattr(2) correctly fails without permission"
9103
9104 test_102q() {
9105         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9106                 skip "MDS needs to be at least 2.6.92"
9107
9108         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9109 }
9110 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9111
9112 test_102r() {
9113         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9114                 skip "MDS needs to be at least 2.6.93"
9115
9116         touch $DIR/$tfile || error "touch"
9117         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9118         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9119         rm $DIR/$tfile || error "rm"
9120
9121         #normal directory
9122         mkdir -p $DIR/$tdir || error "mkdir"
9123         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9124         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9125         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9126                 error "$testfile error deleting user.author1"
9127         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9128                 grep "user.$(basename $tdir)" &&
9129                 error "$tdir did not delete user.$(basename $tdir)"
9130         rmdir $DIR/$tdir || error "rmdir"
9131
9132         #striped directory
9133         test_mkdir $DIR/$tdir
9134         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9135         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9136         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9137                 error "$testfile error deleting user.author1"
9138         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9139                 grep "user.$(basename $tdir)" &&
9140                 error "$tdir did not delete user.$(basename $tdir)"
9141         rmdir $DIR/$tdir || error "rm striped dir"
9142 }
9143 run_test 102r "set EAs with empty values"
9144
9145 test_102s() {
9146         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9147                 skip "MDS needs to be at least 2.11.52"
9148
9149         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9150
9151         save_lustre_params client "llite.*.xattr_cache" > $save
9152
9153         for cache in 0 1; do
9154                 lctl set_param llite.*.xattr_cache=$cache
9155
9156                 rm -f $DIR/$tfile
9157                 touch $DIR/$tfile || error "touch"
9158                 for prefix in lustre security system trusted user; do
9159                         # Note getxattr() may fail with 'Operation not
9160                         # supported' or 'No such attribute' depending
9161                         # on prefix and cache.
9162                         getfattr -n $prefix.n102s $DIR/$tfile &&
9163                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9164                 done
9165         done
9166
9167         restore_lustre_params < $save
9168 }
9169 run_test 102s "getting nonexistent xattrs should fail"
9170
9171 test_102t() {
9172         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9173                 skip "MDS needs to be at least 2.11.52"
9174
9175         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9176
9177         save_lustre_params client "llite.*.xattr_cache" > $save
9178
9179         for cache in 0 1; do
9180                 lctl set_param llite.*.xattr_cache=$cache
9181
9182                 for buf_size in 0 256; do
9183                         rm -f $DIR/$tfile
9184                         touch $DIR/$tfile || error "touch"
9185                         setfattr -n user.multiop $DIR/$tfile
9186                         $MULTIOP $DIR/$tfile oa$buf_size ||
9187                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9188                 done
9189         done
9190
9191         restore_lustre_params < $save
9192 }
9193 run_test 102t "zero length xattr values handled correctly"
9194
9195 run_acl_subtest()
9196 {
9197     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9198     return $?
9199 }
9200
9201 test_103a() {
9202         [ "$UID" != 0 ] && skip "must run as root"
9203         $GSS && skip_env "could not run under gss"
9204         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9205                 skip_env "must have acl enabled"
9206         [ -z "$(which setfacl 2>/dev/null)" ] &&
9207                 skip_env "could not find setfacl"
9208         remote_mds_nodsh && skip "remote MDS with nodsh"
9209
9210         gpasswd -a daemon bin                           # LU-5641
9211         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9212
9213         declare -a identity_old
9214
9215         for num in $(seq $MDSCOUNT); do
9216                 switch_identity $num true || identity_old[$num]=$?
9217         done
9218
9219         SAVE_UMASK=$(umask)
9220         umask 0022
9221         mkdir -p $DIR/$tdir
9222         cd $DIR/$tdir
9223
9224         echo "performing cp ..."
9225         run_acl_subtest cp || error "run_acl_subtest cp failed"
9226         echo "performing getfacl-noacl..."
9227         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9228         echo "performing misc..."
9229         run_acl_subtest misc || error  "misc test failed"
9230         echo "performing permissions..."
9231         run_acl_subtest permissions || error "permissions failed"
9232         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9233         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9234                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9235                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9236         then
9237                 echo "performing permissions xattr..."
9238                 run_acl_subtest permissions_xattr ||
9239                         error "permissions_xattr failed"
9240         fi
9241         echo "performing setfacl..."
9242         run_acl_subtest setfacl || error  "setfacl test failed"
9243
9244         # inheritance test got from HP
9245         echo "performing inheritance..."
9246         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9247         chmod +x make-tree || error "chmod +x failed"
9248         run_acl_subtest inheritance || error "inheritance test failed"
9249         rm -f make-tree
9250
9251         echo "LU-974 ignore umask when acl is enabled..."
9252         run_acl_subtest 974 || error "LU-974 umask test failed"
9253         if [ $MDSCOUNT -ge 2 ]; then
9254                 run_acl_subtest 974_remote ||
9255                         error "LU-974 umask test failed under remote dir"
9256         fi
9257
9258         echo "LU-2561 newly created file is same size as directory..."
9259         if [ "$mds1_FSTYPE" != "zfs" ]; then
9260                 run_acl_subtest 2561 || error "LU-2561 test failed"
9261         else
9262                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9263         fi
9264
9265         run_acl_subtest 4924 || error "LU-4924 test failed"
9266
9267         cd $SAVE_PWD
9268         umask $SAVE_UMASK
9269
9270         for num in $(seq $MDSCOUNT); do
9271                 if [ "${identity_old[$num]}" = 1 ]; then
9272                         switch_identity $num false || identity_old[$num]=$?
9273                 fi
9274         done
9275 }
9276 run_test 103a "acl test"
9277
9278 test_103b() {
9279         declare -a pids
9280         local U
9281
9282         for U in {0..511}; do
9283                 {
9284                 local O=$(printf "%04o" $U)
9285
9286                 umask $(printf "%04o" $((511 ^ $O)))
9287                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9288                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9289
9290                 (( $S == ($O & 0666) )) ||
9291                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9292
9293                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9294                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9295                 (( $S == ($O & 0666) )) ||
9296                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9297
9298                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9299                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9300                 (( $S == ($O & 0666) )) ||
9301                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9302                 rm -f $DIR/$tfile.[smp]$0
9303                 } &
9304                 local pid=$!
9305
9306                 # limit the concurrently running threads to 64. LU-11878
9307                 local idx=$((U % 64))
9308                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9309                 pids[idx]=$pid
9310         done
9311         wait
9312 }
9313 run_test 103b "umask lfs setstripe"
9314
9315 test_103c() {
9316         mkdir -p $DIR/$tdir
9317         cp -rp $DIR/$tdir $DIR/$tdir.bak
9318
9319         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9320                 error "$DIR/$tdir shouldn't contain default ACL"
9321         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9322                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9323         true
9324 }
9325 run_test 103c "'cp -rp' won't set empty acl"
9326
9327 test_104a() {
9328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9329
9330         touch $DIR/$tfile
9331         lfs df || error "lfs df failed"
9332         lfs df -ih || error "lfs df -ih failed"
9333         lfs df -h $DIR || error "lfs df -h $DIR failed"
9334         lfs df -i $DIR || error "lfs df -i $DIR failed"
9335         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9336         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9337
9338         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9339         lctl --device %$OSC deactivate
9340         lfs df || error "lfs df with deactivated OSC failed"
9341         lctl --device %$OSC activate
9342         # wait the osc back to normal
9343         wait_osc_import_ready client ost
9344
9345         lfs df || error "lfs df with reactivated OSC failed"
9346         rm -f $DIR/$tfile
9347 }
9348 run_test 104a "lfs df [-ih] [path] test ========================="
9349
9350 test_104b() {
9351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9352         [ $RUNAS_ID -eq $UID ] &&
9353                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9354
9355         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9356                         grep "Permission denied" | wc -l)))
9357         if [ $denied_cnt -ne 0 ]; then
9358                 error "lfs check servers test failed"
9359         fi
9360 }
9361 run_test 104b "$RUNAS lfs check servers test ===================="
9362
9363 test_105a() {
9364         # doesn't work on 2.4 kernels
9365         touch $DIR/$tfile
9366         if $(flock_is_enabled); then
9367                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9368         else
9369                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9370         fi
9371         rm -f $DIR/$tfile
9372 }
9373 run_test 105a "flock when mounted without -o flock test ========"
9374
9375 test_105b() {
9376         touch $DIR/$tfile
9377         if $(flock_is_enabled); then
9378                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9379         else
9380                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9381         fi
9382         rm -f $DIR/$tfile
9383 }
9384 run_test 105b "fcntl when mounted without -o flock test ========"
9385
9386 test_105c() {
9387         touch $DIR/$tfile
9388         if $(flock_is_enabled); then
9389                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9390         else
9391                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9392         fi
9393         rm -f $DIR/$tfile
9394 }
9395 run_test 105c "lockf when mounted without -o flock test"
9396
9397 test_105d() { # bug 15924
9398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9399
9400         test_mkdir $DIR/$tdir
9401         flock_is_enabled || skip_env "mount w/o flock enabled"
9402         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9403         $LCTL set_param fail_loc=0x80000315
9404         flocks_test 2 $DIR/$tdir
9405 }
9406 run_test 105d "flock race (should not freeze) ========"
9407
9408 test_105e() { # bug 22660 && 22040
9409         flock_is_enabled || skip_env "mount w/o flock enabled"
9410
9411         touch $DIR/$tfile
9412         flocks_test 3 $DIR/$tfile
9413 }
9414 run_test 105e "Two conflicting flocks from same process"
9415
9416 test_106() { #bug 10921
9417         test_mkdir $DIR/$tdir
9418         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9419         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9420 }
9421 run_test 106 "attempt exec of dir followed by chown of that dir"
9422
9423 test_107() {
9424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9425
9426         CDIR=`pwd`
9427         local file=core
9428
9429         cd $DIR
9430         rm -f $file
9431
9432         local save_pattern=$(sysctl -n kernel.core_pattern)
9433         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9434         sysctl -w kernel.core_pattern=$file
9435         sysctl -w kernel.core_uses_pid=0
9436
9437         ulimit -c unlimited
9438         sleep 60 &
9439         SLEEPPID=$!
9440
9441         sleep 1
9442
9443         kill -s 11 $SLEEPPID
9444         wait $SLEEPPID
9445         if [ -e $file ]; then
9446                 size=`stat -c%s $file`
9447                 [ $size -eq 0 ] && error "Fail to create core file $file"
9448         else
9449                 error "Fail to create core file $file"
9450         fi
9451         rm -f $file
9452         sysctl -w kernel.core_pattern=$save_pattern
9453         sysctl -w kernel.core_uses_pid=$save_uses_pid
9454         cd $CDIR
9455 }
9456 run_test 107 "Coredump on SIG"
9457
9458 test_110() {
9459         test_mkdir $DIR/$tdir
9460         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9461         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9462                 error "mkdir with 256 char should fail, but did not"
9463         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9464                 error "create with 255 char failed"
9465         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9466                 error "create with 256 char should fail, but did not"
9467
9468         ls -l $DIR/$tdir
9469         rm -rf $DIR/$tdir
9470 }
9471 run_test 110 "filename length checking"
9472
9473 #
9474 # Purpose: To verify dynamic thread (OSS) creation.
9475 #
9476 test_115() {
9477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9478         remote_ost_nodsh && skip "remote OST with nodsh"
9479
9480         # Lustre does not stop service threads once they are started.
9481         # Reset number of running threads to default.
9482         stopall
9483         setupall
9484
9485         local OSTIO_pre
9486         local save_params="$TMP/sanity-$TESTNAME.parameters"
9487
9488         # Get ll_ost_io count before I/O
9489         OSTIO_pre=$(do_facet ost1 \
9490                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9491         # Exit if lustre is not running (ll_ost_io not running).
9492         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9493
9494         echo "Starting with $OSTIO_pre threads"
9495         local thread_max=$((OSTIO_pre * 2))
9496         local rpc_in_flight=$((thread_max * 2))
9497         # Number of I/O Process proposed to be started.
9498         local nfiles
9499         local facets=$(get_facets OST)
9500
9501         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9502         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9503
9504         # Set in_flight to $rpc_in_flight
9505         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9506                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9507         nfiles=${rpc_in_flight}
9508         # Set ost thread_max to $thread_max
9509         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9510
9511         # 5 Minutes should be sufficient for max number of OSS
9512         # threads(thread_max) to be created.
9513         local timeout=300
9514
9515         # Start I/O.
9516         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9517         test_mkdir $DIR/$tdir
9518         for i in $(seq $nfiles); do
9519                 local file=$DIR/$tdir/${tfile}-$i
9520                 $LFS setstripe -c -1 -i 0 $file
9521                 ($WTL $file $timeout)&
9522         done
9523
9524         # I/O Started - Wait for thread_started to reach thread_max or report
9525         # error if thread_started is more than thread_max.
9526         echo "Waiting for thread_started to reach thread_max"
9527         local thread_started=0
9528         local end_time=$((SECONDS + timeout))
9529
9530         while [ $SECONDS -le $end_time ] ; do
9531                 echo -n "."
9532                 # Get ost i/o thread_started count.
9533                 thread_started=$(do_facet ost1 \
9534                         "$LCTL get_param \
9535                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9536                 # Break out if thread_started is equal/greater than thread_max
9537                 if [[ $thread_started -ge $thread_max ]]; then
9538                         echo ll_ost_io thread_started $thread_started, \
9539                                 equal/greater than thread_max $thread_max
9540                         break
9541                 fi
9542                 sleep 1
9543         done
9544
9545         # Cleanup - We have the numbers, Kill i/o jobs if running.
9546         jobcount=($(jobs -p))
9547         for i in $(seq 0 $((${#jobcount[@]}-1)))
9548         do
9549                 kill -9 ${jobcount[$i]}
9550                 if [ $? -ne 0 ] ; then
9551                         echo Warning: \
9552                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9553                 fi
9554         done
9555
9556         # Cleanup files left by WTL binary.
9557         for i in $(seq $nfiles); do
9558                 local file=$DIR/$tdir/${tfile}-$i
9559                 rm -rf $file
9560                 if [ $? -ne 0 ] ; then
9561                         echo "Warning: Failed to delete file $file"
9562                 fi
9563         done
9564
9565         restore_lustre_params <$save_params
9566         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9567
9568         # Error out if no new thread has started or Thread started is greater
9569         # than thread max.
9570         if [[ $thread_started -le $OSTIO_pre ||
9571                         $thread_started -gt $thread_max ]]; then
9572                 error "ll_ost_io: thread_started $thread_started" \
9573                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9574                       "No new thread started or thread started greater " \
9575                       "than thread_max."
9576         fi
9577 }
9578 run_test 115 "verify dynamic thread creation===================="
9579
9580 free_min_max () {
9581         wait_delete_completed
9582         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9583         echo "OST kbytes available: ${AVAIL[@]}"
9584         MAXV=${AVAIL[0]}
9585         MAXI=0
9586         MINV=${AVAIL[0]}
9587         MINI=0
9588         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9589                 #echo OST $i: ${AVAIL[i]}kb
9590                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9591                         MAXV=${AVAIL[i]}
9592                         MAXI=$i
9593                 fi
9594                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9595                         MINV=${AVAIL[i]}
9596                         MINI=$i
9597                 fi
9598         done
9599         echo "Min free space: OST $MINI: $MINV"
9600         echo "Max free space: OST $MAXI: $MAXV"
9601 }
9602
9603 test_116a() { # was previously test_116()
9604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9605         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9606         remote_mds_nodsh && skip "remote MDS with nodsh"
9607
9608         echo -n "Free space priority "
9609         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9610                 head -n1
9611         declare -a AVAIL
9612         free_min_max
9613
9614         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9615         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9616         trap simple_cleanup_common EXIT
9617
9618         # Check if we need to generate uneven OSTs
9619         test_mkdir -p $DIR/$tdir/OST${MINI}
9620         local FILL=$((MINV / 4))
9621         local DIFF=$((MAXV - MINV))
9622         local DIFF2=$((DIFF * 100 / MINV))
9623
9624         local threshold=$(do_facet $SINGLEMDS \
9625                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9626         threshold=${threshold%%%}
9627         echo -n "Check for uneven OSTs: "
9628         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9629
9630         if [[ $DIFF2 -gt $threshold ]]; then
9631                 echo "ok"
9632                 echo "Don't need to fill OST$MINI"
9633         else
9634                 # generate uneven OSTs. Write 2% over the QOS threshold value
9635                 echo "no"
9636                 DIFF=$((threshold - DIFF2 + 2))
9637                 DIFF2=$((MINV * DIFF / 100))
9638                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9639                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9640                         error "setstripe failed"
9641                 DIFF=$((DIFF2 / 2048))
9642                 i=0
9643                 while [ $i -lt $DIFF ]; do
9644                         i=$((i + 1))
9645                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9646                                 bs=2M count=1 2>/dev/null
9647                         echo -n .
9648                 done
9649                 echo .
9650                 sync
9651                 sleep_maxage
9652                 free_min_max
9653         fi
9654
9655         DIFF=$((MAXV - MINV))
9656         DIFF2=$((DIFF * 100 / MINV))
9657         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9658         if [ $DIFF2 -gt $threshold ]; then
9659                 echo "ok"
9660         else
9661                 echo "failed - QOS mode won't be used"
9662                 simple_cleanup_common
9663                 skip "QOS imbalance criteria not met"
9664         fi
9665
9666         MINI1=$MINI
9667         MINV1=$MINV
9668         MAXI1=$MAXI
9669         MAXV1=$MAXV
9670
9671         # now fill using QOS
9672         $LFS setstripe -c 1 $DIR/$tdir
9673         FILL=$((FILL / 200))
9674         if [ $FILL -gt 600 ]; then
9675                 FILL=600
9676         fi
9677         echo "writing $FILL files to QOS-assigned OSTs"
9678         i=0
9679         while [ $i -lt $FILL ]; do
9680                 i=$((i + 1))
9681                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9682                         count=1 2>/dev/null
9683                 echo -n .
9684         done
9685         echo "wrote $i 200k files"
9686         sync
9687         sleep_maxage
9688
9689         echo "Note: free space may not be updated, so measurements might be off"
9690         free_min_max
9691         DIFF2=$((MAXV - MINV))
9692         echo "free space delta: orig $DIFF final $DIFF2"
9693         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9694         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9695         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9696         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9697         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9698         if [[ $DIFF -gt 0 ]]; then
9699                 FILL=$((DIFF2 * 100 / DIFF - 100))
9700                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9701         fi
9702
9703         # Figure out which files were written where
9704         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9705                awk '/'$MINI1': / {print $2; exit}')
9706         echo $UUID
9707         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9708         echo "$MINC files created on smaller OST $MINI1"
9709         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9710                awk '/'$MAXI1': / {print $2; exit}')
9711         echo $UUID
9712         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9713         echo "$MAXC files created on larger OST $MAXI1"
9714         if [[ $MINC -gt 0 ]]; then
9715                 FILL=$((MAXC * 100 / MINC - 100))
9716                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9717         fi
9718         [[ $MAXC -gt $MINC ]] ||
9719                 error_ignore LU-9 "stripe QOS didn't balance free space"
9720         simple_cleanup_common
9721 }
9722 run_test 116a "stripe QOS: free space balance ==================="
9723
9724 test_116b() { # LU-2093
9725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9726         remote_mds_nodsh && skip "remote MDS with nodsh"
9727
9728 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9729         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9730                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9731         [ -z "$old_rr" ] && skip "no QOS"
9732         do_facet $SINGLEMDS lctl set_param \
9733                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9734         mkdir -p $DIR/$tdir
9735         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9736         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9737         do_facet $SINGLEMDS lctl set_param fail_loc=0
9738         rm -rf $DIR/$tdir
9739         do_facet $SINGLEMDS lctl set_param \
9740                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9741 }
9742 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9743
9744 test_117() # bug 10891
9745 {
9746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9747
9748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9749         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9750         lctl set_param fail_loc=0x21e
9751         > $DIR/$tfile || error "truncate failed"
9752         lctl set_param fail_loc=0
9753         echo "Truncate succeeded."
9754         rm -f $DIR/$tfile
9755 }
9756 run_test 117 "verify osd extend =========="
9757
9758 NO_SLOW_RESENDCOUNT=4
9759 export OLD_RESENDCOUNT=""
9760 set_resend_count () {
9761         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9762         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9763         lctl set_param -n $PROC_RESENDCOUNT $1
9764         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9765 }
9766
9767 # for reduce test_118* time (b=14842)
9768 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9769
9770 # Reset async IO behavior after error case
9771 reset_async() {
9772         FILE=$DIR/reset_async
9773
9774         # Ensure all OSCs are cleared
9775         $LFS setstripe -c -1 $FILE
9776         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9777         sync
9778         rm $FILE
9779 }
9780
9781 test_118a() #bug 11710
9782 {
9783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9784
9785         reset_async
9786
9787         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9788         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9789         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9790
9791         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9792                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9793                 return 1;
9794         fi
9795         rm -f $DIR/$tfile
9796 }
9797 run_test 118a "verify O_SYNC works =========="
9798
9799 test_118b()
9800 {
9801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9802         remote_ost_nodsh && skip "remote OST with nodsh"
9803
9804         reset_async
9805
9806         #define OBD_FAIL_SRV_ENOENT 0x217
9807         set_nodes_failloc "$(osts_nodes)" 0x217
9808         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9809         RC=$?
9810         set_nodes_failloc "$(osts_nodes)" 0
9811         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9812         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9813                     grep -c writeback)
9814
9815         if [[ $RC -eq 0 ]]; then
9816                 error "Must return error due to dropped pages, rc=$RC"
9817                 return 1;
9818         fi
9819
9820         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9821                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9822                 return 1;
9823         fi
9824
9825         echo "Dirty pages not leaked on ENOENT"
9826
9827         # Due to the above error the OSC will issue all RPCs syncronously
9828         # until a subsequent RPC completes successfully without error.
9829         $MULTIOP $DIR/$tfile Ow4096yc
9830         rm -f $DIR/$tfile
9831
9832         return 0
9833 }
9834 run_test 118b "Reclaim dirty pages on fatal error =========="
9835
9836 test_118c()
9837 {
9838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9839
9840         # for 118c, restore the original resend count, LU-1940
9841         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9842                                 set_resend_count $OLD_RESENDCOUNT
9843         remote_ost_nodsh && skip "remote OST with nodsh"
9844
9845         reset_async
9846
9847         #define OBD_FAIL_OST_EROFS               0x216
9848         set_nodes_failloc "$(osts_nodes)" 0x216
9849
9850         # multiop should block due to fsync until pages are written
9851         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9852         MULTIPID=$!
9853         sleep 1
9854
9855         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9856                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9857         fi
9858
9859         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9860                     grep -c writeback)
9861         if [[ $WRITEBACK -eq 0 ]]; then
9862                 error "No page in writeback, writeback=$WRITEBACK"
9863         fi
9864
9865         set_nodes_failloc "$(osts_nodes)" 0
9866         wait $MULTIPID
9867         RC=$?
9868         if [[ $RC -ne 0 ]]; then
9869                 error "Multiop fsync failed, rc=$RC"
9870         fi
9871
9872         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9873         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9874                     grep -c writeback)
9875         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9876                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9877         fi
9878
9879         rm -f $DIR/$tfile
9880         echo "Dirty pages flushed via fsync on EROFS"
9881         return 0
9882 }
9883 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9884
9885 # continue to use small resend count to reduce test_118* time (b=14842)
9886 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9887
9888 test_118d()
9889 {
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891         remote_ost_nodsh && skip "remote OST with nodsh"
9892
9893         reset_async
9894
9895         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9896         set_nodes_failloc "$(osts_nodes)" 0x214
9897         # multiop should block due to fsync until pages are written
9898         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9899         MULTIPID=$!
9900         sleep 1
9901
9902         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9903                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9904         fi
9905
9906         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9907                     grep -c writeback)
9908         if [[ $WRITEBACK -eq 0 ]]; then
9909                 error "No page in writeback, writeback=$WRITEBACK"
9910         fi
9911
9912         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9913         set_nodes_failloc "$(osts_nodes)" 0
9914
9915         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9916         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9917                     grep -c writeback)
9918         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9919                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9920         fi
9921
9922         rm -f $DIR/$tfile
9923         echo "Dirty pages gaurenteed flushed via fsync"
9924         return 0
9925 }
9926 run_test 118d "Fsync validation inject a delay of the bulk =========="
9927
9928 test_118f() {
9929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9930
9931         reset_async
9932
9933         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9934         lctl set_param fail_loc=0x8000040a
9935
9936         # Should simulate EINVAL error which is fatal
9937         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9938         RC=$?
9939         if [[ $RC -eq 0 ]]; then
9940                 error "Must return error due to dropped pages, rc=$RC"
9941         fi
9942
9943         lctl set_param fail_loc=0x0
9944
9945         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9946         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9947         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9948                     grep -c writeback)
9949         if [[ $LOCKED -ne 0 ]]; then
9950                 error "Locked pages remain in cache, locked=$LOCKED"
9951         fi
9952
9953         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9954                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9955         fi
9956
9957         rm -f $DIR/$tfile
9958         echo "No pages locked after fsync"
9959
9960         reset_async
9961         return 0
9962 }
9963 run_test 118f "Simulate unrecoverable OSC side error =========="
9964
9965 test_118g() {
9966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9967
9968         reset_async
9969
9970         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9971         lctl set_param fail_loc=0x406
9972
9973         # simulate local -ENOMEM
9974         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9975         RC=$?
9976
9977         lctl set_param fail_loc=0
9978         if [[ $RC -eq 0 ]]; then
9979                 error "Must return error due to dropped pages, rc=$RC"
9980         fi
9981
9982         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9983         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9984         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9985                         grep -c writeback)
9986         if [[ $LOCKED -ne 0 ]]; then
9987                 error "Locked pages remain in cache, locked=$LOCKED"
9988         fi
9989
9990         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9991                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9992         fi
9993
9994         rm -f $DIR/$tfile
9995         echo "No pages locked after fsync"
9996
9997         reset_async
9998         return 0
9999 }
10000 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10001
10002 test_118h() {
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004         remote_ost_nodsh && skip "remote OST with nodsh"
10005
10006         reset_async
10007
10008         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10009         set_nodes_failloc "$(osts_nodes)" 0x20e
10010         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10011         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10012         RC=$?
10013
10014         set_nodes_failloc "$(osts_nodes)" 0
10015         if [[ $RC -eq 0 ]]; then
10016                 error "Must return error due to dropped pages, rc=$RC"
10017         fi
10018
10019         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10020         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10021         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10022                     grep -c writeback)
10023         if [[ $LOCKED -ne 0 ]]; then
10024                 error "Locked pages remain in cache, locked=$LOCKED"
10025         fi
10026
10027         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10028                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10029         fi
10030
10031         rm -f $DIR/$tfile
10032         echo "No pages locked after fsync"
10033
10034         return 0
10035 }
10036 run_test 118h "Verify timeout in handling recoverables errors  =========="
10037
10038 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10039
10040 test_118i() {
10041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10042         remote_ost_nodsh && skip "remote OST with nodsh"
10043
10044         reset_async
10045
10046         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10047         set_nodes_failloc "$(osts_nodes)" 0x20e
10048
10049         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10050         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10051         PID=$!
10052         sleep 5
10053         set_nodes_failloc "$(osts_nodes)" 0
10054
10055         wait $PID
10056         RC=$?
10057         if [[ $RC -ne 0 ]]; then
10058                 error "got error, but should be not, rc=$RC"
10059         fi
10060
10061         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10062         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10063         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10064         if [[ $LOCKED -ne 0 ]]; then
10065                 error "Locked pages remain in cache, locked=$LOCKED"
10066         fi
10067
10068         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10069                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10070         fi
10071
10072         rm -f $DIR/$tfile
10073         echo "No pages locked after fsync"
10074
10075         return 0
10076 }
10077 run_test 118i "Fix error before timeout in recoverable error  =========="
10078
10079 [ "$SLOW" = "no" ] && set_resend_count 4
10080
10081 test_118j() {
10082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10083         remote_ost_nodsh && skip "remote OST with nodsh"
10084
10085         reset_async
10086
10087         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10088         set_nodes_failloc "$(osts_nodes)" 0x220
10089
10090         # return -EIO from OST
10091         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10092         RC=$?
10093         set_nodes_failloc "$(osts_nodes)" 0x0
10094         if [[ $RC -eq 0 ]]; then
10095                 error "Must return error due to dropped pages, rc=$RC"
10096         fi
10097
10098         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10099         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10100         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10101         if [[ $LOCKED -ne 0 ]]; then
10102                 error "Locked pages remain in cache, locked=$LOCKED"
10103         fi
10104
10105         # in recoverable error on OST we want resend and stay until it finished
10106         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10107                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10108         fi
10109
10110         rm -f $DIR/$tfile
10111         echo "No pages locked after fsync"
10112
10113         return 0
10114 }
10115 run_test 118j "Simulate unrecoverable OST side error =========="
10116
10117 test_118k()
10118 {
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120         remote_ost_nodsh && skip "remote OSTs with nodsh"
10121
10122         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10123         set_nodes_failloc "$(osts_nodes)" 0x20e
10124         test_mkdir $DIR/$tdir
10125
10126         for ((i=0;i<10;i++)); do
10127                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10128                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10129                 SLEEPPID=$!
10130                 sleep 0.500s
10131                 kill $SLEEPPID
10132                 wait $SLEEPPID
10133         done
10134
10135         set_nodes_failloc "$(osts_nodes)" 0
10136         rm -rf $DIR/$tdir
10137 }
10138 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10139
10140 test_118l() # LU-646
10141 {
10142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10143
10144         test_mkdir $DIR/$tdir
10145         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10146         rm -rf $DIR/$tdir
10147 }
10148 run_test 118l "fsync dir"
10149
10150 test_118m() # LU-3066
10151 {
10152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10153
10154         test_mkdir $DIR/$tdir
10155         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10156         rm -rf $DIR/$tdir
10157 }
10158 run_test 118m "fdatasync dir ========="
10159
10160 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10161
10162 test_118n()
10163 {
10164         local begin
10165         local end
10166
10167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10168         remote_ost_nodsh && skip "remote OSTs with nodsh"
10169
10170         # Sleep to avoid a cached response.
10171         #define OBD_STATFS_CACHE_SECONDS 1
10172         sleep 2
10173
10174         # Inject a 10 second delay in the OST_STATFS handler.
10175         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10176         set_nodes_failloc "$(osts_nodes)" 0x242
10177
10178         begin=$SECONDS
10179         stat --file-system $MOUNT > /dev/null
10180         end=$SECONDS
10181
10182         set_nodes_failloc "$(osts_nodes)" 0
10183
10184         if ((end - begin > 20)); then
10185             error "statfs took $((end - begin)) seconds, expected 10"
10186         fi
10187 }
10188 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10189
10190 test_119a() # bug 11737
10191 {
10192         BSIZE=$((512 * 1024))
10193         directio write $DIR/$tfile 0 1 $BSIZE
10194         # We ask to read two blocks, which is more than a file size.
10195         # directio will indicate an error when requested and actual
10196         # sizes aren't equeal (a normal situation in this case) and
10197         # print actual read amount.
10198         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10199         if [ "$NOB" != "$BSIZE" ]; then
10200                 error "read $NOB bytes instead of $BSIZE"
10201         fi
10202         rm -f $DIR/$tfile
10203 }
10204 run_test 119a "Short directIO read must return actual read amount"
10205
10206 test_119b() # bug 11737
10207 {
10208         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10209
10210         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10212         sync
10213         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10214                 error "direct read failed"
10215         rm -f $DIR/$tfile
10216 }
10217 run_test 119b "Sparse directIO read must return actual read amount"
10218
10219 test_119c() # bug 13099
10220 {
10221         BSIZE=1048576
10222         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10223         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10224         rm -f $DIR/$tfile
10225 }
10226 run_test 119c "Testing for direct read hitting hole"
10227
10228 test_119d() # bug 15950
10229 {
10230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10231
10232         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10233         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10234         BSIZE=1048576
10235         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10236         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10237         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10238         lctl set_param fail_loc=0x40d
10239         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10240         pid_dio=$!
10241         sleep 1
10242         cat $DIR/$tfile > /dev/null &
10243         lctl set_param fail_loc=0
10244         pid_reads=$!
10245         wait $pid_dio
10246         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10247         sleep 2
10248         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10249         error "the read rpcs have not completed in 2s"
10250         rm -f $DIR/$tfile
10251         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10252 }
10253 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10254
10255 test_120a() {
10256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10257         remote_mds_nodsh && skip "remote MDS with nodsh"
10258         test_mkdir -i0 -c1 $DIR/$tdir
10259         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10260                 skip_env "no early lock cancel on server"
10261
10262         lru_resize_disable mdc
10263         lru_resize_disable osc
10264         cancel_lru_locks mdc
10265         # asynchronous object destroy at MDT could cause bl ast to client
10266         cancel_lru_locks osc
10267
10268         stat $DIR/$tdir > /dev/null
10269         can1=$(do_facet mds1 \
10270                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10271                awk '/ldlm_cancel/ {print $2}')
10272         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10273                awk '/ldlm_bl_callback/ {print $2}')
10274         test_mkdir -i0 -c1 $DIR/$tdir/d1
10275         can2=$(do_facet mds1 \
10276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10277                awk '/ldlm_cancel/ {print $2}')
10278         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10279                awk '/ldlm_bl_callback/ {print $2}')
10280         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10281         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10282         lru_resize_enable mdc
10283         lru_resize_enable osc
10284 }
10285 run_test 120a "Early Lock Cancel: mkdir test"
10286
10287 test_120b() {
10288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10289         remote_mds_nodsh && skip "remote MDS with nodsh"
10290         test_mkdir $DIR/$tdir
10291         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10292                 skip_env "no early lock cancel on server"
10293
10294         lru_resize_disable mdc
10295         lru_resize_disable osc
10296         cancel_lru_locks mdc
10297         stat $DIR/$tdir > /dev/null
10298         can1=$(do_facet $SINGLEMDS \
10299                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10300                awk '/ldlm_cancel/ {print $2}')
10301         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10302                awk '/ldlm_bl_callback/ {print $2}')
10303         touch $DIR/$tdir/f1
10304         can2=$(do_facet $SINGLEMDS \
10305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10306                awk '/ldlm_cancel/ {print $2}')
10307         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10308                awk '/ldlm_bl_callback/ {print $2}')
10309         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10310         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10311         lru_resize_enable mdc
10312         lru_resize_enable osc
10313 }
10314 run_test 120b "Early Lock Cancel: create test"
10315
10316 test_120c() {
10317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10318         remote_mds_nodsh && skip "remote MDS with nodsh"
10319         test_mkdir -i0 -c1 $DIR/$tdir
10320         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10321                 skip "no early lock cancel on server"
10322
10323         lru_resize_disable mdc
10324         lru_resize_disable osc
10325         test_mkdir -i0 -c1 $DIR/$tdir/d1
10326         test_mkdir -i0 -c1 $DIR/$tdir/d2
10327         touch $DIR/$tdir/d1/f1
10328         cancel_lru_locks mdc
10329         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10330         can1=$(do_facet mds1 \
10331                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10332                awk '/ldlm_cancel/ {print $2}')
10333         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10334                awk '/ldlm_bl_callback/ {print $2}')
10335         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10336         can2=$(do_facet mds1 \
10337                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10338                awk '/ldlm_cancel/ {print $2}')
10339         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10340                awk '/ldlm_bl_callback/ {print $2}')
10341         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10342         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10343         lru_resize_enable mdc
10344         lru_resize_enable osc
10345 }
10346 run_test 120c "Early Lock Cancel: link test"
10347
10348 test_120d() {
10349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10350         remote_mds_nodsh && skip "remote MDS with nodsh"
10351         test_mkdir -i0 -c1 $DIR/$tdir
10352         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10353                 skip_env "no early lock cancel on server"
10354
10355         lru_resize_disable mdc
10356         lru_resize_disable osc
10357         touch $DIR/$tdir
10358         cancel_lru_locks mdc
10359         stat $DIR/$tdir > /dev/null
10360         can1=$(do_facet mds1 \
10361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10362                awk '/ldlm_cancel/ {print $2}')
10363         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10364                awk '/ldlm_bl_callback/ {print $2}')
10365         chmod a+x $DIR/$tdir
10366         can2=$(do_facet mds1 \
10367                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10368                awk '/ldlm_cancel/ {print $2}')
10369         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10370                awk '/ldlm_bl_callback/ {print $2}')
10371         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10372         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10373         lru_resize_enable mdc
10374         lru_resize_enable osc
10375 }
10376 run_test 120d "Early Lock Cancel: setattr test"
10377
10378 test_120e() {
10379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10380         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10381                 skip_env "no early lock cancel on server"
10382         remote_mds_nodsh && skip "remote MDS with nodsh"
10383
10384         local dlmtrace_set=false
10385
10386         test_mkdir -i0 -c1 $DIR/$tdir
10387         lru_resize_disable mdc
10388         lru_resize_disable osc
10389         ! $LCTL get_param debug | grep -q dlmtrace &&
10390                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10391         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10392         cancel_lru_locks mdc
10393         cancel_lru_locks osc
10394         dd if=$DIR/$tdir/f1 of=/dev/null
10395         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10396         # XXX client can not do early lock cancel of OST lock
10397         # during unlink (LU-4206), so cancel osc lock now.
10398         sleep 2
10399         cancel_lru_locks osc
10400         can1=$(do_facet mds1 \
10401                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10402                awk '/ldlm_cancel/ {print $2}')
10403         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10404                awk '/ldlm_bl_callback/ {print $2}')
10405         unlink $DIR/$tdir/f1
10406         sleep 5
10407         can2=$(do_facet mds1 \
10408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10409                awk '/ldlm_cancel/ {print $2}')
10410         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10411                awk '/ldlm_bl_callback/ {print $2}')
10412         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10413                 $LCTL dk $TMP/cancel.debug.txt
10414         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10415                 $LCTL dk $TMP/blocking.debug.txt
10416         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10417         lru_resize_enable mdc
10418         lru_resize_enable osc
10419 }
10420 run_test 120e "Early Lock Cancel: unlink test"
10421
10422 test_120f() {
10423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10424         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10425                 skip_env "no early lock cancel on server"
10426         remote_mds_nodsh && skip "remote MDS with nodsh"
10427
10428         test_mkdir -i0 -c1 $DIR/$tdir
10429         lru_resize_disable mdc
10430         lru_resize_disable osc
10431         test_mkdir -i0 -c1 $DIR/$tdir/d1
10432         test_mkdir -i0 -c1 $DIR/$tdir/d2
10433         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10434         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10435         cancel_lru_locks mdc
10436         cancel_lru_locks osc
10437         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10438         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10439         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10440         # XXX client can not do early lock cancel of OST lock
10441         # during rename (LU-4206), so cancel osc lock now.
10442         sleep 2
10443         cancel_lru_locks osc
10444         can1=$(do_facet mds1 \
10445                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10446                awk '/ldlm_cancel/ {print $2}')
10447         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10448                awk '/ldlm_bl_callback/ {print $2}')
10449         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10450         sleep 5
10451         can2=$(do_facet mds1 \
10452                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10453                awk '/ldlm_cancel/ {print $2}')
10454         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10455                awk '/ldlm_bl_callback/ {print $2}')
10456         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10457         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10458         lru_resize_enable mdc
10459         lru_resize_enable osc
10460 }
10461 run_test 120f "Early Lock Cancel: rename test"
10462
10463 test_120g() {
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10466                 skip_env "no early lock cancel on server"
10467         remote_mds_nodsh && skip "remote MDS with nodsh"
10468
10469         lru_resize_disable mdc
10470         lru_resize_disable osc
10471         count=10000
10472         echo create $count files
10473         test_mkdir $DIR/$tdir
10474         cancel_lru_locks mdc
10475         cancel_lru_locks osc
10476         t0=$(date +%s)
10477
10478         can0=$(do_facet $SINGLEMDS \
10479                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10480                awk '/ldlm_cancel/ {print $2}')
10481         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10482                awk '/ldlm_bl_callback/ {print $2}')
10483         createmany -o $DIR/$tdir/f $count
10484         sync
10485         can1=$(do_facet $SINGLEMDS \
10486                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10487                awk '/ldlm_cancel/ {print $2}')
10488         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10489                awk '/ldlm_bl_callback/ {print $2}')
10490         t1=$(date +%s)
10491         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10492         echo rm $count files
10493         rm -r $DIR/$tdir
10494         sync
10495         can2=$(do_facet $SINGLEMDS \
10496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10497                awk '/ldlm_cancel/ {print $2}')
10498         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10499                awk '/ldlm_bl_callback/ {print $2}')
10500         t2=$(date +%s)
10501         echo total: $count removes in $((t2-t1))
10502         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10503         sleep 2
10504         # wait for commitment of removal
10505         lru_resize_enable mdc
10506         lru_resize_enable osc
10507 }
10508 run_test 120g "Early Lock Cancel: performance test"
10509
10510 test_121() { #bug #10589
10511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10512
10513         rm -rf $DIR/$tfile
10514         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10515 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10516         lctl set_param fail_loc=0x310
10517         cancel_lru_locks osc > /dev/null
10518         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10519         lctl set_param fail_loc=0
10520         [[ $reads -eq $writes ]] ||
10521                 error "read $reads blocks, must be $writes blocks"
10522 }
10523 run_test 121 "read cancel race ========="
10524
10525 test_123a() { # was test 123, statahead(bug 11401)
10526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10527
10528         SLOWOK=0
10529         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10530                 log "testing UP system. Performance may be lower than expected."
10531                 SLOWOK=1
10532         fi
10533
10534         rm -rf $DIR/$tdir
10535         test_mkdir $DIR/$tdir
10536         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10537         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10538         MULT=10
10539         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10540                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10541
10542                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10543                 lctl set_param -n llite.*.statahead_max 0
10544                 lctl get_param llite.*.statahead_max
10545                 cancel_lru_locks mdc
10546                 cancel_lru_locks osc
10547                 stime=`date +%s`
10548                 time ls -l $DIR/$tdir | wc -l
10549                 etime=`date +%s`
10550                 delta=$((etime - stime))
10551                 log "ls $i files without statahead: $delta sec"
10552                 lctl set_param llite.*.statahead_max=$max
10553
10554                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10555                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10556                 cancel_lru_locks mdc
10557                 cancel_lru_locks osc
10558                 stime=`date +%s`
10559                 time ls -l $DIR/$tdir | wc -l
10560                 etime=`date +%s`
10561                 delta_sa=$((etime - stime))
10562                 log "ls $i files with statahead: $delta_sa sec"
10563                 lctl get_param -n llite.*.statahead_stats
10564                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10565
10566                 [[ $swrong -lt $ewrong ]] &&
10567                         log "statahead was stopped, maybe too many locks held!"
10568                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10569
10570                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10571                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10572                     lctl set_param -n llite.*.statahead_max 0
10573                     lctl get_param llite.*.statahead_max
10574                     cancel_lru_locks mdc
10575                     cancel_lru_locks osc
10576                     stime=`date +%s`
10577                     time ls -l $DIR/$tdir | wc -l
10578                     etime=`date +%s`
10579                     delta=$((etime - stime))
10580                     log "ls $i files again without statahead: $delta sec"
10581                     lctl set_param llite.*.statahead_max=$max
10582                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10583                         if [  $SLOWOK -eq 0 ]; then
10584                                 error "ls $i files is slower with statahead!"
10585                         else
10586                                 log "ls $i files is slower with statahead!"
10587                         fi
10588                         break
10589                     fi
10590                 fi
10591
10592                 [ $delta -gt 20 ] && break
10593                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10594                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10595         done
10596         log "ls done"
10597
10598         stime=`date +%s`
10599         rm -r $DIR/$tdir
10600         sync
10601         etime=`date +%s`
10602         delta=$((etime - stime))
10603         log "rm -r $DIR/$tdir/: $delta seconds"
10604         log "rm done"
10605         lctl get_param -n llite.*.statahead_stats
10606 }
10607 run_test 123a "verify statahead work"
10608
10609 test_123b () { # statahead(bug 15027)
10610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10611
10612         test_mkdir $DIR/$tdir
10613         createmany -o $DIR/$tdir/$tfile-%d 1000
10614
10615         cancel_lru_locks mdc
10616         cancel_lru_locks osc
10617
10618 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10619         lctl set_param fail_loc=0x80000803
10620         ls -lR $DIR/$tdir > /dev/null
10621         log "ls done"
10622         lctl set_param fail_loc=0x0
10623         lctl get_param -n llite.*.statahead_stats
10624         rm -r $DIR/$tdir
10625         sync
10626
10627 }
10628 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10629
10630 test_124a() {
10631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10632         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10633                 skip_env "no lru resize on server"
10634
10635         local NR=2000
10636
10637         test_mkdir $DIR/$tdir
10638
10639         log "create $NR files at $DIR/$tdir"
10640         createmany -o $DIR/$tdir/f $NR ||
10641                 error "failed to create $NR files in $DIR/$tdir"
10642
10643         cancel_lru_locks mdc
10644         ls -l $DIR/$tdir > /dev/null
10645
10646         local NSDIR=""
10647         local LRU_SIZE=0
10648         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10649                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10650                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10651                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10652                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10653                         log "NSDIR=$NSDIR"
10654                         log "NS=$(basename $NSDIR)"
10655                         break
10656                 fi
10657         done
10658
10659         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10660                 skip "Not enough cached locks created!"
10661         fi
10662         log "LRU=$LRU_SIZE"
10663
10664         local SLEEP=30
10665
10666         # We know that lru resize allows one client to hold $LIMIT locks
10667         # for 10h. After that locks begin to be killed by client.
10668         local MAX_HRS=10
10669         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10670         log "LIMIT=$LIMIT"
10671         if [ $LIMIT -lt $LRU_SIZE ]; then
10672                 skip "Limit is too small $LIMIT"
10673         fi
10674
10675         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10676         # killing locks. Some time was spent for creating locks. This means
10677         # that up to the moment of sleep finish we must have killed some of
10678         # them (10-100 locks). This depends on how fast ther were created.
10679         # Many of them were touched in almost the same moment and thus will
10680         # be killed in groups.
10681         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10682
10683         # Use $LRU_SIZE_B here to take into account real number of locks
10684         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10685         local LRU_SIZE_B=$LRU_SIZE
10686         log "LVF=$LVF"
10687         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10688         log "OLD_LVF=$OLD_LVF"
10689         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10690
10691         # Let's make sure that we really have some margin. Client checks
10692         # cached locks every 10 sec.
10693         SLEEP=$((SLEEP+20))
10694         log "Sleep ${SLEEP} sec"
10695         local SEC=0
10696         while ((SEC<$SLEEP)); do
10697                 echo -n "..."
10698                 sleep 5
10699                 SEC=$((SEC+5))
10700                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10701                 echo -n "$LRU_SIZE"
10702         done
10703         echo ""
10704         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10705         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10706
10707         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10708                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10709                 unlinkmany $DIR/$tdir/f $NR
10710                 return
10711         }
10712
10713         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10714         log "unlink $NR files at $DIR/$tdir"
10715         unlinkmany $DIR/$tdir/f $NR
10716 }
10717 run_test 124a "lru resize ======================================="
10718
10719 get_max_pool_limit()
10720 {
10721         local limit=$($LCTL get_param \
10722                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10723         local max=0
10724         for l in $limit; do
10725                 if [[ $l -gt $max ]]; then
10726                         max=$l
10727                 fi
10728         done
10729         echo $max
10730 }
10731
10732 test_124b() {
10733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10734         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10735                 skip_env "no lru resize on server"
10736
10737         LIMIT=$(get_max_pool_limit)
10738
10739         NR=$(($(default_lru_size)*20))
10740         if [[ $NR -gt $LIMIT ]]; then
10741                 log "Limit lock number by $LIMIT locks"
10742                 NR=$LIMIT
10743         fi
10744
10745         IFree=$(mdsrate_inodes_available)
10746         if [ $IFree -lt $NR ]; then
10747                 log "Limit lock number by $IFree inodes"
10748                 NR=$IFree
10749         fi
10750
10751         lru_resize_disable mdc
10752         test_mkdir -p $DIR/$tdir/disable_lru_resize
10753
10754         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10755         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10756         cancel_lru_locks mdc
10757         stime=`date +%s`
10758         PID=""
10759         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10760         PID="$PID $!"
10761         sleep 2
10762         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10763         PID="$PID $!"
10764         sleep 2
10765         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10766         PID="$PID $!"
10767         wait $PID
10768         etime=`date +%s`
10769         nolruresize_delta=$((etime-stime))
10770         log "ls -la time: $nolruresize_delta seconds"
10771         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10772         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10773
10774         lru_resize_enable mdc
10775         test_mkdir -p $DIR/$tdir/enable_lru_resize
10776
10777         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10778         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10779         cancel_lru_locks mdc
10780         stime=`date +%s`
10781         PID=""
10782         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10783         PID="$PID $!"
10784         sleep 2
10785         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10786         PID="$PID $!"
10787         sleep 2
10788         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10789         PID="$PID $!"
10790         wait $PID
10791         etime=`date +%s`
10792         lruresize_delta=$((etime-stime))
10793         log "ls -la time: $lruresize_delta seconds"
10794         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10795
10796         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10797                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10798         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10799                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10800         else
10801                 log "lru resize performs the same with no lru resize"
10802         fi
10803         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10804 }
10805 run_test 124b "lru resize (performance test) ======================="
10806
10807 test_124c() {
10808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10809         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10810                 skip_env "no lru resize on server"
10811
10812         # cache ununsed locks on client
10813         local nr=100
10814         cancel_lru_locks mdc
10815         test_mkdir $DIR/$tdir
10816         createmany -o $DIR/$tdir/f $nr ||
10817                 error "failed to create $nr files in $DIR/$tdir"
10818         ls -l $DIR/$tdir > /dev/null
10819
10820         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10821         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10822         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10823         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10824         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10825
10826         # set lru_max_age to 1 sec
10827         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10828         echo "sleep $((recalc_p * 2)) seconds..."
10829         sleep $((recalc_p * 2))
10830
10831         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10832         # restore lru_max_age
10833         $LCTL set_param -n $nsdir.lru_max_age $max_age
10834         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10835         unlinkmany $DIR/$tdir/f $nr
10836 }
10837 run_test 124c "LRUR cancel very aged locks"
10838
10839 test_125() { # 13358
10840         $LCTL get_param -n llite.*.client_type | grep -q local ||
10841                 skip "must run as local client"
10842         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10843                 skip_env "must have acl enabled"
10844         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10845
10846         test_mkdir $DIR/$tdir
10847         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10848         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10849         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10850 }
10851 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10852
10853 test_126() { # bug 12829/13455
10854         $GSS && skip_env "must run as gss disabled"
10855         $LCTL get_param -n llite.*.client_type | grep -q local ||
10856                 skip "must run as local client"
10857         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10858
10859         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10860         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10861         rm -f $DIR/$tfile
10862         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10863 }
10864 run_test 126 "check that the fsgid provided by the client is taken into account"
10865
10866 test_127a() { # bug 15521
10867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10868
10869         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10870         $LCTL set_param osc.*.stats=0
10871         FSIZE=$((2048 * 1024))
10872         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10873         cancel_lru_locks osc
10874         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10875
10876         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10877         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10878                 echo "got $COUNT $NAME"
10879                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10880                 eval $NAME=$COUNT || error "Wrong proc format"
10881
10882                 case $NAME in
10883                         read_bytes|write_bytes)
10884                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10885                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10886                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10887                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10888                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10889                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10890                                 error "sumsquare is too small: $SUMSQ"
10891                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10892                                 error "sumsquare is too big: $SUMSQ"
10893                         ;;
10894                         *) ;;
10895                 esac
10896         done < $DIR/${tfile}.tmp
10897
10898         #check that we actually got some stats
10899         [ "$read_bytes" ] || error "Missing read_bytes stats"
10900         [ "$write_bytes" ] || error "Missing write_bytes stats"
10901         [ "$read_bytes" != 0 ] || error "no read done"
10902         [ "$write_bytes" != 0 ] || error "no write done"
10903 }
10904 run_test 127a "verify the client stats are sane"
10905
10906 test_127b() { # bug LU-333
10907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10908         local name count samp unit min max sum sumsq
10909
10910         $LCTL set_param llite.*.stats=0
10911
10912         # perform 2 reads and writes so MAX is different from SUM.
10913         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10914         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10915         cancel_lru_locks osc
10916         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10917         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10918
10919         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10920         while read name count samp unit min max sum sumsq; do
10921                 echo "got $count $name"
10922                 eval $name=$count || error "Wrong proc format"
10923
10924                 case $name in
10925                 read_bytes)
10926                         [ $count -ne 2 ] && error "count is not 2: $count"
10927                         [ $min -ne $PAGE_SIZE ] &&
10928                                 error "min is not $PAGE_SIZE: $min"
10929                         [ $max -ne $PAGE_SIZE ] &&
10930                                 error "max is incorrect: $max"
10931                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10932                                 error "sum is wrong: $sum"
10933                         ;;
10934                 write_bytes)
10935                         [ $count -ne 2 ] && error "count is not 2: $count"
10936                         [ $min -ne $PAGE_SIZE ] &&
10937                                 error "min is not $PAGE_SIZE: $min"
10938                         [ $max -ne $PAGE_SIZE ] &&
10939                                 error "max is incorrect: $max"
10940                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10941                                 error "sum is wrong: $sum"
10942                         ;;
10943                 *) ;;
10944                 esac
10945         done < $TMP/$tfile.tmp
10946
10947         #check that we actually got some stats
10948         [ "$read_bytes" ] || error "Missing read_bytes stats"
10949         [ "$write_bytes" ] || error "Missing write_bytes stats"
10950         [ "$read_bytes" != 0 ] || error "no read done"
10951         [ "$write_bytes" != 0 ] || error "no write done"
10952
10953         rm -f $TMP/${tfile}.tmp
10954 }
10955 run_test 127b "verify the llite client stats are sane"
10956
10957 test_128() { # bug 15212
10958         touch $DIR/$tfile
10959         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10960                 find $DIR/$tfile
10961                 find $DIR/$tfile
10962         EOF
10963
10964         result=$(grep error $TMP/$tfile.log)
10965         rm -f $DIR/$tfile $TMP/$tfile.log
10966         [ -z "$result" ] ||
10967                 error "consecutive find's under interactive lfs failed"
10968 }
10969 run_test 128 "interactive lfs for 2 consecutive find's"
10970
10971 set_dir_limits () {
10972         local mntdev
10973         local canondev
10974         local node
10975
10976         local ldproc=/proc/fs/ldiskfs
10977         local facets=$(get_facets MDS)
10978
10979         for facet in ${facets//,/ }; do
10980                 canondev=$(ldiskfs_canon \
10981                            *.$(convert_facet2label $facet).mntdev $facet)
10982                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10983                         ldproc=/sys/fs/ldiskfs
10984                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10985                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10986         done
10987 }
10988
10989 check_mds_dmesg() {
10990         local facets=$(get_facets MDS)
10991         for facet in ${facets//,/ }; do
10992                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10993         done
10994         return 1
10995 }
10996
10997 test_129() {
10998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10999         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11000                 skip "Need MDS version with at least 2.5.56"
11001         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11002                 skip_env "ldiskfs only test"
11003         fi
11004         remote_mds_nodsh && skip "remote MDS with nodsh"
11005
11006         local ENOSPC=28
11007         local EFBIG=27
11008         local has_warning=false
11009
11010         rm -rf $DIR/$tdir
11011         mkdir -p $DIR/$tdir
11012
11013         # block size of mds1
11014         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11015         set_dir_limits $maxsize $maxsize
11016         local dirsize=$(stat -c%s "$DIR/$tdir")
11017         local nfiles=0
11018         while [[ $dirsize -le $maxsize ]]; do
11019                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11020                 rc=$?
11021                 if ! $has_warning; then
11022                         check_mds_dmesg '"is approaching"' && has_warning=true
11023                 fi
11024                 # check two errors:
11025                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11026                 # EFBIG for previous versions included in ldiskfs series
11027                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11028                         set_dir_limits 0 0
11029                         echo "return code $rc received as expected"
11030
11031                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11032                                 error_exit "create failed w/o dir size limit"
11033
11034                         check_mds_dmesg '"has reached"' ||
11035                                 error_exit "reached message should be output"
11036
11037                         [ $has_warning = "false" ] &&
11038                                 error_exit "warning message should be output"
11039
11040                         dirsize=$(stat -c%s "$DIR/$tdir")
11041
11042                         [[ $dirsize -ge $maxsize ]] && return 0
11043                         error_exit "current dir size $dirsize, " \
11044                                    "previous limit $maxsize"
11045                 elif [ $rc -ne 0 ]; then
11046                         set_dir_limits 0 0
11047                         error_exit "return $rc received instead of expected " \
11048                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11049                 fi
11050                 nfiles=$((nfiles + 1))
11051                 dirsize=$(stat -c%s "$DIR/$tdir")
11052         done
11053
11054         set_dir_limits 0 0
11055         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11056 }
11057 run_test 129 "test directory size limit ========================"
11058
11059 OLDIFS="$IFS"
11060 cleanup_130() {
11061         trap 0
11062         IFS="$OLDIFS"
11063 }
11064
11065 test_130a() {
11066         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11067         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11068
11069         trap cleanup_130 EXIT RETURN
11070
11071         local fm_file=$DIR/$tfile
11072         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11073         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11074                 error "dd failed for $fm_file"
11075
11076         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11077         filefrag -ves $fm_file
11078         RC=$?
11079         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11080                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11081         [ $RC != 0 ] && error "filefrag $fm_file failed"
11082
11083         filefrag_op=$(filefrag -ve -k $fm_file |
11084                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11085         lun=$($LFS getstripe -i $fm_file)
11086
11087         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11088         IFS=$'\n'
11089         tot_len=0
11090         for line in $filefrag_op
11091         do
11092                 frag_lun=`echo $line | cut -d: -f5`
11093                 ext_len=`echo $line | cut -d: -f4`
11094                 if (( $frag_lun != $lun )); then
11095                         cleanup_130
11096                         error "FIEMAP on 1-stripe file($fm_file) failed"
11097                         return
11098                 fi
11099                 (( tot_len += ext_len ))
11100         done
11101
11102         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11103                 cleanup_130
11104                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11105                 return
11106         fi
11107
11108         cleanup_130
11109
11110         echo "FIEMAP on single striped file succeeded"
11111 }
11112 run_test 130a "FIEMAP (1-stripe file)"
11113
11114 test_130b() {
11115         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11116
11117         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11118         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11119
11120         trap cleanup_130 EXIT RETURN
11121
11122         local fm_file=$DIR/$tfile
11123         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11124                         error "setstripe on $fm_file"
11125         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11126                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11127
11128         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11129                 error "dd failed on $fm_file"
11130
11131         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11132         filefrag_op=$(filefrag -ve -k $fm_file |
11133                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11134
11135         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11136                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11137
11138         IFS=$'\n'
11139         tot_len=0
11140         num_luns=1
11141         for line in $filefrag_op
11142         do
11143                 frag_lun=$(echo $line | cut -d: -f5 |
11144                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11145                 ext_len=$(echo $line | cut -d: -f4)
11146                 if (( $frag_lun != $last_lun )); then
11147                         if (( tot_len != 1024 )); then
11148                                 cleanup_130
11149                                 error "FIEMAP on $fm_file failed; returned " \
11150                                 "len $tot_len for OST $last_lun instead of 1024"
11151                                 return
11152                         else
11153                                 (( num_luns += 1 ))
11154                                 tot_len=0
11155                         fi
11156                 fi
11157                 (( tot_len += ext_len ))
11158                 last_lun=$frag_lun
11159         done
11160         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11161                 cleanup_130
11162                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11163                         "luns or wrong len for OST $last_lun"
11164                 return
11165         fi
11166
11167         cleanup_130
11168
11169         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11170 }
11171 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11172
11173 test_130c() {
11174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11175
11176         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11177         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11178
11179         trap cleanup_130 EXIT RETURN
11180
11181         local fm_file=$DIR/$tfile
11182         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11183         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11184                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11185
11186         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11187                         error "dd failed on $fm_file"
11188
11189         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11190         filefrag_op=$(filefrag -ve -k $fm_file |
11191                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11192
11193         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11194                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11195
11196         IFS=$'\n'
11197         tot_len=0
11198         num_luns=1
11199         for line in $filefrag_op
11200         do
11201                 frag_lun=$(echo $line | cut -d: -f5 |
11202                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11203                 ext_len=$(echo $line | cut -d: -f4)
11204                 if (( $frag_lun != $last_lun )); then
11205                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11206                         if (( logical != 512 )); then
11207                                 cleanup_130
11208                                 error "FIEMAP on $fm_file failed; returned " \
11209                                 "logical start for lun $logical instead of 512"
11210                                 return
11211                         fi
11212                         if (( tot_len != 512 )); then
11213                                 cleanup_130
11214                                 error "FIEMAP on $fm_file failed; returned " \
11215                                 "len $tot_len for OST $last_lun instead of 1024"
11216                                 return
11217                         else
11218                                 (( num_luns += 1 ))
11219                                 tot_len=0
11220                         fi
11221                 fi
11222                 (( tot_len += ext_len ))
11223                 last_lun=$frag_lun
11224         done
11225         if (( num_luns != 2 || tot_len != 512 )); then
11226                 cleanup_130
11227                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11228                         "luns or wrong len for OST $last_lun"
11229                 return
11230         fi
11231
11232         cleanup_130
11233
11234         echo "FIEMAP on 2-stripe file with hole succeeded"
11235 }
11236 run_test 130c "FIEMAP (2-stripe file with hole)"
11237
11238 test_130d() {
11239         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11240
11241         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11242         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11243
11244         trap cleanup_130 EXIT RETURN
11245
11246         local fm_file=$DIR/$tfile
11247         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11248                         error "setstripe on $fm_file"
11249         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11250                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11251
11252         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11253         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11254                 error "dd failed on $fm_file"
11255
11256         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11257         filefrag_op=$(filefrag -ve -k $fm_file |
11258                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11259
11260         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11261                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11262
11263         IFS=$'\n'
11264         tot_len=0
11265         num_luns=1
11266         for line in $filefrag_op
11267         do
11268                 frag_lun=$(echo $line | cut -d: -f5 |
11269                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11270                 ext_len=$(echo $line | cut -d: -f4)
11271                 if (( $frag_lun != $last_lun )); then
11272                         if (( tot_len != 1024 )); then
11273                                 cleanup_130
11274                                 error "FIEMAP on $fm_file failed; returned " \
11275                                 "len $tot_len for OST $last_lun instead of 1024"
11276                                 return
11277                         else
11278                                 (( num_luns += 1 ))
11279                                 tot_len=0
11280                         fi
11281                 fi
11282                 (( tot_len += ext_len ))
11283                 last_lun=$frag_lun
11284         done
11285         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11286                 cleanup_130
11287                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11288                         "luns or wrong len for OST $last_lun"
11289                 return
11290         fi
11291
11292         cleanup_130
11293
11294         echo "FIEMAP on N-stripe file succeeded"
11295 }
11296 run_test 130d "FIEMAP (N-stripe file)"
11297
11298 test_130e() {
11299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11300
11301         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11302         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11303
11304         trap cleanup_130 EXIT RETURN
11305
11306         local fm_file=$DIR/$tfile
11307         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11308         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11309                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11310
11311         NUM_BLKS=512
11312         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11313         for ((i = 0; i < $NUM_BLKS; i++))
11314         do
11315                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11316         done
11317
11318         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11319         filefrag_op=$(filefrag -ve -k $fm_file |
11320                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11321
11322         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11323                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11324
11325         IFS=$'\n'
11326         tot_len=0
11327         num_luns=1
11328         for line in $filefrag_op
11329         do
11330                 frag_lun=$(echo $line | cut -d: -f5 |
11331                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11332                 ext_len=$(echo $line | cut -d: -f4)
11333                 if (( $frag_lun != $last_lun )); then
11334                         if (( tot_len != $EXPECTED_LEN )); then
11335                                 cleanup_130
11336                                 error "FIEMAP on $fm_file failed; returned " \
11337                                 "len $tot_len for OST $last_lun instead " \
11338                                 "of $EXPECTED_LEN"
11339                                 return
11340                         else
11341                                 (( num_luns += 1 ))
11342                                 tot_len=0
11343                         fi
11344                 fi
11345                 (( tot_len += ext_len ))
11346                 last_lun=$frag_lun
11347         done
11348         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11349                 cleanup_130
11350                 error "FIEMAP on $fm_file failed; returned wrong number " \
11351                         "of luns or wrong len for OST $last_lun"
11352                 return
11353         fi
11354
11355         cleanup_130
11356
11357         echo "FIEMAP with continuation calls succeeded"
11358 }
11359 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11360
11361 test_130f() {
11362         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11363         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11364
11365         local fm_file=$DIR/$tfile
11366         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11367                 error "multiop create with lov_delay_create on $fm_file"
11368
11369         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11370         filefrag_extents=$(filefrag -vek $fm_file |
11371                            awk '/extents? found/ { print $2 }')
11372         if [[ "$filefrag_extents" != "0" ]]; then
11373                 error "FIEMAP on $fm_file failed; " \
11374                       "returned $filefrag_extents expected 0"
11375         fi
11376
11377         rm -f $fm_file
11378 }
11379 run_test 130f "FIEMAP (unstriped file)"
11380
11381 # Test for writev/readv
11382 test_131a() {
11383         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11384                 error "writev test failed"
11385         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11386                 error "readv failed"
11387         rm -f $DIR/$tfile
11388 }
11389 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11390
11391 test_131b() {
11392         local fsize=$((524288 + 1048576 + 1572864))
11393         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11394                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11395                         error "append writev test failed"
11396
11397         ((fsize += 1572864 + 1048576))
11398         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11399                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11400                         error "append writev test failed"
11401         rm -f $DIR/$tfile
11402 }
11403 run_test 131b "test append writev"
11404
11405 test_131c() {
11406         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11407         error "NOT PASS"
11408 }
11409 run_test 131c "test read/write on file w/o objects"
11410
11411 test_131d() {
11412         rwv -f $DIR/$tfile -w -n 1 1572864
11413         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11414         if [ "$NOB" != 1572864 ]; then
11415                 error "Short read filed: read $NOB bytes instead of 1572864"
11416         fi
11417         rm -f $DIR/$tfile
11418 }
11419 run_test 131d "test short read"
11420
11421 test_131e() {
11422         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11423         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11424         error "read hitting hole failed"
11425         rm -f $DIR/$tfile
11426 }
11427 run_test 131e "test read hitting hole"
11428
11429 check_stats() {
11430         local facet=$1
11431         local op=$2
11432         local want=${3:-0}
11433         local res
11434
11435         case $facet in
11436         mds*) res=$(do_facet $facet \
11437                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11438                  ;;
11439         ost*) res=$(do_facet $facet \
11440                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11441                  ;;
11442         *) error "Wrong facet '$facet'" ;;
11443         esac
11444         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11445         # if the argument $3 is zero, it means any stat increment is ok.
11446         if [[ $want -gt 0 ]]; then
11447                 local count=$(echo $res | awk '{ print $2 }')
11448                 [[ $count -ne $want ]] &&
11449                         error "The $op counter on $facet is $count, not $want"
11450         fi
11451 }
11452
11453 test_133a() {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455         remote_ost_nodsh && skip "remote OST with nodsh"
11456         remote_mds_nodsh && skip "remote MDS with nodsh"
11457         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11458                 skip_env "MDS doesn't support rename stats"
11459
11460         local testdir=$DIR/${tdir}/stats_testdir
11461
11462         mkdir -p $DIR/${tdir}
11463
11464         # clear stats.
11465         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11466         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11467
11468         # verify mdt stats first.
11469         mkdir ${testdir} || error "mkdir failed"
11470         check_stats $SINGLEMDS "mkdir" 1
11471         touch ${testdir}/${tfile} || error "touch failed"
11472         check_stats $SINGLEMDS "open" 1
11473         check_stats $SINGLEMDS "close" 1
11474         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11475                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11476                 check_stats $SINGLEMDS "mknod" 2
11477         }
11478         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11479         check_stats $SINGLEMDS "unlink" 1
11480         rm -f ${testdir}/${tfile} || error "file remove failed"
11481         check_stats $SINGLEMDS "unlink" 2
11482
11483         # remove working dir and check mdt stats again.
11484         rmdir ${testdir} || error "rmdir failed"
11485         check_stats $SINGLEMDS "rmdir" 1
11486
11487         local testdir1=$DIR/${tdir}/stats_testdir1
11488         mkdir -p ${testdir}
11489         mkdir -p ${testdir1}
11490         touch ${testdir1}/test1
11491         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11492         check_stats $SINGLEMDS "crossdir_rename" 1
11493
11494         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11495         check_stats $SINGLEMDS "samedir_rename" 1
11496
11497         rm -rf $DIR/${tdir}
11498 }
11499 run_test 133a "Verifying MDT stats ========================================"
11500
11501 test_133b() {
11502         local res
11503
11504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11505         remote_ost_nodsh && skip "remote OST with nodsh"
11506         remote_mds_nodsh && skip "remote MDS with nodsh"
11507
11508         local testdir=$DIR/${tdir}/stats_testdir
11509
11510         mkdir -p ${testdir} || error "mkdir failed"
11511         touch ${testdir}/${tfile} || error "touch failed"
11512         cancel_lru_locks mdc
11513
11514         # clear stats.
11515         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11516         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11517
11518         # extra mdt stats verification.
11519         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11520         check_stats $SINGLEMDS "setattr" 1
11521         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11522         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11523         then            # LU-1740
11524                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11525                 check_stats $SINGLEMDS "getattr" 1
11526         fi
11527         rm -rf $DIR/${tdir}
11528
11529         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11530         # so the check below is not reliable
11531         [ $MDSCOUNT -eq 1 ] || return 0
11532
11533         # Sleep to avoid a cached response.
11534         #define OBD_STATFS_CACHE_SECONDS 1
11535         sleep 2
11536         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11537         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11538         $LFS df || error "lfs failed"
11539         check_stats $SINGLEMDS "statfs" 1
11540
11541         # check aggregated statfs (LU-10018)
11542         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11543                 return 0
11544         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11545                 return 0
11546         sleep 2
11547         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11548         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11549         df $DIR
11550         check_stats $SINGLEMDS "statfs" 1
11551
11552         # We want to check that the client didn't send OST_STATFS to
11553         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11554         # extra care is needed here.
11555         if remote_mds; then
11556                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11557                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11558
11559                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11560                 [ "$res" ] && error "OST got STATFS"
11561         fi
11562
11563         return 0
11564 }
11565 run_test 133b "Verifying extra MDT stats =================================="
11566
11567 test_133c() {
11568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11569         remote_ost_nodsh && skip "remote OST with nodsh"
11570         remote_mds_nodsh && skip "remote MDS with nodsh"
11571
11572         local testdir=$DIR/$tdir/stats_testdir
11573
11574         test_mkdir -p $testdir
11575
11576         # verify obdfilter stats.
11577         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11578         sync
11579         cancel_lru_locks osc
11580         wait_delete_completed
11581
11582         # clear stats.
11583         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11584         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11585
11586         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11587                 error "dd failed"
11588         sync
11589         cancel_lru_locks osc
11590         check_stats ost1 "write" 1
11591
11592         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11593         check_stats ost1 "read" 1
11594
11595         > $testdir/$tfile || error "truncate failed"
11596         check_stats ost1 "punch" 1
11597
11598         rm -f $testdir/$tfile || error "file remove failed"
11599         wait_delete_completed
11600         check_stats ost1 "destroy" 1
11601
11602         rm -rf $DIR/$tdir
11603 }
11604 run_test 133c "Verifying OST stats ========================================"
11605
11606 order_2() {
11607         local value=$1
11608         local orig=$value
11609         local order=1
11610
11611         while [ $value -ge 2 ]; do
11612                 order=$((order*2))
11613                 value=$((value/2))
11614         done
11615
11616         if [ $orig -gt $order ]; then
11617                 order=$((order*2))
11618         fi
11619         echo $order
11620 }
11621
11622 size_in_KMGT() {
11623     local value=$1
11624     local size=('K' 'M' 'G' 'T');
11625     local i=0
11626     local size_string=$value
11627
11628     while [ $value -ge 1024 ]; do
11629         if [ $i -gt 3 ]; then
11630             #T is the biggest unit we get here, if that is bigger,
11631             #just return XXXT
11632             size_string=${value}T
11633             break
11634         fi
11635         value=$((value >> 10))
11636         if [ $value -lt 1024 ]; then
11637             size_string=${value}${size[$i]}
11638             break
11639         fi
11640         i=$((i + 1))
11641     done
11642
11643     echo $size_string
11644 }
11645
11646 get_rename_size() {
11647         local size=$1
11648         local context=${2:-.}
11649         local sample=$(do_facet $SINGLEMDS $LCTL \
11650                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11651                 grep -A1 $context |
11652                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11653         echo $sample
11654 }
11655
11656 test_133d() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658         remote_ost_nodsh && skip "remote OST with nodsh"
11659         remote_mds_nodsh && skip "remote MDS with nodsh"
11660         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11661                 skip_env "MDS doesn't support rename stats"
11662
11663         local testdir1=$DIR/${tdir}/stats_testdir1
11664         local testdir2=$DIR/${tdir}/stats_testdir2
11665         mkdir -p $DIR/${tdir}
11666
11667         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11668
11669         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11670         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11671
11672         createmany -o $testdir1/test 512 || error "createmany failed"
11673
11674         # check samedir rename size
11675         mv ${testdir1}/test0 ${testdir1}/test_0
11676
11677         local testdir1_size=$(ls -l $DIR/${tdir} |
11678                 awk '/stats_testdir1/ {print $5}')
11679         local testdir2_size=$(ls -l $DIR/${tdir} |
11680                 awk '/stats_testdir2/ {print $5}')
11681
11682         testdir1_size=$(order_2 $testdir1_size)
11683         testdir2_size=$(order_2 $testdir2_size)
11684
11685         testdir1_size=$(size_in_KMGT $testdir1_size)
11686         testdir2_size=$(size_in_KMGT $testdir2_size)
11687
11688         echo "source rename dir size: ${testdir1_size}"
11689         echo "target rename dir size: ${testdir2_size}"
11690
11691         local cmd="do_facet $SINGLEMDS $LCTL "
11692         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11693
11694         eval $cmd || error "$cmd failed"
11695         local samedir=$($cmd | grep 'same_dir')
11696         local same_sample=$(get_rename_size $testdir1_size)
11697         [ -z "$samedir" ] && error "samedir_rename_size count error"
11698         [[ $same_sample -eq 1 ]] ||
11699                 error "samedir_rename_size error $same_sample"
11700         echo "Check same dir rename stats success"
11701
11702         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11703
11704         # check crossdir rename size
11705         mv ${testdir1}/test_0 ${testdir2}/test_0
11706
11707         testdir1_size=$(ls -l $DIR/${tdir} |
11708                 awk '/stats_testdir1/ {print $5}')
11709         testdir2_size=$(ls -l $DIR/${tdir} |
11710                 awk '/stats_testdir2/ {print $5}')
11711
11712         testdir1_size=$(order_2 $testdir1_size)
11713         testdir2_size=$(order_2 $testdir2_size)
11714
11715         testdir1_size=$(size_in_KMGT $testdir1_size)
11716         testdir2_size=$(size_in_KMGT $testdir2_size)
11717
11718         echo "source rename dir size: ${testdir1_size}"
11719         echo "target rename dir size: ${testdir2_size}"
11720
11721         eval $cmd || error "$cmd failed"
11722         local crossdir=$($cmd | grep 'crossdir')
11723         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11724         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11725         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11726         [[ $src_sample -eq 1 ]] ||
11727                 error "crossdir_rename_size error $src_sample"
11728         [[ $tgt_sample -eq 1 ]] ||
11729                 error "crossdir_rename_size error $tgt_sample"
11730         echo "Check cross dir rename stats success"
11731         rm -rf $DIR/${tdir}
11732 }
11733 run_test 133d "Verifying rename_stats ========================================"
11734
11735 test_133e() {
11736         remote_mds_nodsh && skip "remote MDS with nodsh"
11737         remote_ost_nodsh && skip "remote OST with nodsh"
11738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11739
11740         local testdir=$DIR/${tdir}/stats_testdir
11741         local ctr f0 f1 bs=32768 count=42 sum
11742
11743         mkdir -p ${testdir} || error "mkdir failed"
11744
11745         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11746
11747         for ctr in {write,read}_bytes; do
11748                 sync
11749                 cancel_lru_locks osc
11750
11751                 do_facet ost1 $LCTL set_param -n \
11752                         "obdfilter.*.exports.clear=clear"
11753
11754                 if [ $ctr = write_bytes ]; then
11755                         f0=/dev/zero
11756                         f1=${testdir}/${tfile}
11757                 else
11758                         f0=${testdir}/${tfile}
11759                         f1=/dev/null
11760                 fi
11761
11762                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11763                         error "dd failed"
11764                 sync
11765                 cancel_lru_locks osc
11766
11767                 sum=$(do_facet ost1 $LCTL get_param \
11768                         "obdfilter.*.exports.*.stats" |
11769                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11770                                 $1 == ctr { sum += $7 }
11771                                 END { printf("%0.0f", sum) }')
11772
11773                 if ((sum != bs * count)); then
11774                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11775                 fi
11776         done
11777
11778         rm -rf $DIR/${tdir}
11779 }
11780 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11781
11782 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11783
11784 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11785 # not honor the -ignore_readdir_race option correctly. So we call
11786 # error_ignore() rather than error() in these cases. See LU-11152.
11787 error_133() {
11788         if (find --version; do_facet mds1 find --version) |
11789                 grep -q '\b4\.5\.1[1-4]\b'; then
11790                 error_ignore LU-11152 "$@"
11791         else
11792                 error "$@"
11793         fi
11794 }
11795
11796 test_133f() {
11797         # First without trusting modes.
11798         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11799         echo "proc_dirs='$proc_dirs'"
11800         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11801         find $proc_dirs -exec cat '{}' \; &> /dev/null
11802
11803         # Second verifying readability.
11804         $LCTL get_param -R '*' &> /dev/null
11805
11806         # Verifing writability with badarea_io.
11807         find $proc_dirs \
11808                 -ignore_readdir_race \
11809                 -type f \
11810                 -not -name force_lbug \
11811                 -not -name changelog_mask \
11812                 -exec badarea_io '{}' \; ||
11813                         error_133 "find $proc_dirs failed"
11814 }
11815 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11816
11817 test_133g() {
11818         remote_mds_nodsh && skip "remote MDS with nodsh"
11819         remote_ost_nodsh && skip "remote OST with nodsh"
11820
11821         # eventually, this can also be replaced with "lctl get_param -R",
11822         # but not until that option is always available on the server
11823         local facet
11824         for facet in mds1 ost1; do
11825                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11826                         skip_noexit "Too old lustre on $facet"
11827                 local facet_proc_dirs=$(do_facet $facet \
11828                                         \\\ls -d $proc_regexp 2>/dev/null)
11829                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11830                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11831                 do_facet $facet find $facet_proc_dirs \
11832                         ! -name req_history \
11833                         -exec cat '{}' \\\; &> /dev/null
11834
11835                 do_facet $facet find $facet_proc_dirs \
11836                         ! -name req_history \
11837                         -type f \
11838                         -exec cat '{}' \\\; &> /dev/null ||
11839                                 error "proc file read failed"
11840
11841                 do_facet $facet find $facet_proc_dirs \
11842                         -ignore_readdir_race \
11843                         -type f \
11844                         -not -name force_lbug \
11845                         -not -name changelog_mask \
11846                         -exec badarea_io '{}' \\\; ||
11847                                 error_133 "$facet find $facet_proc_dirs failed"
11848         done
11849
11850         # remount the FS in case writes/reads /proc break the FS
11851         cleanup || error "failed to unmount"
11852         setup || error "failed to setup"
11853         true
11854 }
11855 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11856
11857 test_133h() {
11858         remote_mds_nodsh && skip "remote MDS with nodsh"
11859         remote_ost_nodsh && skip "remote OST with nodsh"
11860         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11861                 skip "Need MDS version at least 2.9.54"
11862
11863         local facet
11864
11865         for facet in client mds1 ost1; do
11866                 local facet_proc_dirs=$(do_facet $facet \
11867                                         \\\ls -d $proc_regexp 2> /dev/null)
11868                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11869                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11870                 # Get the list of files that are missing the terminating newline
11871                 local missing=($(do_facet $facet \
11872                         find ${facet_proc_dirs} -type f \|              \
11873                                 while read F\; do                       \
11874                                         awk -v FS='\v' -v RS='\v\v'     \
11875                                         "'END { if(NR>0 &&              \
11876                                         \\\$NF !~ /.*\\\n\$/)           \
11877                                                 print FILENAME}'"       \
11878                                         '\$F'\;                         \
11879                                 done 2>/dev/null))
11880                 [ ${#missing[*]} -eq 0 ] ||
11881                         error "files do not end with newline: ${missing[*]}"
11882         done
11883 }
11884 run_test 133h "Proc files should end with newlines"
11885
11886 test_134a() {
11887         remote_mds_nodsh && skip "remote MDS with nodsh"
11888         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11889                 skip "Need MDS version at least 2.7.54"
11890
11891         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11892         cancel_lru_locks mdc
11893
11894         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11895         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11896         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11897
11898         local nr=1000
11899         createmany -o $DIR/$tdir/f $nr ||
11900                 error "failed to create $nr files in $DIR/$tdir"
11901         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11902
11903         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11904         do_facet mds1 $LCTL set_param fail_loc=0x327
11905         do_facet mds1 $LCTL set_param fail_val=500
11906         touch $DIR/$tdir/m
11907
11908         echo "sleep 10 seconds ..."
11909         sleep 10
11910         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11911
11912         do_facet mds1 $LCTL set_param fail_loc=0
11913         do_facet mds1 $LCTL set_param fail_val=0
11914         [ $lck_cnt -lt $unused ] ||
11915                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11916
11917         rm $DIR/$tdir/m
11918         unlinkmany $DIR/$tdir/f $nr
11919 }
11920 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11921
11922 test_134b() {
11923         remote_mds_nodsh && skip "remote MDS with nodsh"
11924         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11925                 skip "Need MDS version at least 2.7.54"
11926
11927         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11928         cancel_lru_locks mdc
11929
11930         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11931                         ldlm.lock_reclaim_threshold_mb)
11932         # disable reclaim temporarily
11933         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11934
11935         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11936         do_facet mds1 $LCTL set_param fail_loc=0x328
11937         do_facet mds1 $LCTL set_param fail_val=500
11938
11939         $LCTL set_param debug=+trace
11940
11941         local nr=600
11942         createmany -o $DIR/$tdir/f $nr &
11943         local create_pid=$!
11944
11945         echo "Sleep $TIMEOUT seconds ..."
11946         sleep $TIMEOUT
11947         if ! ps -p $create_pid  > /dev/null 2>&1; then
11948                 do_facet mds1 $LCTL set_param fail_loc=0
11949                 do_facet mds1 $LCTL set_param fail_val=0
11950                 do_facet mds1 $LCTL set_param \
11951                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11952                 error "createmany finished incorrectly!"
11953         fi
11954         do_facet mds1 $LCTL set_param fail_loc=0
11955         do_facet mds1 $LCTL set_param fail_val=0
11956         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11957         wait $create_pid || return 1
11958
11959         unlinkmany $DIR/$tdir/f $nr
11960 }
11961 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11962
11963 test_140() { #bug-17379
11964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11965
11966         test_mkdir $DIR/$tdir
11967         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11968         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11969
11970         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11971         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11972         local i=0
11973         while i=$((i + 1)); do
11974                 test_mkdir $i
11975                 cd $i || error "Changing to $i"
11976                 ln -s ../stat stat || error "Creating stat symlink"
11977                 # Read the symlink until ELOOP present,
11978                 # not LBUGing the system is considered success,
11979                 # we didn't overrun the stack.
11980                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11981                 if [ $ret -ne 0 ]; then
11982                         if [ $ret -eq 40 ]; then
11983                                 break  # -ELOOP
11984                         else
11985                                 error "Open stat symlink"
11986                                         return
11987                         fi
11988                 fi
11989         done
11990         i=$((i - 1))
11991         echo "The symlink depth = $i"
11992         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11993                 error "Invalid symlink depth"
11994
11995         # Test recursive symlink
11996         ln -s symlink_self symlink_self
11997         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11998         echo "open symlink_self returns $ret"
11999         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12000 }
12001 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12002
12003 test_150() {
12004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12005
12006         local TF="$TMP/$tfile"
12007
12008         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12009         cp $TF $DIR/$tfile
12010         cancel_lru_locks $OSC
12011         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12012         remount_client $MOUNT
12013         df -P $MOUNT
12014         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12015
12016         $TRUNCATE $TF 6000
12017         $TRUNCATE $DIR/$tfile 6000
12018         cancel_lru_locks $OSC
12019         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12020
12021         echo "12345" >>$TF
12022         echo "12345" >>$DIR/$tfile
12023         cancel_lru_locks $OSC
12024         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12025
12026         echo "12345" >>$TF
12027         echo "12345" >>$DIR/$tfile
12028         cancel_lru_locks $OSC
12029         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12030
12031         rm -f $TF
12032         true
12033 }
12034 run_test 150 "truncate/append tests"
12035
12036 #LU-2902 roc_hit was not able to read all values from lproc
12037 function roc_hit_init() {
12038         local list=$(comma_list $(osts_nodes))
12039         local dir=$DIR/$tdir-check
12040         local file=$dir/$tfile
12041         local BEFORE
12042         local AFTER
12043         local idx
12044
12045         test_mkdir $dir
12046         #use setstripe to do a write to every ost
12047         for i in $(seq 0 $((OSTCOUNT-1))); do
12048                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12049                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12050                 idx=$(printf %04x $i)
12051                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12052                         awk '$1 == "cache_access" {sum += $7}
12053                                 END { printf("%0.0f", sum) }')
12054
12055                 cancel_lru_locks osc
12056                 cat $file >/dev/null
12057
12058                 AFTER=$(get_osd_param $list *OST*$idx stats |
12059                         awk '$1 == "cache_access" {sum += $7}
12060                                 END { printf("%0.0f", sum) }')
12061
12062                 echo BEFORE:$BEFORE AFTER:$AFTER
12063                 if ! let "AFTER - BEFORE == 4"; then
12064                         rm -rf $dir
12065                         error "roc_hit is not safe to use"
12066                 fi
12067                 rm $file
12068         done
12069
12070         rm -rf $dir
12071 }
12072
12073 function roc_hit() {
12074         local list=$(comma_list $(osts_nodes))
12075         echo $(get_osd_param $list '' stats |
12076                 awk '$1 == "cache_hit" {sum += $7}
12077                         END { printf("%0.0f", sum) }')
12078 }
12079
12080 function set_cache() {
12081         local on=1
12082
12083         if [ "$2" == "off" ]; then
12084                 on=0;
12085         fi
12086         local list=$(comma_list $(osts_nodes))
12087         set_osd_param $list '' $1_cache_enable $on
12088
12089         cancel_lru_locks osc
12090 }
12091
12092 test_151() {
12093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12094         remote_ost_nodsh && skip "remote OST with nodsh"
12095
12096         local CPAGES=3
12097         local list=$(comma_list $(osts_nodes))
12098
12099         # check whether obdfilter is cache capable at all
12100         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12101                 skip "not cache-capable obdfilter"
12102         fi
12103
12104         # check cache is enabled on all obdfilters
12105         if get_osd_param $list '' read_cache_enable | grep 0; then
12106                 skip "oss cache is disabled"
12107         fi
12108
12109         set_osd_param $list '' writethrough_cache_enable 1
12110
12111         # check write cache is enabled on all obdfilters
12112         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12113                 skip "oss write cache is NOT enabled"
12114         fi
12115
12116         roc_hit_init
12117
12118         #define OBD_FAIL_OBD_NO_LRU  0x609
12119         do_nodes $list $LCTL set_param fail_loc=0x609
12120
12121         # pages should be in the case right after write
12122         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12123                 error "dd failed"
12124
12125         local BEFORE=$(roc_hit)
12126         cancel_lru_locks osc
12127         cat $DIR/$tfile >/dev/null
12128         local AFTER=$(roc_hit)
12129
12130         do_nodes $list $LCTL set_param fail_loc=0
12131
12132         if ! let "AFTER - BEFORE == CPAGES"; then
12133                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12134         fi
12135
12136         # the following read invalidates the cache
12137         cancel_lru_locks osc
12138         set_osd_param $list '' read_cache_enable 0
12139         cat $DIR/$tfile >/dev/null
12140
12141         # now data shouldn't be found in the cache
12142         BEFORE=$(roc_hit)
12143         cancel_lru_locks osc
12144         cat $DIR/$tfile >/dev/null
12145         AFTER=$(roc_hit)
12146         if let "AFTER - BEFORE != 0"; then
12147                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12148         fi
12149
12150         set_osd_param $list '' read_cache_enable 1
12151         rm -f $DIR/$tfile
12152 }
12153 run_test 151 "test cache on oss and controls ==============================="
12154
12155 test_152() {
12156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12157
12158         local TF="$TMP/$tfile"
12159
12160         # simulate ENOMEM during write
12161 #define OBD_FAIL_OST_NOMEM      0x226
12162         lctl set_param fail_loc=0x80000226
12163         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12164         cp $TF $DIR/$tfile
12165         sync || error "sync failed"
12166         lctl set_param fail_loc=0
12167
12168         # discard client's cache
12169         cancel_lru_locks osc
12170
12171         # simulate ENOMEM during read
12172         lctl set_param fail_loc=0x80000226
12173         cmp $TF $DIR/$tfile || error "cmp failed"
12174         lctl set_param fail_loc=0
12175
12176         rm -f $TF
12177 }
12178 run_test 152 "test read/write with enomem ============================"
12179
12180 test_153() {
12181         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12182 }
12183 run_test 153 "test if fdatasync does not crash ======================="
12184
12185 dot_lustre_fid_permission_check() {
12186         local fid=$1
12187         local ffid=$MOUNT/.lustre/fid/$fid
12188         local test_dir=$2
12189
12190         echo "stat fid $fid"
12191         stat $ffid > /dev/null || error "stat $ffid failed."
12192         echo "touch fid $fid"
12193         touch $ffid || error "touch $ffid failed."
12194         echo "write to fid $fid"
12195         cat /etc/hosts > $ffid || error "write $ffid failed."
12196         echo "read fid $fid"
12197         diff /etc/hosts $ffid || error "read $ffid failed."
12198         echo "append write to fid $fid"
12199         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12200         echo "rename fid $fid"
12201         mv $ffid $test_dir/$tfile.1 &&
12202                 error "rename $ffid to $tfile.1 should fail."
12203         touch $test_dir/$tfile.1
12204         mv $test_dir/$tfile.1 $ffid &&
12205                 error "rename $tfile.1 to $ffid should fail."
12206         rm -f $test_dir/$tfile.1
12207         echo "truncate fid $fid"
12208         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12209         echo "link fid $fid"
12210         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12211         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12212                 echo "setfacl fid $fid"
12213                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12214                 echo "getfacl fid $fid"
12215                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12216         fi
12217         echo "unlink fid $fid"
12218         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12219         echo "mknod fid $fid"
12220         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12221
12222         fid=[0xf00000400:0x1:0x0]
12223         ffid=$MOUNT/.lustre/fid/$fid
12224
12225         echo "stat non-exist fid $fid"
12226         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12227         echo "write to non-exist fid $fid"
12228         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12229         echo "link new fid $fid"
12230         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12231
12232         mkdir -p $test_dir/$tdir
12233         touch $test_dir/$tdir/$tfile
12234         fid=$($LFS path2fid $test_dir/$tdir)
12235         rc=$?
12236         [ $rc -ne 0 ] &&
12237                 error "error: could not get fid for $test_dir/$dir/$tfile."
12238
12239         ffid=$MOUNT/.lustre/fid/$fid
12240
12241         echo "ls $fid"
12242         ls $ffid > /dev/null || error "ls $ffid failed."
12243         echo "touch $fid/$tfile.1"
12244         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12245
12246         echo "touch $MOUNT/.lustre/fid/$tfile"
12247         touch $MOUNT/.lustre/fid/$tfile && \
12248                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12249
12250         echo "setxattr to $MOUNT/.lustre/fid"
12251         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12252
12253         echo "listxattr for $MOUNT/.lustre/fid"
12254         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12255
12256         echo "delxattr from $MOUNT/.lustre/fid"
12257         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12258
12259         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12260         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12261                 error "touch invalid fid should fail."
12262
12263         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12264         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12265                 error "touch non-normal fid should fail."
12266
12267         echo "rename $tdir to $MOUNT/.lustre/fid"
12268         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12269                 error "rename to $MOUNT/.lustre/fid should fail."
12270
12271         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12272         then            # LU-3547
12273                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12274                 local new_obf_mode=777
12275
12276                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12277                 chmod $new_obf_mode $DIR/.lustre/fid ||
12278                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12279
12280                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12281                 [ $obf_mode -eq $new_obf_mode ] ||
12282                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12283
12284                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12285                 chmod $old_obf_mode $DIR/.lustre/fid ||
12286                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12287         fi
12288
12289         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12290         fid=$($LFS path2fid $test_dir/$tfile-2)
12291
12292         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12293         then # LU-5424
12294                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12295                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12296                         error "create lov data thru .lustre failed"
12297         fi
12298         echo "cp /etc/passwd $test_dir/$tfile-2"
12299         cp /etc/passwd $test_dir/$tfile-2 ||
12300                 error "copy to $test_dir/$tfile-2 failed."
12301         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12302         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12303                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12304
12305         rm -rf $test_dir/tfile.lnk
12306         rm -rf $test_dir/$tfile-2
12307 }
12308
12309 test_154A() {
12310         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12311                 skip "Need MDS version at least 2.4.1"
12312
12313         local tf=$DIR/$tfile
12314         touch $tf
12315
12316         local fid=$($LFS path2fid $tf)
12317         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12318
12319         # check that we get the same pathname back
12320         local found=$($LFS fid2path $MOUNT "$fid")
12321         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12322         [ "$found" == "$tf" ] ||
12323                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12324 }
12325 run_test 154A "lfs path2fid and fid2path basic checks"
12326
12327 test_154B() {
12328         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12329                 skip "Need MDS version at least 2.4.1"
12330
12331         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12332         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12333         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12334         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12335
12336         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12337         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12338
12339         # check that we get the same pathname
12340         echo "PFID: $PFID, name: $name"
12341         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12342         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12343         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12344                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12345
12346         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12347 }
12348 run_test 154B "verify the ll_decode_linkea tool"
12349
12350 test_154a() {
12351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12352         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12353         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12354                 skip "Need MDS version at least 2.2.51"
12355         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12356
12357         cp /etc/hosts $DIR/$tfile
12358
12359         fid=$($LFS path2fid $DIR/$tfile)
12360         rc=$?
12361         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12362
12363         dot_lustre_fid_permission_check "$fid" $DIR ||
12364                 error "dot lustre permission check $fid failed"
12365
12366         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12367
12368         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12369
12370         touch $MOUNT/.lustre/file &&
12371                 error "creation is not allowed under .lustre"
12372
12373         mkdir $MOUNT/.lustre/dir &&
12374                 error "mkdir is not allowed under .lustre"
12375
12376         rm -rf $DIR/$tfile
12377 }
12378 run_test 154a "Open-by-FID"
12379
12380 test_154b() {
12381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12382         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12384         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12385                 skip "Need MDS version at least 2.2.51"
12386
12387         local remote_dir=$DIR/$tdir/remote_dir
12388         local MDTIDX=1
12389         local rc=0
12390
12391         mkdir -p $DIR/$tdir
12392         $LFS mkdir -i $MDTIDX $remote_dir ||
12393                 error "create remote directory failed"
12394
12395         cp /etc/hosts $remote_dir/$tfile
12396
12397         fid=$($LFS path2fid $remote_dir/$tfile)
12398         rc=$?
12399         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12400
12401         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12402                 error "dot lustre permission check $fid failed"
12403         rm -rf $DIR/$tdir
12404 }
12405 run_test 154b "Open-by-FID for remote directory"
12406
12407 test_154c() {
12408         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12409                 skip "Need MDS version at least 2.4.1"
12410
12411         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12412         local FID1=$($LFS path2fid $DIR/$tfile.1)
12413         local FID2=$($LFS path2fid $DIR/$tfile.2)
12414         local FID3=$($LFS path2fid $DIR/$tfile.3)
12415
12416         local N=1
12417         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12418                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12419                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12420                 local want=FID$N
12421                 [ "$FID" = "${!want}" ] ||
12422                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12423                 N=$((N + 1))
12424         done
12425
12426         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12427         do
12428                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12429                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12430                 N=$((N + 1))
12431         done
12432 }
12433 run_test 154c "lfs path2fid and fid2path multiple arguments"
12434
12435 test_154d() {
12436         remote_mds_nodsh && skip "remote MDS with nodsh"
12437         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12438                 skip "Need MDS version at least 2.5.53"
12439
12440         if remote_mds; then
12441                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12442         else
12443                 nid="0@lo"
12444         fi
12445         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12446         local fd
12447         local cmd
12448
12449         rm -f $DIR/$tfile
12450         touch $DIR/$tfile
12451
12452         local fid=$($LFS path2fid $DIR/$tfile)
12453         # Open the file
12454         fd=$(free_fd)
12455         cmd="exec $fd<$DIR/$tfile"
12456         eval $cmd
12457         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12458         echo "$fid_list" | grep "$fid"
12459         rc=$?
12460
12461         cmd="exec $fd>/dev/null"
12462         eval $cmd
12463         if [ $rc -ne 0 ]; then
12464                 error "FID $fid not found in open files list $fid_list"
12465         fi
12466 }
12467 run_test 154d "Verify open file fid"
12468
12469 test_154e()
12470 {
12471         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12472                 skip "Need MDS version at least 2.6.50"
12473
12474         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12475                 error ".lustre returned by readdir"
12476         fi
12477 }
12478 run_test 154e ".lustre is not returned by readdir"
12479
12480 test_154f() {
12481         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12482
12483         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12484         test_mkdir -p -c1 $DIR/$tdir/d
12485         # test dirs inherit from its stripe
12486         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12487         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12488         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12489         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12490         touch $DIR/f
12491
12492         # get fid of parents
12493         local FID0=$($LFS path2fid $DIR/$tdir/d)
12494         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12495         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12496         local FID3=$($LFS path2fid $DIR)
12497
12498         # check that path2fid --parents returns expected <parent_fid>/name
12499         # 1) test for a directory (single parent)
12500         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12501         [ "$parent" == "$FID0/foo1" ] ||
12502                 error "expected parent: $FID0/foo1, got: $parent"
12503
12504         # 2) test for a file with nlink > 1 (multiple parents)
12505         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12506         echo "$parent" | grep -F "$FID1/$tfile" ||
12507                 error "$FID1/$tfile not returned in parent list"
12508         echo "$parent" | grep -F "$FID2/link" ||
12509                 error "$FID2/link not returned in parent list"
12510
12511         # 3) get parent by fid
12512         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12513         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12514         echo "$parent" | grep -F "$FID1/$tfile" ||
12515                 error "$FID1/$tfile not returned in parent list (by fid)"
12516         echo "$parent" | grep -F "$FID2/link" ||
12517                 error "$FID2/link not returned in parent list (by fid)"
12518
12519         # 4) test for entry in root directory
12520         parent=$($LFS path2fid --parents $DIR/f)
12521         echo "$parent" | grep -F "$FID3/f" ||
12522                 error "$FID3/f not returned in parent list"
12523
12524         # 5) test it on root directory
12525         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12526                 error "$MOUNT should not have parents"
12527
12528         # enable xattr caching and check that linkea is correctly updated
12529         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12530         save_lustre_params client "llite.*.xattr_cache" > $save
12531         lctl set_param llite.*.xattr_cache 1
12532
12533         # 6.1) linkea update on rename
12534         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12535
12536         # get parents by fid
12537         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12538         # foo1 should no longer be returned in parent list
12539         echo "$parent" | grep -F "$FID1" &&
12540                 error "$FID1 should no longer be in parent list"
12541         # the new path should appear
12542         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12543                 error "$FID2/$tfile.moved is not in parent list"
12544
12545         # 6.2) linkea update on unlink
12546         rm -f $DIR/$tdir/d/foo2/link
12547         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12548         # foo2/link should no longer be returned in parent list
12549         echo "$parent" | grep -F "$FID2/link" &&
12550                 error "$FID2/link should no longer be in parent list"
12551         true
12552
12553         rm -f $DIR/f
12554         restore_lustre_params < $save
12555         rm -f $save
12556 }
12557 run_test 154f "get parent fids by reading link ea"
12558
12559 test_154g()
12560 {
12561         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12562         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12563            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12564                 skip "Need MDS version at least 2.6.92"
12565
12566         mkdir -p $DIR/$tdir
12567         llapi_fid_test -d $DIR/$tdir
12568 }
12569 run_test 154g "various llapi FID tests"
12570
12571 test_155_small_load() {
12572     local temp=$TMP/$tfile
12573     local file=$DIR/$tfile
12574
12575     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12576         error "dd of=$temp bs=6096 count=1 failed"
12577     cp $temp $file
12578     cancel_lru_locks $OSC
12579     cmp $temp $file || error "$temp $file differ"
12580
12581     $TRUNCATE $temp 6000
12582     $TRUNCATE $file 6000
12583     cmp $temp $file || error "$temp $file differ (truncate1)"
12584
12585     echo "12345" >>$temp
12586     echo "12345" >>$file
12587     cmp $temp $file || error "$temp $file differ (append1)"
12588
12589     echo "12345" >>$temp
12590     echo "12345" >>$file
12591     cmp $temp $file || error "$temp $file differ (append2)"
12592
12593     rm -f $temp $file
12594     true
12595 }
12596
12597 test_155_big_load() {
12598         remote_ost_nodsh && skip "remote OST with nodsh"
12599
12600         local temp=$TMP/$tfile
12601         local file=$DIR/$tfile
12602
12603         free_min_max
12604         local cache_size=$(do_facet ost$((MAXI+1)) \
12605                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12606         local large_file_size=$((cache_size * 2))
12607
12608         echo "OSS cache size: $cache_size KB"
12609         echo "Large file size: $large_file_size KB"
12610
12611         [ $MAXV -le $large_file_size ] &&
12612                 skip_env "max available OST size needs > $large_file_size KB"
12613
12614         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12615
12616         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12617                 error "dd of=$temp bs=$large_file_size count=1k failed"
12618         cp $temp $file
12619         ls -lh $temp $file
12620         cancel_lru_locks osc
12621         cmp $temp $file || error "$temp $file differ"
12622
12623         rm -f $temp $file
12624         true
12625 }
12626
12627 save_writethrough() {
12628         local facets=$(get_facets OST)
12629
12630         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12631 }
12632
12633 test_155a() {
12634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12635
12636         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12637
12638         save_writethrough $p
12639
12640         set_cache read on
12641         set_cache writethrough on
12642         test_155_small_load
12643         restore_lustre_params < $p
12644         rm -f $p
12645 }
12646 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12647
12648 test_155b() {
12649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12650
12651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12652
12653         save_writethrough $p
12654
12655         set_cache read on
12656         set_cache writethrough off
12657         test_155_small_load
12658         restore_lustre_params < $p
12659         rm -f $p
12660 }
12661 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12662
12663 test_155c() {
12664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12665
12666         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12667
12668         save_writethrough $p
12669
12670         set_cache read off
12671         set_cache writethrough on
12672         test_155_small_load
12673         restore_lustre_params < $p
12674         rm -f $p
12675 }
12676 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12677
12678 test_155d() {
12679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12680
12681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12682
12683         save_writethrough $p
12684
12685         set_cache read off
12686         set_cache writethrough off
12687         test_155_small_load
12688         restore_lustre_params < $p
12689         rm -f $p
12690 }
12691 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12692
12693 test_155e() {
12694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12695
12696         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12697
12698         save_writethrough $p
12699
12700         set_cache read on
12701         set_cache writethrough on
12702         test_155_big_load
12703         restore_lustre_params < $p
12704         rm -f $p
12705 }
12706 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12707
12708 test_155f() {
12709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12710
12711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12712
12713         save_writethrough $p
12714
12715         set_cache read on
12716         set_cache writethrough off
12717         test_155_big_load
12718         restore_lustre_params < $p
12719         rm -f $p
12720 }
12721 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12722
12723 test_155g() {
12724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12725
12726         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12727
12728         save_writethrough $p
12729
12730         set_cache read off
12731         set_cache writethrough on
12732         test_155_big_load
12733         restore_lustre_params < $p
12734         rm -f $p
12735 }
12736 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12737
12738 test_155h() {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740
12741         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12742
12743         save_writethrough $p
12744
12745         set_cache read off
12746         set_cache writethrough off
12747         test_155_big_load
12748         restore_lustre_params < $p
12749         rm -f $p
12750 }
12751 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12752
12753 test_156() {
12754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12755         remote_ost_nodsh && skip "remote OST with nodsh"
12756         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12757                 skip "stats not implemented on old servers"
12758         [ "$ost1_FSTYPE" = "zfs" ] &&
12759                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12760
12761         local CPAGES=3
12762         local BEFORE
12763         local AFTER
12764         local file="$DIR/$tfile"
12765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12766
12767         save_writethrough $p
12768         roc_hit_init
12769
12770         log "Turn on read and write cache"
12771         set_cache read on
12772         set_cache writethrough on
12773
12774         log "Write data and read it back."
12775         log "Read should be satisfied from the cache."
12776         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12777         BEFORE=$(roc_hit)
12778         cancel_lru_locks osc
12779         cat $file >/dev/null
12780         AFTER=$(roc_hit)
12781         if ! let "AFTER - BEFORE == CPAGES"; then
12782                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12783         else
12784                 log "cache hits:: before: $BEFORE, after: $AFTER"
12785         fi
12786
12787         log "Read again; it should be satisfied from the cache."
12788         BEFORE=$AFTER
12789         cancel_lru_locks osc
12790         cat $file >/dev/null
12791         AFTER=$(roc_hit)
12792         if ! let "AFTER - BEFORE == CPAGES"; then
12793                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12794         else
12795                 log "cache hits:: before: $BEFORE, after: $AFTER"
12796         fi
12797
12798         log "Turn off the read cache and turn on the write cache"
12799         set_cache read off
12800         set_cache writethrough on
12801
12802         log "Read again; it should be satisfied from the cache."
12803         BEFORE=$(roc_hit)
12804         cancel_lru_locks osc
12805         cat $file >/dev/null
12806         AFTER=$(roc_hit)
12807         if ! let "AFTER - BEFORE == CPAGES"; then
12808                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12809         else
12810                 log "cache hits:: before: $BEFORE, after: $AFTER"
12811         fi
12812
12813         log "Read again; it should not be satisfied from the cache."
12814         BEFORE=$AFTER
12815         cancel_lru_locks osc
12816         cat $file >/dev/null
12817         AFTER=$(roc_hit)
12818         if ! let "AFTER - BEFORE == 0"; then
12819                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12820         else
12821                 log "cache hits:: before: $BEFORE, after: $AFTER"
12822         fi
12823
12824         log "Write data and read it back."
12825         log "Read should be satisfied from the cache."
12826         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12827         BEFORE=$(roc_hit)
12828         cancel_lru_locks osc
12829         cat $file >/dev/null
12830         AFTER=$(roc_hit)
12831         if ! let "AFTER - BEFORE == CPAGES"; then
12832                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12833         else
12834                 log "cache hits:: before: $BEFORE, after: $AFTER"
12835         fi
12836
12837         log "Read again; it should not be satisfied from the cache."
12838         BEFORE=$AFTER
12839         cancel_lru_locks osc
12840         cat $file >/dev/null
12841         AFTER=$(roc_hit)
12842         if ! let "AFTER - BEFORE == 0"; then
12843                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12844         else
12845                 log "cache hits:: before: $BEFORE, after: $AFTER"
12846         fi
12847
12848         log "Turn off read and write cache"
12849         set_cache read off
12850         set_cache writethrough off
12851
12852         log "Write data and read it back"
12853         log "It should not be satisfied from the cache."
12854         rm -f $file
12855         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12856         cancel_lru_locks osc
12857         BEFORE=$(roc_hit)
12858         cat $file >/dev/null
12859         AFTER=$(roc_hit)
12860         if ! let "AFTER - BEFORE == 0"; then
12861                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12862         else
12863                 log "cache hits:: before: $BEFORE, after: $AFTER"
12864         fi
12865
12866         log "Turn on the read cache and turn off the write cache"
12867         set_cache read on
12868         set_cache writethrough off
12869
12870         log "Write data and read it back"
12871         log "It should not be satisfied from the cache."
12872         rm -f $file
12873         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12874         BEFORE=$(roc_hit)
12875         cancel_lru_locks osc
12876         cat $file >/dev/null
12877         AFTER=$(roc_hit)
12878         if ! let "AFTER - BEFORE == 0"; then
12879                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12880         else
12881                 log "cache hits:: before: $BEFORE, after: $AFTER"
12882         fi
12883
12884         log "Read again; it should be satisfied from the cache."
12885         BEFORE=$(roc_hit)
12886         cancel_lru_locks osc
12887         cat $file >/dev/null
12888         AFTER=$(roc_hit)
12889         if ! let "AFTER - BEFORE == CPAGES"; then
12890                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12891         else
12892                 log "cache hits:: before: $BEFORE, after: $AFTER"
12893         fi
12894
12895         restore_lustre_params < $p
12896         rm -f $p $file
12897 }
12898 run_test 156 "Verification of tunables"
12899
12900 test_160a() {
12901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12902         remote_mds_nodsh && skip "remote MDS with nodsh"
12903         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12904                 skip "Need MDS version at least 2.2.0"
12905
12906         changelog_register || error "changelog_register failed"
12907         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12908         changelog_users $SINGLEMDS | grep -q $cl_user ||
12909                 error "User $cl_user not found in changelog_users"
12910
12911         # change something
12912         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12913         changelog_clear 0 || error "changelog_clear failed"
12914         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12915         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12916         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12917         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12918         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12919         rm $DIR/$tdir/pics/desktop.jpg
12920
12921         changelog_dump | tail -10
12922
12923         echo "verifying changelog mask"
12924         changelog_chmask "-MKDIR"
12925         changelog_chmask "-CLOSE"
12926
12927         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12928         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12929
12930         changelog_chmask "+MKDIR"
12931         changelog_chmask "+CLOSE"
12932
12933         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12934         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12935
12936         changelog_dump | tail -10
12937         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12938         CLOSES=$(changelog_dump | grep -c "CLOSE")
12939         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12940         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12941
12942         # verify contents
12943         echo "verifying target fid"
12944         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12945         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12946         [ "$fidc" == "$fidf" ] ||
12947                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12948         echo "verifying parent fid"
12949         # The FID returned from the Changelog may be the directory shard on
12950         # a different MDT, and not the FID returned by path2fid on the parent.
12951         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12952         # since this is what will matter when recreating this file in the tree.
12953         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12954         local pathp=$($LFS fid2path $MOUNT "$fidp")
12955         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12956                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12957
12958         echo "getting records for $cl_user"
12959         changelog_users $SINGLEMDS
12960         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12961         local nclr=3
12962         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12963                 error "changelog_clear failed"
12964         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12965         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12966         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12967                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12968
12969         local min0_rec=$(changelog_users $SINGLEMDS |
12970                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12971         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12972                           awk '{ print $1; exit; }')
12973
12974         changelog_dump | tail -n 5
12975         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12976         [ $first_rec == $((min0_rec + 1)) ] ||
12977                 error "first index should be $min0_rec + 1 not $first_rec"
12978
12979         # LU-3446 changelog index reset on MDT restart
12980         local cur_rec1=$(changelog_users $SINGLEMDS |
12981                          awk '/^current.index:/ { print $NF }')
12982         changelog_clear 0 ||
12983                 error "clear all changelog records for $cl_user failed"
12984         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12985         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12986                 error "Fail to start $SINGLEMDS"
12987         local cur_rec2=$(changelog_users $SINGLEMDS |
12988                          awk '/^current.index:/ { print $NF }')
12989         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12990         [ $cur_rec1 == $cur_rec2 ] ||
12991                 error "current index should be $cur_rec1 not $cur_rec2"
12992
12993         echo "verifying users from this test are deregistered"
12994         changelog_deregister || error "changelog_deregister failed"
12995         changelog_users $SINGLEMDS | grep -q $cl_user &&
12996                 error "User '$cl_user' still in changelog_users"
12997
12998         # lctl get_param -n mdd.*.changelog_users
12999         # current index: 144
13000         # ID    index (idle seconds)
13001         # cl3   144 (2)
13002         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13003                 # this is the normal case where all users were deregistered
13004                 # make sure no new records are added when no users are present
13005                 local last_rec1=$(changelog_users $SINGLEMDS |
13006                                   awk '/^current.index:/ { print $NF }')
13007                 touch $DIR/$tdir/chloe
13008                 local last_rec2=$(changelog_users $SINGLEMDS |
13009                                   awk '/^current.index:/ { print $NF }')
13010                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13011                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13012         else
13013                 # any changelog users must be leftovers from a previous test
13014                 changelog_users $SINGLEMDS
13015                 echo "other changelog users; can't verify off"
13016         fi
13017 }
13018 run_test 160a "changelog sanity"
13019
13020 test_160b() { # LU-3587
13021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13022         remote_mds_nodsh && skip "remote MDS with nodsh"
13023         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13024                 skip "Need MDS version at least 2.2.0"
13025
13026         changelog_register || error "changelog_register failed"
13027         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13028         changelog_users $SINGLEMDS | grep -q $cl_user ||
13029                 error "User '$cl_user' not found in changelog_users"
13030
13031         local longname1=$(str_repeat a 255)
13032         local longname2=$(str_repeat b 255)
13033
13034         cd $DIR
13035         echo "creating very long named file"
13036         touch $longname1 || error "create of '$longname1' failed"
13037         echo "renaming very long named file"
13038         mv $longname1 $longname2
13039
13040         changelog_dump | grep RENME | tail -n 5
13041         rm -f $longname2
13042 }
13043 run_test 160b "Verify that very long rename doesn't crash in changelog"
13044
13045 test_160c() {
13046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13047         remote_mds_nodsh && skip "remote MDS with nodsh"
13048
13049         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13050                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13051                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13052                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13053
13054         local rc=0
13055
13056         # Registration step
13057         changelog_register || error "changelog_register failed"
13058
13059         rm -rf $DIR/$tdir
13060         mkdir -p $DIR/$tdir
13061         $MCREATE $DIR/$tdir/foo_160c
13062         changelog_chmask "-TRUNC"
13063         $TRUNCATE $DIR/$tdir/foo_160c 200
13064         changelog_chmask "+TRUNC"
13065         $TRUNCATE $DIR/$tdir/foo_160c 199
13066         changelog_dump | tail -n 5
13067         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13068         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13069 }
13070 run_test 160c "verify that changelog log catch the truncate event"
13071
13072 test_160d() {
13073         remote_mds_nodsh && skip "remote MDS with nodsh"
13074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13077                 skip "Need MDS version at least 2.7.60"
13078
13079         # Registration step
13080         changelog_register || error "changelog_register failed"
13081
13082         mkdir -p $DIR/$tdir/migrate_dir
13083         changelog_clear 0 || error "changelog_clear failed"
13084
13085         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13086         changelog_dump | tail -n 5
13087         local migrates=$(changelog_dump | grep -c "MIGRT")
13088         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13089 }
13090 run_test 160d "verify that changelog log catch the migrate event"
13091
13092 test_160e() {
13093         remote_mds_nodsh && skip "remote MDS with nodsh"
13094
13095         # Create a user
13096         changelog_register || error "changelog_register failed"
13097
13098         # Delete a future user (expect fail)
13099         local MDT0=$(facet_svc $SINGLEMDS)
13100         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13101         local rc=$?
13102
13103         if [ $rc -eq 0 ]; then
13104                 error "Deleted non-existant user cl77"
13105         elif [ $rc -ne 2 ]; then
13106                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13107         fi
13108
13109         # Clear to a bad index (1 billion should be safe)
13110         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13111         rc=$?
13112
13113         if [ $rc -eq 0 ]; then
13114                 error "Successfully cleared to invalid CL index"
13115         elif [ $rc -ne 22 ]; then
13116                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13117         fi
13118 }
13119 run_test 160e "changelog negative testing (should return errors)"
13120
13121 test_160f() {
13122         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13123         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13124                 skip "Need MDS version at least 2.10.56"
13125
13126         local mdts=$(comma_list $(mdts_nodes))
13127
13128         # Create a user
13129         changelog_register || error "first changelog_register failed"
13130         changelog_register || error "second changelog_register failed"
13131         local cl_users
13132         declare -A cl_user1
13133         declare -A cl_user2
13134         local user_rec1
13135         local user_rec2
13136         local i
13137
13138         # generate some changelog records to accumulate on each MDT
13139         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13140         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13141                 error "create $DIR/$tdir/$tfile failed"
13142
13143         # check changelogs have been generated
13144         local nbcl=$(changelog_dump | wc -l)
13145         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13146
13147         for param in "changelog_max_idle_time=10" \
13148                      "changelog_gc=1" \
13149                      "changelog_min_gc_interval=2" \
13150                      "changelog_min_free_cat_entries=3"; do
13151                 local MDT0=$(facet_svc $SINGLEMDS)
13152                 local var="${param%=*}"
13153                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13154
13155                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13156                 do_nodes $mdts $LCTL set_param mdd.*.$param
13157         done
13158
13159         # force cl_user2 to be idle (1st part)
13160         sleep 9
13161
13162         # simulate changelog catalog almost full
13163         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13164         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13165
13166         for i in $(seq $MDSCOUNT); do
13167                 cl_users=(${CL_USERS[mds$i]})
13168                 cl_user1[mds$i]="${cl_users[0]}"
13169                 cl_user2[mds$i]="${cl_users[1]}"
13170
13171                 [ -n "${cl_user1[mds$i]}" ] ||
13172                         error "mds$i: no user registered"
13173                 [ -n "${cl_user2[mds$i]}" ] ||
13174                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13175
13176                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13177                 [ -n "$user_rec1" ] ||
13178                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13179                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13180                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13181                 [ -n "$user_rec2" ] ||
13182                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13183                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13184                      "$user_rec1 + 2 == $user_rec2"
13185                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13186                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13187                               "$user_rec1 + 2, but is $user_rec2"
13188                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13189                 [ -n "$user_rec2" ] ||
13190                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13191                 [ $user_rec1 == $user_rec2 ] ||
13192                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13193                               "$user_rec1, but is $user_rec2"
13194         done
13195
13196         # force cl_user2 to be idle (2nd part) and to reach
13197         # changelog_max_idle_time
13198         sleep 2
13199
13200         # generate one more changelog to trigger fail_loc
13201         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13202                 error "create $DIR/$tdir/${tfile}bis failed"
13203
13204         # ensure gc thread is done
13205         for i in $(mdts_nodes); do
13206                 wait_update $i \
13207                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13208                         error "$i: GC-thread not done"
13209         done
13210
13211         local first_rec
13212         for i in $(seq $MDSCOUNT); do
13213                 # check cl_user1 still registered
13214                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13215                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13216                 # check cl_user2 unregistered
13217                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13218                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13219
13220                 # check changelogs are present and starting at $user_rec1 + 1
13221                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13222                 [ -n "$user_rec1" ] ||
13223                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13224                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13225                             awk '{ print $1; exit; }')
13226
13227                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13228                 [ $((user_rec1 + 1)) == $first_rec ] ||
13229                         error "mds$i: first index should be $user_rec1 + 1, " \
13230                               "but is $first_rec"
13231         done
13232 }
13233 run_test 160f "changelog garbage collect (timestamped users)"
13234
13235 test_160g() {
13236         remote_mds_nodsh && skip "remote MDS with nodsh"
13237         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13238                 skip "Need MDS version at least 2.10.56"
13239
13240         local mdts=$(comma_list $(mdts_nodes))
13241
13242         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13243         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13244
13245         # Create a user
13246         changelog_register || error "first changelog_register failed"
13247         changelog_register || error "second changelog_register failed"
13248         local cl_users
13249         declare -A cl_user1
13250         declare -A cl_user2
13251         local user_rec1
13252         local user_rec2
13253         local i
13254
13255         # generate some changelog records to accumulate on each MDT
13256         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13257         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13258                 error "create $DIR/$tdir/$tfile failed"
13259
13260         # check changelogs have been generated
13261         local nbcl=$(changelog_dump | wc -l)
13262         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13263
13264         # reduce the max_idle_indexes value to make sure we exceed it
13265         max_ndx=$((nbcl / 2 - 1))
13266
13267         for param in "changelog_max_idle_indexes=$max_ndx" \
13268                      "changelog_gc=1" \
13269                      "changelog_min_gc_interval=2" \
13270                      "changelog_min_free_cat_entries=3"; do
13271                 local MDT0=$(facet_svc $SINGLEMDS)
13272                 local var="${param%=*}"
13273                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13274
13275                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13276                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13277                         error "unable to set mdd.*.$param"
13278         done
13279
13280         # simulate changelog catalog almost full
13281         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13282         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13283
13284         for i in $(seq $MDSCOUNT); do
13285                 cl_users=(${CL_USERS[mds$i]})
13286                 cl_user1[mds$i]="${cl_users[0]}"
13287                 cl_user2[mds$i]="${cl_users[1]}"
13288
13289                 [ -n "${cl_user1[mds$i]}" ] ||
13290                         error "mds$i: no user registered"
13291                 [ -n "${cl_user2[mds$i]}" ] ||
13292                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13293
13294                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13295                 [ -n "$user_rec1" ] ||
13296                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13297                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13298                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13299                 [ -n "$user_rec2" ] ||
13300                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13301                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13302                      "$user_rec1 + 2 == $user_rec2"
13303                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13304                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13305                               "$user_rec1 + 2, but is $user_rec2"
13306                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13307                 [ -n "$user_rec2" ] ||
13308                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13309                 [ $user_rec1 == $user_rec2 ] ||
13310                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13311                               "$user_rec1, but is $user_rec2"
13312         done
13313
13314         # ensure we are past the previous changelog_min_gc_interval set above
13315         sleep 2
13316
13317         # generate one more changelog to trigger fail_loc
13318         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13319                 error "create $DIR/$tdir/${tfile}bis failed"
13320
13321         # ensure gc thread is done
13322         for i in $(mdts_nodes); do
13323                 wait_update $i \
13324                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13325                         error "$i: GC-thread not done"
13326         done
13327
13328         local first_rec
13329         for i in $(seq $MDSCOUNT); do
13330                 # check cl_user1 still registered
13331                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13332                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13333                 # check cl_user2 unregistered
13334                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13335                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13336
13337                 # check changelogs are present and starting at $user_rec1 + 1
13338                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13339                 [ -n "$user_rec1" ] ||
13340                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13341                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13342                             awk '{ print $1; exit; }')
13343
13344                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13345                 [ $((user_rec1 + 1)) == $first_rec ] ||
13346                         error "mds$i: first index should be $user_rec1 + 1, " \
13347                               "but is $first_rec"
13348         done
13349 }
13350 run_test 160g "changelog garbage collect (old users)"
13351
13352 test_160h() {
13353         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13354         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13355                 skip "Need MDS version at least 2.10.56"
13356
13357         local mdts=$(comma_list $(mdts_nodes))
13358
13359         # Create a user
13360         changelog_register || error "first changelog_register failed"
13361         changelog_register || error "second changelog_register failed"
13362         local cl_users
13363         declare -A cl_user1
13364         declare -A cl_user2
13365         local user_rec1
13366         local user_rec2
13367         local i
13368
13369         # generate some changelog records to accumulate on each MDT
13370         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13371         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13372                 error "create $DIR/$tdir/$tfile failed"
13373
13374         # check changelogs have been generated
13375         local nbcl=$(changelog_dump | wc -l)
13376         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13377
13378         for param in "changelog_max_idle_time=10" \
13379                      "changelog_gc=1" \
13380                      "changelog_min_gc_interval=2"; do
13381                 local MDT0=$(facet_svc $SINGLEMDS)
13382                 local var="${param%=*}"
13383                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13384
13385                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13386                 do_nodes $mdts $LCTL set_param mdd.*.$param
13387         done
13388
13389         # force cl_user2 to be idle (1st part)
13390         sleep 9
13391
13392         for i in $(seq $MDSCOUNT); do
13393                 cl_users=(${CL_USERS[mds$i]})
13394                 cl_user1[mds$i]="${cl_users[0]}"
13395                 cl_user2[mds$i]="${cl_users[1]}"
13396
13397                 [ -n "${cl_user1[mds$i]}" ] ||
13398                         error "mds$i: no user registered"
13399                 [ -n "${cl_user2[mds$i]}" ] ||
13400                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13401
13402                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13403                 [ -n "$user_rec1" ] ||
13404                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13405                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13406                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13407                 [ -n "$user_rec2" ] ||
13408                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13409                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13410                      "$user_rec1 + 2 == $user_rec2"
13411                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13412                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13413                               "$user_rec1 + 2, but is $user_rec2"
13414                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13415                 [ -n "$user_rec2" ] ||
13416                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13417                 [ $user_rec1 == $user_rec2 ] ||
13418                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13419                               "$user_rec1, but is $user_rec2"
13420         done
13421
13422         # force cl_user2 to be idle (2nd part) and to reach
13423         # changelog_max_idle_time
13424         sleep 2
13425
13426         # force each GC-thread start and block then
13427         # one per MDT/MDD, set fail_val accordingly
13428         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13429         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13430
13431         # generate more changelogs to trigger fail_loc
13432         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13433                 error "create $DIR/$tdir/${tfile}bis failed"
13434
13435         # stop MDT to stop GC-thread, should be done in back-ground as it will
13436         # block waiting for the thread to be released and exit
13437         declare -A stop_pids
13438         for i in $(seq $MDSCOUNT); do
13439                 stop mds$i &
13440                 stop_pids[mds$i]=$!
13441         done
13442
13443         for i in $(mdts_nodes); do
13444                 local facet
13445                 local nb=0
13446                 local facets=$(facets_up_on_host $i)
13447
13448                 for facet in ${facets//,/ }; do
13449                         if [[ $facet == mds* ]]; then
13450                                 nb=$((nb + 1))
13451                         fi
13452                 done
13453                 # ensure each MDS's gc threads are still present and all in "R"
13454                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13455                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13456                         error "$i: expected $nb GC-thread"
13457                 wait_update $i \
13458                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13459                         "R" 20 ||
13460                         error "$i: GC-thread not found in R-state"
13461                 # check umounts of each MDT on MDS have reached kthread_stop()
13462                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13463                         error "$i: expected $nb umount"
13464                 wait_update $i \
13465                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13466                         error "$i: umount not found in D-state"
13467         done
13468
13469         # release all GC-threads
13470         do_nodes $mdts $LCTL set_param fail_loc=0
13471
13472         # wait for MDT stop to complete
13473         for i in $(seq $MDSCOUNT); do
13474                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13475         done
13476
13477         # XXX
13478         # may try to check if any orphan changelog records are present
13479         # via ldiskfs/zfs and llog_reader...
13480
13481         # re-start/mount MDTs
13482         for i in $(seq $MDSCOUNT); do
13483                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13484                         error "Fail to start mds$i"
13485         done
13486
13487         local first_rec
13488         for i in $(seq $MDSCOUNT); do
13489                 # check cl_user1 still registered
13490                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13491                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13492                 # check cl_user2 unregistered
13493                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13494                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13495
13496                 # check changelogs are present and starting at $user_rec1 + 1
13497                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13498                 [ -n "$user_rec1" ] ||
13499                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13500                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13501                             awk '{ print $1; exit; }')
13502
13503                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13504                 [ $((user_rec1 + 1)) == $first_rec ] ||
13505                         error "mds$i: first index should be $user_rec1 + 1, " \
13506                               "but is $first_rec"
13507         done
13508 }
13509 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13510               "during mount"
13511
13512 test_160i() {
13513
13514         local mdts=$(comma_list $(mdts_nodes))
13515
13516         changelog_register || error "first changelog_register failed"
13517
13518         # generate some changelog records to accumulate on each MDT
13519         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13520         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13521                 error "create $DIR/$tdir/$tfile failed"
13522
13523         # check changelogs have been generated
13524         local nbcl=$(changelog_dump | wc -l)
13525         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13526
13527         # simulate race between register and unregister
13528         # XXX as fail_loc is set per-MDS, with DNE configs the race
13529         # simulation will only occur for one MDT per MDS and for the
13530         # others the normal race scenario will take place
13531         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13532         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13533         do_nodes $mdts $LCTL set_param fail_val=1
13534
13535         # unregister 1st user
13536         changelog_deregister &
13537         local pid1=$!
13538         # wait some time for deregister work to reach race rdv
13539         sleep 2
13540         # register 2nd user
13541         changelog_register || error "2nd user register failed"
13542
13543         wait $pid1 || error "1st user deregister failed"
13544
13545         local i
13546         local last_rec
13547         declare -A LAST_REC
13548         for i in $(seq $MDSCOUNT); do
13549                 if changelog_users mds$i | grep "^cl"; then
13550                         # make sure new records are added with one user present
13551                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13552                                           awk '/^current.index:/ { print $NF }')
13553                 else
13554                         error "mds$i has no user registered"
13555                 fi
13556         done
13557
13558         # generate more changelog records to accumulate on each MDT
13559         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13560                 error "create $DIR/$tdir/${tfile}bis failed"
13561
13562         for i in $(seq $MDSCOUNT); do
13563                 last_rec=$(changelog_users $SINGLEMDS |
13564                            awk '/^current.index:/ { print $NF }')
13565                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13566                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13567                         error "changelogs are off on mds$i"
13568         done
13569 }
13570 run_test 160i "changelog user register/unregister race"
13571
13572 test_161a() {
13573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13574
13575         test_mkdir -c1 $DIR/$tdir
13576         cp /etc/hosts $DIR/$tdir/$tfile
13577         test_mkdir -c1 $DIR/$tdir/foo1
13578         test_mkdir -c1 $DIR/$tdir/foo2
13579         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13580         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13581         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13582         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13583         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13584         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13585                 $LFS fid2path $DIR $FID
13586                 error "bad link ea"
13587         fi
13588         # middle
13589         rm $DIR/$tdir/foo2/zachary
13590         # last
13591         rm $DIR/$tdir/foo2/thor
13592         # first
13593         rm $DIR/$tdir/$tfile
13594         # rename
13595         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13596         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13597                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13598         rm $DIR/$tdir/foo2/maggie
13599
13600         # overflow the EA
13601         local longname=$tfile.avg_len_is_thirty_two_
13602         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13603                 error_noexit 'failed to unlink many hardlinks'" EXIT
13604         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13605                 error "failed to hardlink many files"
13606         links=$($LFS fid2path $DIR $FID | wc -l)
13607         echo -n "${links}/1000 links in link EA"
13608         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13609 }
13610 run_test 161a "link ea sanity"
13611
13612 test_161b() {
13613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13614         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13615
13616         local MDTIDX=1
13617         local remote_dir=$DIR/$tdir/remote_dir
13618
13619         mkdir -p $DIR/$tdir
13620         $LFS mkdir -i $MDTIDX $remote_dir ||
13621                 error "create remote directory failed"
13622
13623         cp /etc/hosts $remote_dir/$tfile
13624         mkdir -p $remote_dir/foo1
13625         mkdir -p $remote_dir/foo2
13626         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13627         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13628         ln $remote_dir/$tfile $remote_dir/foo1/luna
13629         ln $remote_dir/$tfile $remote_dir/foo2/thor
13630
13631         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13632                      tr -d ']')
13633         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13634                 $LFS fid2path $DIR $FID
13635                 error "bad link ea"
13636         fi
13637         # middle
13638         rm $remote_dir/foo2/zachary
13639         # last
13640         rm $remote_dir/foo2/thor
13641         # first
13642         rm $remote_dir/$tfile
13643         # rename
13644         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13645         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13646         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13647                 $LFS fid2path $DIR $FID
13648                 error "bad link rename"
13649         fi
13650         rm $remote_dir/foo2/maggie
13651
13652         # overflow the EA
13653         local longname=filename_avg_len_is_thirty_two_
13654         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13655                 error "failed to hardlink many files"
13656         links=$($LFS fid2path $DIR $FID | wc -l)
13657         echo -n "${links}/1000 links in link EA"
13658         [[ ${links} -gt 60 ]] ||
13659                 error "expected at least 60 links in link EA"
13660         unlinkmany $remote_dir/foo2/$longname 1000 ||
13661         error "failed to unlink many hardlinks"
13662 }
13663 run_test 161b "link ea sanity under remote directory"
13664
13665 test_161c() {
13666         remote_mds_nodsh && skip "remote MDS with nodsh"
13667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13668         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13669                 skip "Need MDS version at least 2.1.5"
13670
13671         # define CLF_RENAME_LAST 0x0001
13672         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13673         changelog_register || error "changelog_register failed"
13674
13675         rm -rf $DIR/$tdir
13676         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13677         touch $DIR/$tdir/foo_161c
13678         touch $DIR/$tdir/bar_161c
13679         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13680         changelog_dump | grep RENME | tail -n 5
13681         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13682         changelog_clear 0 || error "changelog_clear failed"
13683         if [ x$flags != "x0x1" ]; then
13684                 error "flag $flags is not 0x1"
13685         fi
13686
13687         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13688         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13689         touch $DIR/$tdir/foo_161c
13690         touch $DIR/$tdir/bar_161c
13691         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13692         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13693         changelog_dump | grep RENME | tail -n 5
13694         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13695         changelog_clear 0 || error "changelog_clear failed"
13696         if [ x$flags != "x0x0" ]; then
13697                 error "flag $flags is not 0x0"
13698         fi
13699         echo "rename overwrite a target having nlink > 1," \
13700                 "changelog record has flags of $flags"
13701
13702         # rename doesn't overwrite a target (changelog flag 0x0)
13703         touch $DIR/$tdir/foo_161c
13704         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13705         changelog_dump | grep RENME | tail -n 5
13706         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13707         changelog_clear 0 || error "changelog_clear failed"
13708         if [ x$flags != "x0x0" ]; then
13709                 error "flag $flags is not 0x0"
13710         fi
13711         echo "rename doesn't overwrite a target," \
13712                 "changelog record has flags of $flags"
13713
13714         # define CLF_UNLINK_LAST 0x0001
13715         # unlink a file having nlink = 1 (changelog flag 0x1)
13716         rm -f $DIR/$tdir/foo2_161c
13717         changelog_dump | grep UNLNK | tail -n 5
13718         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13719         changelog_clear 0 || error "changelog_clear failed"
13720         if [ x$flags != "x0x1" ]; then
13721                 error "flag $flags is not 0x1"
13722         fi
13723         echo "unlink a file having nlink = 1," \
13724                 "changelog record has flags of $flags"
13725
13726         # unlink a file having nlink > 1 (changelog flag 0x0)
13727         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13728         rm -f $DIR/$tdir/foobar_161c
13729         changelog_dump | grep UNLNK | tail -n 5
13730         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13731         changelog_clear 0 || error "changelog_clear failed"
13732         if [ x$flags != "x0x0" ]; then
13733                 error "flag $flags is not 0x0"
13734         fi
13735         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13736 }
13737 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13738
13739 test_161d() {
13740         remote_mds_nodsh && skip "remote MDS with nodsh"
13741         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13742
13743         local pid
13744         local fid
13745
13746         changelog_register || error "changelog_register failed"
13747
13748         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13749         # interfer with $MOUNT/.lustre/fid/ access
13750         mkdir $DIR/$tdir
13751         [[ $? -eq 0 ]] || error "mkdir failed"
13752
13753         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13754         $LCTL set_param fail_loc=0x8000140c
13755         # 5s pause
13756         $LCTL set_param fail_val=5
13757
13758         # create file
13759         echo foofoo > $DIR/$tdir/$tfile &
13760         pid=$!
13761
13762         # wait for create to be delayed
13763         sleep 2
13764
13765         ps -p $pid
13766         [[ $? -eq 0 ]] || error "create should be blocked"
13767
13768         local tempfile=$(mktemp)
13769         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13770         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13771         # some delay may occur during ChangeLog publishing and file read just
13772         # above, that could allow file write to happen finally
13773         [[ -s $tempfile ]] && echo "file should be empty"
13774
13775         $LCTL set_param fail_loc=0
13776
13777         wait $pid
13778         [[ $? -eq 0 ]] || error "create failed"
13779 }
13780 run_test 161d "create with concurrent .lustre/fid access"
13781
13782 check_path() {
13783         local expected="$1"
13784         shift
13785         local fid="$2"
13786
13787         local path
13788         path=$($LFS fid2path "$@")
13789         local rc=$?
13790
13791         if [ $rc -ne 0 ]; then
13792                 error "path looked up of '$expected' failed: rc=$rc"
13793         elif [ "$path" != "$expected" ]; then
13794                 error "path looked up '$path' instead of '$expected'"
13795         else
13796                 echo "FID '$fid' resolves to path '$path' as expected"
13797         fi
13798 }
13799
13800 test_162a() { # was test_162
13801         test_mkdir -p -c1 $DIR/$tdir/d2
13802         touch $DIR/$tdir/d2/$tfile
13803         touch $DIR/$tdir/d2/x1
13804         touch $DIR/$tdir/d2/x2
13805         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13806         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13807         # regular file
13808         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13809         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13810
13811         # softlink
13812         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13813         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13814         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13815
13816         # softlink to wrong file
13817         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13818         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13819         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13820
13821         # hardlink
13822         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13823         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13824         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13825         # fid2path dir/fsname should both work
13826         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13827         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13828
13829         # hardlink count: check that there are 2 links
13830         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13831         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13832
13833         # hardlink indexing: remove the first link
13834         rm $DIR/$tdir/d2/p/q/r/hlink
13835         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13836 }
13837 run_test 162a "path lookup sanity"
13838
13839 test_162b() {
13840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13842
13843         mkdir $DIR/$tdir
13844         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13845                                 error "create striped dir failed"
13846
13847         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13848                                         tail -n 1 | awk '{print $2}')
13849         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13850
13851         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13852         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13853
13854         # regular file
13855         for ((i=0;i<5;i++)); do
13856                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13857                         error "get fid for f$i failed"
13858                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13859
13860                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13861                         error "get fid for d$i failed"
13862                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13863         done
13864
13865         return 0
13866 }
13867 run_test 162b "striped directory path lookup sanity"
13868
13869 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13870 test_162c() {
13871         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13872                 skip "Need MDS version at least 2.7.51"
13873
13874         local lpath=$tdir.local
13875         local rpath=$tdir.remote
13876
13877         test_mkdir $DIR/$lpath
13878         test_mkdir $DIR/$rpath
13879
13880         for ((i = 0; i <= 101; i++)); do
13881                 lpath="$lpath/$i"
13882                 mkdir $DIR/$lpath
13883                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13884                         error "get fid for local directory $DIR/$lpath failed"
13885                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13886
13887                 rpath="$rpath/$i"
13888                 test_mkdir $DIR/$rpath
13889                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13890                         error "get fid for remote directory $DIR/$rpath failed"
13891                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13892         done
13893
13894         return 0
13895 }
13896 run_test 162c "fid2path works with paths 100 or more directories deep"
13897
13898 test_169() {
13899         # do directio so as not to populate the page cache
13900         log "creating a 10 Mb file"
13901         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13902         log "starting reads"
13903         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13904         log "truncating the file"
13905         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13906         log "killing dd"
13907         kill %+ || true # reads might have finished
13908         echo "wait until dd is finished"
13909         wait
13910         log "removing the temporary file"
13911         rm -rf $DIR/$tfile || error "tmp file removal failed"
13912 }
13913 run_test 169 "parallel read and truncate should not deadlock"
13914
13915 test_170() {
13916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13917
13918         $LCTL clear     # bug 18514
13919         $LCTL debug_daemon start $TMP/${tfile}_log_good
13920         touch $DIR/$tfile
13921         $LCTL debug_daemon stop
13922         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13923                 error "sed failed to read log_good"
13924
13925         $LCTL debug_daemon start $TMP/${tfile}_log_good
13926         rm -rf $DIR/$tfile
13927         $LCTL debug_daemon stop
13928
13929         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13930                error "lctl df log_bad failed"
13931
13932         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13933         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13934
13935         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13936         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13937
13938         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13939                 error "bad_line good_line1 good_line2 are empty"
13940
13941         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13942         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13943         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13944
13945         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13946         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13947         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13948
13949         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13950                 error "bad_line_new good_line_new are empty"
13951
13952         local expected_good=$((good_line1 + good_line2*2))
13953
13954         rm -f $TMP/${tfile}*
13955         # LU-231, short malformed line may not be counted into bad lines
13956         if [ $bad_line -ne $bad_line_new ] &&
13957                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13958                 error "expected $bad_line bad lines, but got $bad_line_new"
13959                 return 1
13960         fi
13961
13962         if [ $expected_good -ne $good_line_new ]; then
13963                 error "expected $expected_good good lines, but got $good_line_new"
13964                 return 2
13965         fi
13966         true
13967 }
13968 run_test 170 "test lctl df to handle corrupted log ====================="
13969
13970 test_171() { # bug20592
13971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13972
13973         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13974         $LCTL set_param fail_loc=0x50e
13975         $LCTL set_param fail_val=3000
13976         multiop_bg_pause $DIR/$tfile O_s || true
13977         local MULTIPID=$!
13978         kill -USR1 $MULTIPID
13979         # cause log dump
13980         sleep 3
13981         wait $MULTIPID
13982         if dmesg | grep "recursive fault"; then
13983                 error "caught a recursive fault"
13984         fi
13985         $LCTL set_param fail_loc=0
13986         true
13987 }
13988 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13989
13990 # it would be good to share it with obdfilter-survey/iokit-libecho code
13991 setup_obdecho_osc () {
13992         local rc=0
13993         local ost_nid=$1
13994         local obdfilter_name=$2
13995         echo "Creating new osc for $obdfilter_name on $ost_nid"
13996         # make sure we can find loopback nid
13997         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13998
13999         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14000                            ${obdfilter_name}_osc_UUID || rc=2; }
14001         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14002                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14003         return $rc
14004 }
14005
14006 cleanup_obdecho_osc () {
14007         local obdfilter_name=$1
14008         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14009         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14010         return 0
14011 }
14012
14013 obdecho_test() {
14014         local OBD=$1
14015         local node=$2
14016         local pages=${3:-64}
14017         local rc=0
14018         local id
14019
14020         local count=10
14021         local obd_size=$(get_obd_size $node $OBD)
14022         local page_size=$(get_page_size $node)
14023         if [[ -n "$obd_size" ]]; then
14024                 local new_count=$((obd_size / (pages * page_size / 1024)))
14025                 [[ $new_count -ge $count ]] || count=$new_count
14026         fi
14027
14028         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14029         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14030                            rc=2; }
14031         if [ $rc -eq 0 ]; then
14032             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14033             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14034         fi
14035         echo "New object id is $id"
14036         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14037                            rc=4; }
14038         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14039                            "test_brw $count w v $pages $id" || rc=4; }
14040         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14041                            rc=4; }
14042         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14043                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14044         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14045                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14046         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14047         return $rc
14048 }
14049
14050 test_180a() {
14051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14052
14053         if ! module_loaded obdecho; then
14054                 load_module obdecho/obdecho &&
14055                         stack_trap "rmmod obdecho" EXIT ||
14056                         error "unable to load obdecho on client"
14057         fi
14058
14059         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14060         local host=$($LCTL get_param -n osc.$osc.import |
14061                      awk '/current_connection:/ { print $2 }' )
14062         local target=$($LCTL get_param -n osc.$osc.import |
14063                        awk '/target:/ { print $2 }' )
14064         target=${target%_UUID}
14065
14066         if [ -n "$target" ]; then
14067                 setup_obdecho_osc $host $target &&
14068                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14069                         { error "obdecho setup failed with $?"; return; }
14070
14071                 obdecho_test ${target}_osc client ||
14072                         error "obdecho_test failed on ${target}_osc"
14073         else
14074                 $LCTL get_param osc.$osc.import
14075                 error "there is no osc.$osc.import target"
14076         fi
14077 }
14078 run_test 180a "test obdecho on osc"
14079
14080 test_180b() {
14081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14082         remote_ost_nodsh && skip "remote OST with nodsh"
14083
14084         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14085                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14086                 error "failed to load module obdecho"
14087
14088         local target=$(do_facet ost1 $LCTL dl |
14089                        awk '/obdfilter/ { print $4; exit; }')
14090
14091         if [ -n "$target" ]; then
14092                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14093         else
14094                 do_facet ost1 $LCTL dl
14095                 error "there is no obdfilter target on ost1"
14096         fi
14097 }
14098 run_test 180b "test obdecho directly on obdfilter"
14099
14100 test_180c() { # LU-2598
14101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14102         remote_ost_nodsh && skip "remote OST with nodsh"
14103         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14104                 skip "Need MDS version at least 2.4.0"
14105
14106         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14107                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14108                 error "failed to load module obdecho"
14109
14110         local target=$(do_facet ost1 $LCTL dl |
14111                        awk '/obdfilter/ { print $4; exit; }')
14112
14113         if [ -n "$target" ]; then
14114                 local pages=16384 # 64MB bulk I/O RPC size
14115
14116                 obdecho_test "$target" ost1 "$pages" ||
14117                         error "obdecho_test with pages=$pages failed with $?"
14118         else
14119                 do_facet ost1 $LCTL dl
14120                 error "there is no obdfilter target on ost1"
14121         fi
14122 }
14123 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14124
14125 test_181() { # bug 22177
14126         test_mkdir $DIR/$tdir
14127         # create enough files to index the directory
14128         createmany -o $DIR/$tdir/foobar 4000
14129         # print attributes for debug purpose
14130         lsattr -d .
14131         # open dir
14132         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14133         MULTIPID=$!
14134         # remove the files & current working dir
14135         unlinkmany $DIR/$tdir/foobar 4000
14136         rmdir $DIR/$tdir
14137         kill -USR1 $MULTIPID
14138         wait $MULTIPID
14139         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14140         return 0
14141 }
14142 run_test 181 "Test open-unlinked dir ========================"
14143
14144 test_182() {
14145         local fcount=1000
14146         local tcount=10
14147
14148         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14149
14150         $LCTL set_param mdc.*.rpc_stats=clear
14151
14152         for (( i = 0; i < $tcount; i++ )) ; do
14153                 mkdir $DIR/$tdir/$i
14154         done
14155
14156         for (( i = 0; i < $tcount; i++ )) ; do
14157                 createmany -o $DIR/$tdir/$i/f- $fcount &
14158         done
14159         wait
14160
14161         for (( i = 0; i < $tcount; i++ )) ; do
14162                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14163         done
14164         wait
14165
14166         $LCTL get_param mdc.*.rpc_stats
14167
14168         rm -rf $DIR/$tdir
14169 }
14170 run_test 182 "Test parallel modify metadata operations ================"
14171
14172 test_183() { # LU-2275
14173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14174         remote_mds_nodsh && skip "remote MDS with nodsh"
14175         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14176                 skip "Need MDS version at least 2.3.56"
14177
14178         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14179         echo aaa > $DIR/$tdir/$tfile
14180
14181 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14182         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14183
14184         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14185         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14186
14187         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14188
14189         # Flush negative dentry cache
14190         touch $DIR/$tdir/$tfile
14191
14192         # We are not checking for any leaked references here, they'll
14193         # become evident next time we do cleanup with module unload.
14194         rm -rf $DIR/$tdir
14195 }
14196 run_test 183 "No crash or request leak in case of strange dispositions ========"
14197
14198 # test suite 184 is for LU-2016, LU-2017
14199 test_184a() {
14200         check_swap_layouts_support
14201
14202         dir0=$DIR/$tdir/$testnum
14203         test_mkdir -p -c1 $dir0
14204         ref1=/etc/passwd
14205         ref2=/etc/group
14206         file1=$dir0/f1
14207         file2=$dir0/f2
14208         $LFS setstripe -c1 $file1
14209         cp $ref1 $file1
14210         $LFS setstripe -c2 $file2
14211         cp $ref2 $file2
14212         gen1=$($LFS getstripe -g $file1)
14213         gen2=$($LFS getstripe -g $file2)
14214
14215         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14216         gen=$($LFS getstripe -g $file1)
14217         [[ $gen1 != $gen ]] ||
14218                 "Layout generation on $file1 does not change"
14219         gen=$($LFS getstripe -g $file2)
14220         [[ $gen2 != $gen ]] ||
14221                 "Layout generation on $file2 does not change"
14222
14223         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14224         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14225
14226         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14227 }
14228 run_test 184a "Basic layout swap"
14229
14230 test_184b() {
14231         check_swap_layouts_support
14232
14233         dir0=$DIR/$tdir/$testnum
14234         mkdir -p $dir0 || error "creating dir $dir0"
14235         file1=$dir0/f1
14236         file2=$dir0/f2
14237         file3=$dir0/f3
14238         dir1=$dir0/d1
14239         dir2=$dir0/d2
14240         mkdir $dir1 $dir2
14241         $LFS setstripe -c1 $file1
14242         $LFS setstripe -c2 $file2
14243         $LFS setstripe -c1 $file3
14244         chown $RUNAS_ID $file3
14245         gen1=$($LFS getstripe -g $file1)
14246         gen2=$($LFS getstripe -g $file2)
14247
14248         $LFS swap_layouts $dir1 $dir2 &&
14249                 error "swap of directories layouts should fail"
14250         $LFS swap_layouts $dir1 $file1 &&
14251                 error "swap of directory and file layouts should fail"
14252         $RUNAS $LFS swap_layouts $file1 $file2 &&
14253                 error "swap of file we cannot write should fail"
14254         $LFS swap_layouts $file1 $file3 &&
14255                 error "swap of file with different owner should fail"
14256         /bin/true # to clear error code
14257 }
14258 run_test 184b "Forbidden layout swap (will generate errors)"
14259
14260 test_184c() {
14261         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14262         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14263         check_swap_layouts_support
14264
14265         local dir0=$DIR/$tdir/$testnum
14266         mkdir -p $dir0 || error "creating dir $dir0"
14267
14268         local ref1=$dir0/ref1
14269         local ref2=$dir0/ref2
14270         local file1=$dir0/file1
14271         local file2=$dir0/file2
14272         # create a file large enough for the concurrent test
14273         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14274         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14275         echo "ref file size: ref1($(stat -c %s $ref1))," \
14276              "ref2($(stat -c %s $ref2))"
14277
14278         cp $ref2 $file2
14279         dd if=$ref1 of=$file1 bs=16k &
14280         local DD_PID=$!
14281
14282         # Make sure dd starts to copy file
14283         while [ ! -f $file1 ]; do sleep 0.1; done
14284
14285         $LFS swap_layouts $file1 $file2
14286         local rc=$?
14287         wait $DD_PID
14288         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14289         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14290
14291         # how many bytes copied before swapping layout
14292         local copied=$(stat -c %s $file2)
14293         local remaining=$(stat -c %s $ref1)
14294         remaining=$((remaining - copied))
14295         echo "Copied $copied bytes before swapping layout..."
14296
14297         cmp -n $copied $file1 $ref2 | grep differ &&
14298                 error "Content mismatch [0, $copied) of ref2 and file1"
14299         cmp -n $copied $file2 $ref1 ||
14300                 error "Content mismatch [0, $copied) of ref1 and file2"
14301         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14302                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14303
14304         # clean up
14305         rm -f $ref1 $ref2 $file1 $file2
14306 }
14307 run_test 184c "Concurrent write and layout swap"
14308
14309 test_184d() {
14310         check_swap_layouts_support
14311         [ -z "$(which getfattr 2>/dev/null)" ] &&
14312                 skip_env "no getfattr command"
14313
14314         local file1=$DIR/$tdir/$tfile-1
14315         local file2=$DIR/$tdir/$tfile-2
14316         local file3=$DIR/$tdir/$tfile-3
14317         local lovea1
14318         local lovea2
14319
14320         mkdir -p $DIR/$tdir
14321         touch $file1 || error "create $file1 failed"
14322         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14323                 error "create $file2 failed"
14324         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14325                 error "create $file3 failed"
14326         lovea1=$(get_layout_param $file1)
14327
14328         $LFS swap_layouts $file2 $file3 ||
14329                 error "swap $file2 $file3 layouts failed"
14330         $LFS swap_layouts $file1 $file2 ||
14331                 error "swap $file1 $file2 layouts failed"
14332
14333         lovea2=$(get_layout_param $file2)
14334         echo "$lovea1"
14335         echo "$lovea2"
14336         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14337
14338         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14339         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14340 }
14341 run_test 184d "allow stripeless layouts swap"
14342
14343 test_184e() {
14344         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14345                 skip "Need MDS version at least 2.6.94"
14346         check_swap_layouts_support
14347         [ -z "$(which getfattr 2>/dev/null)" ] &&
14348                 skip_env "no getfattr command"
14349
14350         local file1=$DIR/$tdir/$tfile-1
14351         local file2=$DIR/$tdir/$tfile-2
14352         local file3=$DIR/$tdir/$tfile-3
14353         local lovea
14354
14355         mkdir -p $DIR/$tdir
14356         touch $file1 || error "create $file1 failed"
14357         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14358                 error "create $file2 failed"
14359         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14360                 error "create $file3 failed"
14361
14362         $LFS swap_layouts $file1 $file2 ||
14363                 error "swap $file1 $file2 layouts failed"
14364
14365         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14366         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14367
14368         echo 123 > $file1 || error "Should be able to write into $file1"
14369
14370         $LFS swap_layouts $file1 $file3 ||
14371                 error "swap $file1 $file3 layouts failed"
14372
14373         echo 123 > $file1 || error "Should be able to write into $file1"
14374
14375         rm -rf $file1 $file2 $file3
14376 }
14377 run_test 184e "Recreate layout after stripeless layout swaps"
14378
14379 test_184f() {
14380         # Create a file with name longer than sizeof(struct stat) ==
14381         # 144 to see if we can get chars from the file name to appear
14382         # in the returned striping. Note that 'f' == 0x66.
14383         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14384
14385         mkdir -p $DIR/$tdir
14386         mcreate $DIR/$tdir/$file
14387         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14388                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14389         fi
14390 }
14391 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14392
14393 test_185() { # LU-2441
14394         # LU-3553 - no volatile file support in old servers
14395         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14396                 skip "Need MDS version at least 2.3.60"
14397
14398         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14399         touch $DIR/$tdir/spoo
14400         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14401         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14402                 error "cannot create/write a volatile file"
14403         [ "$FILESET" == "" ] &&
14404         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14405                 error "FID is still valid after close"
14406
14407         multiop_bg_pause $DIR/$tdir vVw4096_c
14408         local multi_pid=$!
14409
14410         local OLD_IFS=$IFS
14411         IFS=":"
14412         local fidv=($fid)
14413         IFS=$OLD_IFS
14414         # assume that the next FID for this client is sequential, since stdout
14415         # is unfortunately eaten by multiop_bg_pause
14416         local n=$((${fidv[1]} + 1))
14417         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14418         if [ "$FILESET" == "" ]; then
14419                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14420                         error "FID is missing before close"
14421         fi
14422         kill -USR1 $multi_pid
14423         # 1 second delay, so if mtime change we will see it
14424         sleep 1
14425         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14426         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14427 }
14428 run_test 185 "Volatile file support"
14429
14430 test_187a() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14433                 skip "Need MDS version at least 2.3.0"
14434
14435         local dir0=$DIR/$tdir/$testnum
14436         mkdir -p $dir0 || error "creating dir $dir0"
14437
14438         local file=$dir0/file1
14439         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14440         local dv1=$($LFS data_version $file)
14441         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14442         local dv2=$($LFS data_version $file)
14443         [[ $dv1 != $dv2 ]] ||
14444                 error "data version did not change on write $dv1 == $dv2"
14445
14446         # clean up
14447         rm -f $file1
14448 }
14449 run_test 187a "Test data version change"
14450
14451 test_187b() {
14452         remote_mds_nodsh && skip "remote MDS with nodsh"
14453         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14454                 skip "Need MDS version at least 2.3.0"
14455
14456         local dir0=$DIR/$tdir/$testnum
14457         mkdir -p $dir0 || error "creating dir $dir0"
14458
14459         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14460         [[ ${DV[0]} != ${DV[1]} ]] ||
14461                 error "data version did not change on write"\
14462                       " ${DV[0]} == ${DV[1]}"
14463
14464         # clean up
14465         rm -f $file1
14466 }
14467 run_test 187b "Test data version change on volatile file"
14468
14469 test_200() {
14470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14471         remote_mgs_nodsh && skip "remote MGS with nodsh"
14472         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14473
14474         local POOL=${POOL:-cea1}
14475         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14476         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14477         # Pool OST targets
14478         local first_ost=0
14479         local last_ost=$(($OSTCOUNT - 1))
14480         local ost_step=2
14481         local ost_list=$(seq $first_ost $ost_step $last_ost)
14482         local ost_range="$first_ost $last_ost $ost_step"
14483         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14484         local file_dir=$POOL_ROOT/file_tst
14485         local subdir=$test_path/subdir
14486         local rc=0
14487
14488         if ! combined_mgs_mds ; then
14489                 mount_mgs_client
14490         fi
14491
14492         while : ; do
14493                 # former test_200a test_200b
14494                 pool_add $POOL                          || { rc=$? ; break; }
14495                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14496                 # former test_200c test_200d
14497                 mkdir -p $test_path
14498                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14499                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14500                 mkdir -p $subdir
14501                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14502                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14503                                                         || { rc=$? ; break; }
14504                 # former test_200e test_200f
14505                 local files=$((OSTCOUNT*3))
14506                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14507                                                         || { rc=$? ; break; }
14508                 pool_create_files $POOL $file_dir $files "$ost_list" \
14509                                                         || { rc=$? ; break; }
14510                 # former test_200g test_200h
14511                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14512                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14513
14514                 # former test_201a test_201b test_201c
14515                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14516
14517                 local f=$test_path/$tfile
14518                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14519                 pool_remove $POOL $f                    || { rc=$? ; break; }
14520                 break
14521         done
14522
14523         destroy_test_pools
14524
14525         if ! combined_mgs_mds ; then
14526                 umount_mgs_client
14527         fi
14528         return $rc
14529 }
14530 run_test 200 "OST pools"
14531
14532 # usage: default_attr <count | size | offset>
14533 default_attr() {
14534         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14535 }
14536
14537 # usage: check_default_stripe_attr
14538 check_default_stripe_attr() {
14539         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14540         case $1 in
14541         --stripe-count|-c)
14542                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14543         --stripe-size|-S)
14544                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14545         --stripe-index|-i)
14546                 EXPECTED=-1;;
14547         *)
14548                 error "unknown getstripe attr '$1'"
14549         esac
14550
14551         [ $ACTUAL == $EXPECTED ] ||
14552                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14553 }
14554
14555 test_204a() {
14556         test_mkdir $DIR/$tdir
14557         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14558
14559         check_default_stripe_attr --stripe-count
14560         check_default_stripe_attr --stripe-size
14561         check_default_stripe_attr --stripe-index
14562 }
14563 run_test 204a "Print default stripe attributes"
14564
14565 test_204b() {
14566         test_mkdir $DIR/$tdir
14567         $LFS setstripe --stripe-count 1 $DIR/$tdir
14568
14569         check_default_stripe_attr --stripe-size
14570         check_default_stripe_attr --stripe-index
14571 }
14572 run_test 204b "Print default stripe size and offset"
14573
14574 test_204c() {
14575         test_mkdir $DIR/$tdir
14576         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14577
14578         check_default_stripe_attr --stripe-count
14579         check_default_stripe_attr --stripe-index
14580 }
14581 run_test 204c "Print default stripe count and offset"
14582
14583 test_204d() {
14584         test_mkdir $DIR/$tdir
14585         $LFS setstripe --stripe-index 0 $DIR/$tdir
14586
14587         check_default_stripe_attr --stripe-count
14588         check_default_stripe_attr --stripe-size
14589 }
14590 run_test 204d "Print default stripe count and size"
14591
14592 test_204e() {
14593         test_mkdir $DIR/$tdir
14594         $LFS setstripe -d $DIR/$tdir
14595
14596         check_default_stripe_attr --stripe-count --raw
14597         check_default_stripe_attr --stripe-size --raw
14598         check_default_stripe_attr --stripe-index --raw
14599 }
14600 run_test 204e "Print raw stripe attributes"
14601
14602 test_204f() {
14603         test_mkdir $DIR/$tdir
14604         $LFS setstripe --stripe-count 1 $DIR/$tdir
14605
14606         check_default_stripe_attr --stripe-size --raw
14607         check_default_stripe_attr --stripe-index --raw
14608 }
14609 run_test 204f "Print raw stripe size and offset"
14610
14611 test_204g() {
14612         test_mkdir $DIR/$tdir
14613         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14614
14615         check_default_stripe_attr --stripe-count --raw
14616         check_default_stripe_attr --stripe-index --raw
14617 }
14618 run_test 204g "Print raw stripe count and offset"
14619
14620 test_204h() {
14621         test_mkdir $DIR/$tdir
14622         $LFS setstripe --stripe-index 0 $DIR/$tdir
14623
14624         check_default_stripe_attr --stripe-count --raw
14625         check_default_stripe_attr --stripe-size --raw
14626 }
14627 run_test 204h "Print raw stripe count and size"
14628
14629 # Figure out which job scheduler is being used, if any,
14630 # or use a fake one
14631 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14632         JOBENV=SLURM_JOB_ID
14633 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14634         JOBENV=LSB_JOBID
14635 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14636         JOBENV=PBS_JOBID
14637 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14638         JOBENV=LOADL_STEP_ID
14639 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14640         JOBENV=JOB_ID
14641 else
14642         $LCTL list_param jobid_name > /dev/null 2>&1
14643         if [ $? -eq 0 ]; then
14644                 JOBENV=nodelocal
14645         else
14646                 JOBENV=FAKE_JOBID
14647         fi
14648 fi
14649 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14650
14651 verify_jobstats() {
14652         local cmd=($1)
14653         shift
14654         local facets="$@"
14655
14656 # we don't really need to clear the stats for this test to work, since each
14657 # command has a unique jobid, but it makes debugging easier if needed.
14658 #       for facet in $facets; do
14659 #               local dev=$(convert_facet2label $facet)
14660 #               # clear old jobstats
14661 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14662 #       done
14663
14664         # use a new JobID for each test, or we might see an old one
14665         [ "$JOBENV" = "FAKE_JOBID" ] &&
14666                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14667
14668         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14669
14670         [ "$JOBENV" = "nodelocal" ] && {
14671                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14672                 $LCTL set_param jobid_name=$FAKE_JOBID
14673                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14674         }
14675
14676         log "Test: ${cmd[*]}"
14677         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14678
14679         if [ $JOBENV = "FAKE_JOBID" ]; then
14680                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14681         else
14682                 ${cmd[*]}
14683         fi
14684
14685         # all files are created on OST0000
14686         for facet in $facets; do
14687                 local stats="*.$(convert_facet2label $facet).job_stats"
14688
14689                 # strip out libtool wrappers for in-tree executables
14690                 if [ $(do_facet $facet lctl get_param $stats |
14691                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14692                         do_facet $facet lctl get_param $stats
14693                         error "No jobstats for $JOBVAL found on $facet::$stats"
14694                 fi
14695         done
14696 }
14697
14698 jobstats_set() {
14699         local new_jobenv=$1
14700
14701         set_persistent_param_and_check client "jobid_var" \
14702                 "$FSNAME.sys.jobid_var" $new_jobenv
14703 }
14704
14705 test_205() { # Job stats
14706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14707         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14708                 skip "Need MDS version with at least 2.7.1"
14709         remote_mgs_nodsh && skip "remote MGS with nodsh"
14710         remote_mds_nodsh && skip "remote MDS with nodsh"
14711         remote_ost_nodsh && skip "remote OST with nodsh"
14712         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14713                 skip "Server doesn't support jobstats"
14714         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14715
14716         local old_jobenv=$($LCTL get_param -n jobid_var)
14717         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14718
14719         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14720                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14721         else
14722                 stack_trap "do_facet mgs $PERM_CMD \
14723                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14724         fi
14725         changelog_register
14726
14727         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14728                                 mdt.*.job_cleanup_interval | head -n 1)
14729         local new_interval=5
14730         do_facet $SINGLEMDS \
14731                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14732         stack_trap "do_facet $SINGLEMDS \
14733                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14734         local start=$SECONDS
14735
14736         local cmd
14737         # mkdir
14738         cmd="mkdir $DIR/$tdir"
14739         verify_jobstats "$cmd" "$SINGLEMDS"
14740         # rmdir
14741         cmd="rmdir $DIR/$tdir"
14742         verify_jobstats "$cmd" "$SINGLEMDS"
14743         # mkdir on secondary MDT
14744         if [ $MDSCOUNT -gt 1 ]; then
14745                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14746                 verify_jobstats "$cmd" "mds2"
14747         fi
14748         # mknod
14749         cmd="mknod $DIR/$tfile c 1 3"
14750         verify_jobstats "$cmd" "$SINGLEMDS"
14751         # unlink
14752         cmd="rm -f $DIR/$tfile"
14753         verify_jobstats "$cmd" "$SINGLEMDS"
14754         # create all files on OST0000 so verify_jobstats can find OST stats
14755         # open & close
14756         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14757         verify_jobstats "$cmd" "$SINGLEMDS"
14758         # setattr
14759         cmd="touch $DIR/$tfile"
14760         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14761         # write
14762         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14763         verify_jobstats "$cmd" "ost1"
14764         # read
14765         cancel_lru_locks osc
14766         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14767         verify_jobstats "$cmd" "ost1"
14768         # truncate
14769         cmd="$TRUNCATE $DIR/$tfile 0"
14770         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14771         # rename
14772         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14773         verify_jobstats "$cmd" "$SINGLEMDS"
14774         # jobstats expiry - sleep until old stats should be expired
14775         local left=$((new_interval + 5 - (SECONDS - start)))
14776         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14777                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14778                         "0" $left
14779         cmd="mkdir $DIR/$tdir.expire"
14780         verify_jobstats "$cmd" "$SINGLEMDS"
14781         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14782             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14783
14784         # Ensure that jobid are present in changelog (if supported by MDS)
14785         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14786                 changelog_dump | tail -10
14787                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14788                 [ $jobids -eq 9 ] ||
14789                         error "Wrong changelog jobid count $jobids != 9"
14790
14791                 # LU-5862
14792                 JOBENV="disable"
14793                 jobstats_set $JOBENV
14794                 touch $DIR/$tfile
14795                 changelog_dump | grep $tfile
14796                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14797                 [ $jobids -eq 0 ] ||
14798                         error "Unexpected jobids when jobid_var=$JOBENV"
14799         fi
14800
14801         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14802         JOBENV="JOBCOMPLEX"
14803         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14804
14805         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14806 }
14807 run_test 205 "Verify job stats"
14808
14809 # LU-1480, LU-1773 and LU-1657
14810 test_206() {
14811         mkdir -p $DIR/$tdir
14812         $LFS setstripe -c -1 $DIR/$tdir
14813 #define OBD_FAIL_LOV_INIT 0x1403
14814         $LCTL set_param fail_loc=0xa0001403
14815         $LCTL set_param fail_val=1
14816         touch $DIR/$tdir/$tfile || true
14817 }
14818 run_test 206 "fail lov_init_raid0() doesn't lbug"
14819
14820 test_207a() {
14821         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14822         local fsz=`stat -c %s $DIR/$tfile`
14823         cancel_lru_locks mdc
14824
14825         # do not return layout in getattr intent
14826 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14827         $LCTL set_param fail_loc=0x170
14828         local sz=`stat -c %s $DIR/$tfile`
14829
14830         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14831
14832         rm -rf $DIR/$tfile
14833 }
14834 run_test 207a "can refresh layout at glimpse"
14835
14836 test_207b() {
14837         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14838         local cksum=`md5sum $DIR/$tfile`
14839         local fsz=`stat -c %s $DIR/$tfile`
14840         cancel_lru_locks mdc
14841         cancel_lru_locks osc
14842
14843         # do not return layout in getattr intent
14844 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14845         $LCTL set_param fail_loc=0x171
14846
14847         # it will refresh layout after the file is opened but before read issues
14848         echo checksum is "$cksum"
14849         echo "$cksum" |md5sum -c --quiet || error "file differs"
14850
14851         rm -rf $DIR/$tfile
14852 }
14853 run_test 207b "can refresh layout at open"
14854
14855 test_208() {
14856         # FIXME: in this test suite, only RD lease is used. This is okay
14857         # for now as only exclusive open is supported. After generic lease
14858         # is done, this test suite should be revised. - Jinshan
14859
14860         remote_mds_nodsh && skip "remote MDS with nodsh"
14861         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14862                 skip "Need MDS version at least 2.4.52"
14863
14864         echo "==== test 1: verify get lease work"
14865         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14866
14867         echo "==== test 2: verify lease can be broken by upcoming open"
14868         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14869         local PID=$!
14870         sleep 1
14871
14872         $MULTIOP $DIR/$tfile oO_RDONLY:c
14873         kill -USR1 $PID && wait $PID || error "break lease error"
14874
14875         echo "==== test 3: verify lease can't be granted if an open already exists"
14876         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14877         local PID=$!
14878         sleep 1
14879
14880         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14881         kill -USR1 $PID && wait $PID || error "open file error"
14882
14883         echo "==== test 4: lease can sustain over recovery"
14884         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14885         PID=$!
14886         sleep 1
14887
14888         fail mds1
14889
14890         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14891
14892         echo "==== test 5: lease broken can't be regained by replay"
14893         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14894         PID=$!
14895         sleep 1
14896
14897         # open file to break lease and then recovery
14898         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14899         fail mds1
14900
14901         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14902
14903         rm -f $DIR/$tfile
14904 }
14905 run_test 208 "Exclusive open"
14906
14907 test_209() {
14908         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14909                 skip_env "must have disp_stripe"
14910
14911         touch $DIR/$tfile
14912         sync; sleep 5; sync;
14913
14914         echo 3 > /proc/sys/vm/drop_caches
14915         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14916
14917         # open/close 500 times
14918         for i in $(seq 500); do
14919                 cat $DIR/$tfile
14920         done
14921
14922         echo 3 > /proc/sys/vm/drop_caches
14923         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14924
14925         echo "before: $req_before, after: $req_after"
14926         [ $((req_after - req_before)) -ge 300 ] &&
14927                 error "open/close requests are not freed"
14928         return 0
14929 }
14930 run_test 209 "read-only open/close requests should be freed promptly"
14931
14932 test_212() {
14933         size=`date +%s`
14934         size=$((size % 8192 + 1))
14935         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14936         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14937         rm -f $DIR/f212 $DIR/f212.xyz
14938 }
14939 run_test 212 "Sendfile test ============================================"
14940
14941 test_213() {
14942         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14943         cancel_lru_locks osc
14944         lctl set_param fail_loc=0x8000040f
14945         # generate a read lock
14946         cat $DIR/$tfile > /dev/null
14947         # write to the file, it will try to cancel the above read lock.
14948         cat /etc/hosts >> $DIR/$tfile
14949 }
14950 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14951
14952 test_214() { # for bug 20133
14953         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14954         for (( i=0; i < 340; i++ )) ; do
14955                 touch $DIR/$tdir/d214c/a$i
14956         done
14957
14958         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14959         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14960         ls $DIR/d214c || error "ls $DIR/d214c failed"
14961         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14962         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14963 }
14964 run_test 214 "hash-indexed directory test - bug 20133"
14965
14966 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14967 create_lnet_proc_files() {
14968         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14969 }
14970
14971 # counterpart of create_lnet_proc_files
14972 remove_lnet_proc_files() {
14973         rm -f $TMP/lnet_$1.sys
14974 }
14975
14976 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14977 # 3rd arg as regexp for body
14978 check_lnet_proc_stats() {
14979         local l=$(cat "$TMP/lnet_$1" |wc -l)
14980         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14981
14982         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14983 }
14984
14985 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14986 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14987 # optional and can be regexp for 2nd line (lnet.routes case)
14988 check_lnet_proc_entry() {
14989         local blp=2          # blp stands for 'position of 1st line of body'
14990         [ -z "$5" ] || blp=3 # lnet.routes case
14991
14992         local l=$(cat "$TMP/lnet_$1" |wc -l)
14993         # subtracting one from $blp because the body can be empty
14994         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14995
14996         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14997                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14998
14999         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15000                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15001
15002         # bail out if any unexpected line happened
15003         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15004         [ "$?" != 0 ] || error "$2 misformatted"
15005 }
15006
15007 test_215() { # for bugs 18102, 21079, 21517
15008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15009
15010         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15011         local P='[1-9][0-9]*'           # positive numeric
15012         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15013         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15014         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15015         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15016
15017         local L1 # regexp for 1st line
15018         local L2 # regexp for 2nd line (optional)
15019         local BR # regexp for the rest (body)
15020
15021         # lnet.stats should look as 11 space-separated non-negative numerics
15022         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15023         create_lnet_proc_files "stats"
15024         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15025         remove_lnet_proc_files "stats"
15026
15027         # lnet.routes should look like this:
15028         # Routing disabled/enabled
15029         # net hops priority state router
15030         # where net is a string like tcp0, hops > 0, priority >= 0,
15031         # state is up/down,
15032         # router is a string like 192.168.1.1@tcp2
15033         L1="^Routing (disabled|enabled)$"
15034         L2="^net +hops +priority +state +router$"
15035         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15036         create_lnet_proc_files "routes"
15037         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15038         remove_lnet_proc_files "routes"
15039
15040         # lnet.routers should look like this:
15041         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15042         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15043         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15044         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15045         L1="^ref +rtr_ref +alive +router$"
15046         BR="^$P +$P +(up|down) +$NID$"
15047         create_lnet_proc_files "routers"
15048         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15049         remove_lnet_proc_files "routers"
15050
15051         # lnet.peers should look like this:
15052         # nid refs state last max rtr min tx min queue
15053         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15054         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15055         # numeric (0 or >0 or <0), queue >= 0.
15056         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15057         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15058         create_lnet_proc_files "peers"
15059         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15060         remove_lnet_proc_files "peers"
15061
15062         # lnet.buffers  should look like this:
15063         # pages count credits min
15064         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15065         L1="^pages +count +credits +min$"
15066         BR="^ +$N +$N +$I +$I$"
15067         create_lnet_proc_files "buffers"
15068         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15069         remove_lnet_proc_files "buffers"
15070
15071         # lnet.nis should look like this:
15072         # nid status alive refs peer rtr max tx min
15073         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15074         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15075         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15076         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15077         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15078         create_lnet_proc_files "nis"
15079         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15080         remove_lnet_proc_files "nis"
15081
15082         # can we successfully write to lnet.stats?
15083         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15084 }
15085 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15086
15087 test_216() { # bug 20317
15088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15089         remote_ost_nodsh && skip "remote OST with nodsh"
15090
15091         local node
15092         local facets=$(get_facets OST)
15093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15094
15095         save_lustre_params client "osc.*.contention_seconds" > $p
15096         save_lustre_params $facets \
15097                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15098         save_lustre_params $facets \
15099                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15100         save_lustre_params $facets \
15101                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15102         clear_stats osc.*.osc_stats
15103
15104         # agressive lockless i/o settings
15105         do_nodes $(comma_list $(osts_nodes)) \
15106                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15107                         ldlm.namespaces.filter-*.contended_locks=0 \
15108                         ldlm.namespaces.filter-*.contention_seconds=60"
15109         lctl set_param -n osc.*.contention_seconds=60
15110
15111         $DIRECTIO write $DIR/$tfile 0 10 4096
15112         $CHECKSTAT -s 40960 $DIR/$tfile
15113
15114         # disable lockless i/o
15115         do_nodes $(comma_list $(osts_nodes)) \
15116                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15117                         ldlm.namespaces.filter-*.contended_locks=32 \
15118                         ldlm.namespaces.filter-*.contention_seconds=0"
15119         lctl set_param -n osc.*.contention_seconds=0
15120         clear_stats osc.*.osc_stats
15121
15122         dd if=/dev/zero of=$DIR/$tfile count=0
15123         $CHECKSTAT -s 0 $DIR/$tfile
15124
15125         restore_lustre_params <$p
15126         rm -f $p
15127         rm $DIR/$tfile
15128 }
15129 run_test 216 "check lockless direct write updates file size and kms correctly"
15130
15131 test_217() { # bug 22430
15132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15133
15134         local node
15135         local nid
15136
15137         for node in $(nodes_list); do
15138                 nid=$(host_nids_address $node $NETTYPE)
15139                 if [[ $nid = *-* ]] ; then
15140                         echo "lctl ping $(h2nettype $nid)"
15141                         lctl ping $(h2nettype $nid)
15142                 else
15143                         echo "skipping $node (no hyphen detected)"
15144                 fi
15145         done
15146 }
15147 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15148
15149 test_218() {
15150        # do directio so as not to populate the page cache
15151        log "creating a 10 Mb file"
15152        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15153        log "starting reads"
15154        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15155        log "truncating the file"
15156        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15157        log "killing dd"
15158        kill %+ || true # reads might have finished
15159        echo "wait until dd is finished"
15160        wait
15161        log "removing the temporary file"
15162        rm -rf $DIR/$tfile || error "tmp file removal failed"
15163 }
15164 run_test 218 "parallel read and truncate should not deadlock"
15165
15166 test_219() {
15167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15168
15169         # write one partial page
15170         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15171         # set no grant so vvp_io_commit_write will do sync write
15172         $LCTL set_param fail_loc=0x411
15173         # write a full page at the end of file
15174         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15175
15176         $LCTL set_param fail_loc=0
15177         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15178         $LCTL set_param fail_loc=0x411
15179         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15180
15181         # LU-4201
15182         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15183         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15184 }
15185 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15186
15187 test_220() { #LU-325
15188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15189         remote_ost_nodsh && skip "remote OST with nodsh"
15190         remote_mds_nodsh && skip "remote MDS with nodsh"
15191         remote_mgs_nodsh && skip "remote MGS with nodsh"
15192
15193         local OSTIDX=0
15194
15195         # create on MDT0000 so the last_id and next_id are correct
15196         mkdir $DIR/$tdir
15197         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15198         OST=${OST%_UUID}
15199
15200         # on the mdt's osc
15201         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15202         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15203                         osc.$mdtosc_proc1.prealloc_last_id)
15204         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15205                         osc.$mdtosc_proc1.prealloc_next_id)
15206
15207         $LFS df -i
15208
15209         if ! combined_mgs_mds ; then
15210                 mount_mgs_client
15211         fi
15212
15213         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15214         #define OBD_FAIL_OST_ENOINO              0x229
15215         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15216         create_pool $FSNAME.$TESTNAME || return 1
15217         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15218
15219         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15220
15221         MDSOBJS=$((last_id - next_id))
15222         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15223
15224         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15225         echo "OST still has $count kbytes free"
15226
15227         echo "create $MDSOBJS files @next_id..."
15228         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15229
15230         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15231                         osc.$mdtosc_proc1.prealloc_last_id)
15232         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15233                         osc.$mdtosc_proc1.prealloc_next_id)
15234
15235         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15236         $LFS df -i
15237
15238         echo "cleanup..."
15239
15240         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15241         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15242
15243         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15244                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15245         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15246                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15247         echo "unlink $MDSOBJS files @$next_id..."
15248         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15249
15250         if ! combined_mgs_mds ; then
15251                 umount_mgs_client
15252         fi
15253 }
15254 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15255
15256 test_221() {
15257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15258
15259         dd if=`which date` of=$MOUNT/date oflag=sync
15260         chmod +x $MOUNT/date
15261
15262         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15263         $LCTL set_param fail_loc=0x80001401
15264
15265         $MOUNT/date > /dev/null
15266         rm -f $MOUNT/date
15267 }
15268 run_test 221 "make sure fault and truncate race to not cause OOM"
15269
15270 test_222a () {
15271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15272
15273         rm -rf $DIR/$tdir
15274         test_mkdir $DIR/$tdir
15275         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15276         createmany -o $DIR/$tdir/$tfile 10
15277         cancel_lru_locks mdc
15278         cancel_lru_locks osc
15279         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15280         $LCTL set_param fail_loc=0x31a
15281         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15282         $LCTL set_param fail_loc=0
15283         rm -r $DIR/$tdir
15284 }
15285 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15286
15287 test_222b () {
15288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15289
15290         rm -rf $DIR/$tdir
15291         test_mkdir $DIR/$tdir
15292         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15293         createmany -o $DIR/$tdir/$tfile 10
15294         cancel_lru_locks mdc
15295         cancel_lru_locks osc
15296         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15297         $LCTL set_param fail_loc=0x31a
15298         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15299         $LCTL set_param fail_loc=0
15300 }
15301 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15302
15303 test_223 () {
15304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15305
15306         rm -rf $DIR/$tdir
15307         test_mkdir $DIR/$tdir
15308         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15309         createmany -o $DIR/$tdir/$tfile 10
15310         cancel_lru_locks mdc
15311         cancel_lru_locks osc
15312         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15313         $LCTL set_param fail_loc=0x31b
15314         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15315         $LCTL set_param fail_loc=0
15316         rm -r $DIR/$tdir
15317 }
15318 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15319
15320 test_224a() { # LU-1039, MRP-303
15321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15322
15323         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15324         $LCTL set_param fail_loc=0x508
15325         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15326         $LCTL set_param fail_loc=0
15327         df $DIR
15328 }
15329 run_test 224a "Don't panic on bulk IO failure"
15330
15331 test_224b() { # LU-1039, MRP-303
15332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15333
15334         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15335         cancel_lru_locks osc
15336         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15337         $LCTL set_param fail_loc=0x515
15338         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15339         $LCTL set_param fail_loc=0
15340         df $DIR
15341 }
15342 run_test 224b "Don't panic on bulk IO failure"
15343
15344 test_224c() { # LU-6441
15345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15346         remote_mds_nodsh && skip "remote MDS with nodsh"
15347
15348         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15349         save_writethrough $p
15350         set_cache writethrough on
15351
15352         local pages_per_rpc=$($LCTL get_param \
15353                                 osc.*.max_pages_per_rpc)
15354         local at_max=$($LCTL get_param -n at_max)
15355         local timeout=$($LCTL get_param -n timeout)
15356         local test_at="at_max"
15357         local param_at="$FSNAME.sys.at_max"
15358         local test_timeout="timeout"
15359         local param_timeout="$FSNAME.sys.timeout"
15360
15361         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15362
15363         set_persistent_param_and_check client "$test_at" "$param_at" 0
15364         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15365
15366         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15367         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15368         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15369         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15370         sync
15371         do_facet ost1 "$LCTL set_param fail_loc=0"
15372
15373         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15374         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15375                 $timeout
15376
15377         $LCTL set_param -n $pages_per_rpc
15378         restore_lustre_params < $p
15379         rm -f $p
15380 }
15381 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15382
15383 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15384 test_225a () {
15385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15386         if [ -z ${MDSSURVEY} ]; then
15387                 skip_env "mds-survey not found"
15388         fi
15389         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15390                 skip "Need MDS version at least 2.2.51"
15391
15392         local mds=$(facet_host $SINGLEMDS)
15393         local target=$(do_nodes $mds 'lctl dl' |
15394                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15395
15396         local cmd1="file_count=1000 thrhi=4"
15397         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15398         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15399         local cmd="$cmd1 $cmd2 $cmd3"
15400
15401         rm -f ${TMP}/mds_survey*
15402         echo + $cmd
15403         eval $cmd || error "mds-survey with zero-stripe failed"
15404         cat ${TMP}/mds_survey*
15405         rm -f ${TMP}/mds_survey*
15406 }
15407 run_test 225a "Metadata survey sanity with zero-stripe"
15408
15409 test_225b () {
15410         if [ -z ${MDSSURVEY} ]; then
15411                 skip_env "mds-survey not found"
15412         fi
15413         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15414                 skip "Need MDS version at least 2.2.51"
15415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15416         remote_mds_nodsh && skip "remote MDS with nodsh"
15417         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15418                 skip_env "Need to mount OST to test"
15419         fi
15420
15421         local mds=$(facet_host $SINGLEMDS)
15422         local target=$(do_nodes $mds 'lctl dl' |
15423                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15424
15425         local cmd1="file_count=1000 thrhi=4"
15426         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15427         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15428         local cmd="$cmd1 $cmd2 $cmd3"
15429
15430         rm -f ${TMP}/mds_survey*
15431         echo + $cmd
15432         eval $cmd || error "mds-survey with stripe_count failed"
15433         cat ${TMP}/mds_survey*
15434         rm -f ${TMP}/mds_survey*
15435 }
15436 run_test 225b "Metadata survey sanity with stripe_count = 1"
15437
15438 mcreate_path2fid () {
15439         local mode=$1
15440         local major=$2
15441         local minor=$3
15442         local name=$4
15443         local desc=$5
15444         local path=$DIR/$tdir/$name
15445         local fid
15446         local rc
15447         local fid_path
15448
15449         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15450                 error "cannot create $desc"
15451
15452         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15453         rc=$?
15454         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15455
15456         fid_path=$($LFS fid2path $MOUNT $fid)
15457         rc=$?
15458         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15459
15460         [ "$path" == "$fid_path" ] ||
15461                 error "fid2path returned $fid_path, expected $path"
15462
15463         echo "pass with $path and $fid"
15464 }
15465
15466 test_226a () {
15467         rm -rf $DIR/$tdir
15468         mkdir -p $DIR/$tdir
15469
15470         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15471         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15472         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15473         mcreate_path2fid 0040666 0 0 dir "directory"
15474         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15475         mcreate_path2fid 0100666 0 0 file "regular file"
15476         mcreate_path2fid 0120666 0 0 link "symbolic link"
15477         mcreate_path2fid 0140666 0 0 sock "socket"
15478 }
15479 run_test 226a "call path2fid and fid2path on files of all type"
15480
15481 test_226b () {
15482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15483
15484         local MDTIDX=1
15485
15486         rm -rf $DIR/$tdir
15487         mkdir -p $DIR/$tdir
15488         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15489                 error "create remote directory failed"
15490         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15491         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15492                                 "character special file (null)"
15493         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15494                                 "character special file (no device)"
15495         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15496         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15497                                 "block special file (loop)"
15498         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15499         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15500         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15501 }
15502 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15503
15504 # LU-1299 Executing or running ldd on a truncated executable does not
15505 # cause an out-of-memory condition.
15506 test_227() {
15507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15508         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15509
15510         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15511         chmod +x $MOUNT/date
15512
15513         $MOUNT/date > /dev/null
15514         ldd $MOUNT/date > /dev/null
15515         rm -f $MOUNT/date
15516 }
15517 run_test 227 "running truncated executable does not cause OOM"
15518
15519 # LU-1512 try to reuse idle OI blocks
15520 test_228a() {
15521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15522         remote_mds_nodsh && skip "remote MDS with nodsh"
15523         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15524
15525         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15526         local myDIR=$DIR/$tdir
15527
15528         mkdir -p $myDIR
15529         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15530         $LCTL set_param fail_loc=0x80001002
15531         createmany -o $myDIR/t- 10000
15532         $LCTL set_param fail_loc=0
15533         # The guard is current the largest FID holder
15534         touch $myDIR/guard
15535         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15536                     tr -d '[')
15537         local IDX=$(($SEQ % 64))
15538
15539         do_facet $SINGLEMDS sync
15540         # Make sure journal flushed.
15541         sleep 6
15542         local blk1=$(do_facet $SINGLEMDS \
15543                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15544                      grep Blockcount | awk '{print $4}')
15545
15546         # Remove old files, some OI blocks will become idle.
15547         unlinkmany $myDIR/t- 10000
15548         # Create new files, idle OI blocks should be reused.
15549         createmany -o $myDIR/t- 2000
15550         do_facet $SINGLEMDS sync
15551         # Make sure journal flushed.
15552         sleep 6
15553         local blk2=$(do_facet $SINGLEMDS \
15554                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15555                      grep Blockcount | awk '{print $4}')
15556
15557         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15558 }
15559 run_test 228a "try to reuse idle OI blocks"
15560
15561 test_228b() {
15562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15563         remote_mds_nodsh && skip "remote MDS with nodsh"
15564         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15565
15566         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15567         local myDIR=$DIR/$tdir
15568
15569         mkdir -p $myDIR
15570         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15571         $LCTL set_param fail_loc=0x80001002
15572         createmany -o $myDIR/t- 10000
15573         $LCTL set_param fail_loc=0
15574         # The guard is current the largest FID holder
15575         touch $myDIR/guard
15576         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15577                     tr -d '[')
15578         local IDX=$(($SEQ % 64))
15579
15580         do_facet $SINGLEMDS sync
15581         # Make sure journal flushed.
15582         sleep 6
15583         local blk1=$(do_facet $SINGLEMDS \
15584                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15585                      grep Blockcount | awk '{print $4}')
15586
15587         # Remove old files, some OI blocks will become idle.
15588         unlinkmany $myDIR/t- 10000
15589
15590         # stop the MDT
15591         stop $SINGLEMDS || error "Fail to stop MDT."
15592         # remount the MDT
15593         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15594
15595         df $MOUNT || error "Fail to df."
15596         # Create new files, idle OI blocks should be reused.
15597         createmany -o $myDIR/t- 2000
15598         do_facet $SINGLEMDS sync
15599         # Make sure journal flushed.
15600         sleep 6
15601         local blk2=$(do_facet $SINGLEMDS \
15602                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15603                      grep Blockcount | awk '{print $4}')
15604
15605         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15606 }
15607 run_test 228b "idle OI blocks can be reused after MDT restart"
15608
15609 #LU-1881
15610 test_228c() {
15611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15612         remote_mds_nodsh && skip "remote MDS with nodsh"
15613         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15614
15615         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15616         local myDIR=$DIR/$tdir
15617
15618         mkdir -p $myDIR
15619         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15620         $LCTL set_param fail_loc=0x80001002
15621         # 20000 files can guarantee there are index nodes in the OI file
15622         createmany -o $myDIR/t- 20000
15623         $LCTL set_param fail_loc=0
15624         # The guard is current the largest FID holder
15625         touch $myDIR/guard
15626         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15627                     tr -d '[')
15628         local IDX=$(($SEQ % 64))
15629
15630         do_facet $SINGLEMDS sync
15631         # Make sure journal flushed.
15632         sleep 6
15633         local blk1=$(do_facet $SINGLEMDS \
15634                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15635                      grep Blockcount | awk '{print $4}')
15636
15637         # Remove old files, some OI blocks will become idle.
15638         unlinkmany $myDIR/t- 20000
15639         rm -f $myDIR/guard
15640         # The OI file should become empty now
15641
15642         # Create new files, idle OI blocks should be reused.
15643         createmany -o $myDIR/t- 2000
15644         do_facet $SINGLEMDS sync
15645         # Make sure journal flushed.
15646         sleep 6
15647         local blk2=$(do_facet $SINGLEMDS \
15648                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15649                      grep Blockcount | awk '{print $4}')
15650
15651         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15652 }
15653 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15654
15655 test_229() { # LU-2482, LU-3448
15656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15657         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15658         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15659                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15660
15661         rm -f $DIR/$tfile
15662
15663         # Create a file with a released layout and stripe count 2.
15664         $MULTIOP $DIR/$tfile H2c ||
15665                 error "failed to create file with released layout"
15666
15667         $LFS getstripe -v $DIR/$tfile
15668
15669         local pattern=$($LFS getstripe -L $DIR/$tfile)
15670         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15671
15672         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15673                 error "getstripe"
15674         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15675         stat $DIR/$tfile || error "failed to stat released file"
15676
15677         chown $RUNAS_ID $DIR/$tfile ||
15678                 error "chown $RUNAS_ID $DIR/$tfile failed"
15679
15680         chgrp $RUNAS_ID $DIR/$tfile ||
15681                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15682
15683         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15684         rm $DIR/$tfile || error "failed to remove released file"
15685 }
15686 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15687
15688 test_230a() {
15689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15691         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15692                 skip "Need MDS version at least 2.11.52"
15693
15694         local MDTIDX=1
15695
15696         test_mkdir $DIR/$tdir
15697         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15698         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15699         [ $mdt_idx -ne 0 ] &&
15700                 error "create local directory on wrong MDT $mdt_idx"
15701
15702         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15703                         error "create remote directory failed"
15704         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15705         [ $mdt_idx -ne $MDTIDX ] &&
15706                 error "create remote directory on wrong MDT $mdt_idx"
15707
15708         createmany -o $DIR/$tdir/test_230/t- 10 ||
15709                 error "create files on remote directory failed"
15710         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15711         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15712         rm -r $DIR/$tdir || error "unlink remote directory failed"
15713 }
15714 run_test 230a "Create remote directory and files under the remote directory"
15715
15716 test_230b() {
15717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15719         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15720                 skip "Need MDS version at least 2.11.52"
15721
15722         local MDTIDX=1
15723         local mdt_index
15724         local i
15725         local file
15726         local pid
15727         local stripe_count
15728         local migrate_dir=$DIR/$tdir/migrate_dir
15729         local other_dir=$DIR/$tdir/other_dir
15730
15731         test_mkdir $DIR/$tdir
15732         test_mkdir -i0 -c1 $migrate_dir
15733         test_mkdir -i0 -c1 $other_dir
15734         for ((i=0; i<10; i++)); do
15735                 mkdir -p $migrate_dir/dir_${i}
15736                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15737                         error "create files under remote dir failed $i"
15738         done
15739
15740         cp /etc/passwd $migrate_dir/$tfile
15741         cp /etc/passwd $other_dir/$tfile
15742         chattr +SAD $migrate_dir
15743         chattr +SAD $migrate_dir/$tfile
15744
15745         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15746         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15747         local old_dir_mode=$(stat -c%f $migrate_dir)
15748         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15749
15750         mkdir -p $migrate_dir/dir_default_stripe2
15751         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15752         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15753
15754         mkdir -p $other_dir
15755         ln $migrate_dir/$tfile $other_dir/luna
15756         ln $migrate_dir/$tfile $migrate_dir/sofia
15757         ln $other_dir/$tfile $migrate_dir/david
15758         ln -s $migrate_dir/$tfile $other_dir/zachary
15759         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15760         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15761
15762         $LFS migrate -m $MDTIDX $migrate_dir ||
15763                 error "fails on migrating remote dir to MDT1"
15764
15765         echo "migratate to MDT1, then checking.."
15766         for ((i = 0; i < 10; i++)); do
15767                 for file in $(find $migrate_dir/dir_${i}); do
15768                         mdt_index=$($LFS getstripe -m $file)
15769                         [ $mdt_index == $MDTIDX ] ||
15770                                 error "$file is not on MDT${MDTIDX}"
15771                 done
15772         done
15773
15774         # the multiple link file should still in MDT0
15775         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15776         [ $mdt_index == 0 ] ||
15777                 error "$file is not on MDT${MDTIDX}"
15778
15779         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15780         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15781                 error " expect $old_dir_flag get $new_dir_flag"
15782
15783         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15784         [ "$old_file_flag" = "$new_file_flag" ] ||
15785                 error " expect $old_file_flag get $new_file_flag"
15786
15787         local new_dir_mode=$(stat -c%f $migrate_dir)
15788         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15789                 error "expect mode $old_dir_mode get $new_dir_mode"
15790
15791         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15792         [ "$old_file_mode" = "$new_file_mode" ] ||
15793                 error "expect mode $old_file_mode get $new_file_mode"
15794
15795         diff /etc/passwd $migrate_dir/$tfile ||
15796                 error "$tfile different after migration"
15797
15798         diff /etc/passwd $other_dir/luna ||
15799                 error "luna different after migration"
15800
15801         diff /etc/passwd $migrate_dir/sofia ||
15802                 error "sofia different after migration"
15803
15804         diff /etc/passwd $migrate_dir/david ||
15805                 error "david different after migration"
15806
15807         diff /etc/passwd $other_dir/zachary ||
15808                 error "zachary different after migration"
15809
15810         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15811                 error "${tfile}_ln different after migration"
15812
15813         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15814                 error "${tfile}_ln_other different after migration"
15815
15816         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15817         [ $stripe_count = 2 ] ||
15818                 error "dir strpe_count $d != 2 after migration."
15819
15820         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15821         [ $stripe_count = 2 ] ||
15822                 error "file strpe_count $d != 2 after migration."
15823
15824         #migrate back to MDT0
15825         MDTIDX=0
15826
15827         $LFS migrate -m $MDTIDX $migrate_dir ||
15828                 error "fails on migrating remote dir to MDT0"
15829
15830         echo "migrate back to MDT0, checking.."
15831         for file in $(find $migrate_dir); do
15832                 mdt_index=$($LFS getstripe -m $file)
15833                 [ $mdt_index == $MDTIDX ] ||
15834                         error "$file is not on MDT${MDTIDX}"
15835         done
15836
15837         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15838         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15839                 error " expect $old_dir_flag get $new_dir_flag"
15840
15841         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15842         [ "$old_file_flag" = "$new_file_flag" ] ||
15843                 error " expect $old_file_flag get $new_file_flag"
15844
15845         local new_dir_mode=$(stat -c%f $migrate_dir)
15846         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15847                 error "expect mode $old_dir_mode get $new_dir_mode"
15848
15849         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15850         [ "$old_file_mode" = "$new_file_mode" ] ||
15851                 error "expect mode $old_file_mode get $new_file_mode"
15852
15853         diff /etc/passwd ${migrate_dir}/$tfile ||
15854                 error "$tfile different after migration"
15855
15856         diff /etc/passwd ${other_dir}/luna ||
15857                 error "luna different after migration"
15858
15859         diff /etc/passwd ${migrate_dir}/sofia ||
15860                 error "sofia different after migration"
15861
15862         diff /etc/passwd ${other_dir}/zachary ||
15863                 error "zachary different after migration"
15864
15865         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15866                 error "${tfile}_ln different after migration"
15867
15868         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15869                 error "${tfile}_ln_other different after migration"
15870
15871         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15872         [ $stripe_count = 2 ] ||
15873                 error "dir strpe_count $d != 2 after migration."
15874
15875         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15876         [ $stripe_count = 2 ] ||
15877                 error "file strpe_count $d != 2 after migration."
15878
15879         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15880 }
15881 run_test 230b "migrate directory"
15882
15883 test_230c() {
15884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15885         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15888                 skip "Need MDS version at least 2.11.52"
15889
15890         local MDTIDX=1
15891         local total=3
15892         local mdt_index
15893         local file
15894         local migrate_dir=$DIR/$tdir/migrate_dir
15895
15896         #If migrating directory fails in the middle, all entries of
15897         #the directory is still accessiable.
15898         test_mkdir $DIR/$tdir
15899         test_mkdir -i0 -c1 $migrate_dir
15900         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15901         stat $migrate_dir
15902         createmany -o $migrate_dir/f $total ||
15903                 error "create files under ${migrate_dir} failed"
15904
15905         # fail after migrating top dir, and this will fail only once, so the
15906         # first sub file migration will fail (currently f3), others succeed.
15907         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15908         do_facet mds1 lctl set_param fail_loc=0x1801
15909         local t=$(ls $migrate_dir | wc -l)
15910         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15911                 error "migrate should fail"
15912         local u=$(ls $migrate_dir | wc -l)
15913         [ "$u" == "$t" ] || error "$u != $t during migration"
15914
15915         # add new dir/file should succeed
15916         mkdir $migrate_dir/dir ||
15917                 error "mkdir failed under migrating directory"
15918         touch $migrate_dir/file ||
15919                 error "create file failed under migrating directory"
15920
15921         # add file with existing name should fail
15922         for file in $migrate_dir/f*; do
15923                 stat $file > /dev/null || error "stat $file failed"
15924                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15925                         error "open(O_CREAT|O_EXCL) $file should fail"
15926                 $MULTIOP $file m && error "create $file should fail"
15927                 touch $DIR/$tdir/remote_dir/$tfile ||
15928                         error "touch $tfile failed"
15929                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15930                         error "link $file should fail"
15931                 mdt_index=$($LFS getstripe -m $file)
15932                 if [ $mdt_index == 0 ]; then
15933                         # file failed to migrate is not allowed to rename to
15934                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15935                                 error "rename to $file should fail"
15936                 else
15937                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15938                                 error "rename to $file failed"
15939                 fi
15940                 echo hello >> $file || error "write $file failed"
15941         done
15942
15943         # resume migration with different options should fail
15944         $LFS migrate -m 0 $migrate_dir &&
15945                 error "migrate -m 0 $migrate_dir should fail"
15946
15947         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15948                 error "migrate -c 2 $migrate_dir should fail"
15949
15950         # resume migration should succeed
15951         $LFS migrate -m $MDTIDX $migrate_dir ||
15952                 error "migrate $migrate_dir failed"
15953
15954         echo "Finish migration, then checking.."
15955         for file in $(find $migrate_dir); do
15956                 mdt_index=$($LFS getstripe -m $file)
15957                 [ $mdt_index == $MDTIDX ] ||
15958                         error "$file is not on MDT${MDTIDX}"
15959         done
15960
15961         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15962 }
15963 run_test 230c "check directory accessiblity if migration failed"
15964
15965 test_230d() {
15966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15968         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15969                 skip "Need MDS version at least 2.11.52"
15970         # LU-11235
15971         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15972
15973         local migrate_dir=$DIR/$tdir/migrate_dir
15974         local old_index
15975         local new_index
15976         local old_count
15977         local new_count
15978         local new_hash
15979         local mdt_index
15980         local i
15981         local j
15982
15983         old_index=$((RANDOM % MDSCOUNT))
15984         old_count=$((MDSCOUNT - old_index))
15985         new_index=$((RANDOM % MDSCOUNT))
15986         new_count=$((MDSCOUNT - new_index))
15987         new_hash="all_char"
15988
15989         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15990         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15991
15992         test_mkdir $DIR/$tdir
15993         test_mkdir -i $old_index -c $old_count $migrate_dir
15994
15995         for ((i=0; i<100; i++)); do
15996                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15997                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15998                         error "create files under remote dir failed $i"
15999         done
16000
16001         echo -n "Migrate from MDT$old_index "
16002         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16003         echo -n "to MDT$new_index"
16004         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16005         echo
16006
16007         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16008         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16009                 error "migrate remote dir error"
16010
16011         echo "Finish migration, then checking.."
16012         for file in $(find $migrate_dir); do
16013                 mdt_index=$($LFS getstripe -m $file)
16014                 if [ $mdt_index -lt $new_index ] ||
16015                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16016                         error "$file is on MDT$mdt_index"
16017                 fi
16018         done
16019
16020         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16021 }
16022 run_test 230d "check migrate big directory"
16023
16024 test_230e() {
16025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16027         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16028                 skip "Need MDS version at least 2.11.52"
16029
16030         local i
16031         local j
16032         local a_fid
16033         local b_fid
16034
16035         mkdir -p $DIR/$tdir
16036         mkdir $DIR/$tdir/migrate_dir
16037         mkdir $DIR/$tdir/other_dir
16038         touch $DIR/$tdir/migrate_dir/a
16039         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16040         ls $DIR/$tdir/other_dir
16041
16042         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16043                 error "migrate dir fails"
16044
16045         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16046         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16047
16048         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16049         [ $mdt_index == 0 ] || error "a is not on MDT0"
16050
16051         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16052                 error "migrate dir fails"
16053
16054         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16055         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16056
16057         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16058         [ $mdt_index == 1 ] || error "a is not on MDT1"
16059
16060         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16061         [ $mdt_index == 1 ] || error "b is not on MDT1"
16062
16063         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16064         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16065
16066         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16067
16068         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16069 }
16070 run_test 230e "migrate mulitple local link files"
16071
16072 test_230f() {
16073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16075         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16076                 skip "Need MDS version at least 2.11.52"
16077
16078         local a_fid
16079         local ln_fid
16080
16081         mkdir -p $DIR/$tdir
16082         mkdir $DIR/$tdir/migrate_dir
16083         $LFS mkdir -i1 $DIR/$tdir/other_dir
16084         touch $DIR/$tdir/migrate_dir/a
16085         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16086         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16087         ls $DIR/$tdir/other_dir
16088
16089         # a should be migrated to MDT1, since no other links on MDT0
16090         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16091                 error "#1 migrate dir fails"
16092         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16093         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16094         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16095         [ $mdt_index == 1 ] || error "a is not on MDT1"
16096
16097         # a should stay on MDT1, because it is a mulitple link file
16098         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16099                 error "#2 migrate dir fails"
16100         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16101         [ $mdt_index == 1 ] || error "a is not on MDT1"
16102
16103         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16104                 error "#3 migrate dir fails"
16105
16106         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16107         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16108         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16109
16110         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16111         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16112
16113         # a should be migrated to MDT0, since no other links on MDT1
16114         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16115                 error "#4 migrate dir fails"
16116         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16117         [ $mdt_index == 0 ] || error "a is not on MDT0"
16118
16119         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16120 }
16121 run_test 230f "migrate mulitple remote link files"
16122
16123 test_230g() {
16124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16126         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16127                 skip "Need MDS version at least 2.11.52"
16128
16129         mkdir -p $DIR/$tdir/migrate_dir
16130
16131         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16132                 error "migrating dir to non-exist MDT succeeds"
16133         true
16134 }
16135 run_test 230g "migrate dir to non-exist MDT"
16136
16137 test_230h() {
16138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16140         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16141                 skip "Need MDS version at least 2.11.52"
16142
16143         local mdt_index
16144
16145         mkdir -p $DIR/$tdir/migrate_dir
16146
16147         $LFS migrate -m1 $DIR &&
16148                 error "migrating mountpoint1 should fail"
16149
16150         $LFS migrate -m1 $DIR/$tdir/.. &&
16151                 error "migrating mountpoint2 should fail"
16152
16153         # same as mv
16154         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16155                 error "migrating $tdir/migrate_dir/.. should fail"
16156
16157         true
16158 }
16159 run_test 230h "migrate .. and root"
16160
16161 test_230i() {
16162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16164         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16165                 skip "Need MDS version at least 2.11.52"
16166
16167         mkdir -p $DIR/$tdir/migrate_dir
16168
16169         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16170                 error "migration fails with a tailing slash"
16171
16172         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16173                 error "migration fails with two tailing slashes"
16174 }
16175 run_test 230i "lfs migrate -m tolerates trailing slashes"
16176
16177 test_230j() {
16178         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16179         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16180                 skip "Need MDS version at least 2.11.52"
16181
16182         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16183         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16184                 error "create $tfile failed"
16185         cat /etc/passwd > $DIR/$tdir/$tfile
16186
16187         $LFS migrate -m 1 $DIR/$tdir
16188
16189         cmp /etc/passwd $DIR/$tdir/$tfile ||
16190                 error "DoM file mismatch after migration"
16191 }
16192 run_test 230j "DoM file data not changed after dir migration"
16193
16194 test_230k() {
16195         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16196         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16197                 skip "Need MDS version at least 2.11.56"
16198
16199         local total=20
16200         local files_on_starting_mdt=0
16201
16202         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16203         $LFS getdirstripe $DIR/$tdir
16204         for i in $(seq $total); do
16205                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16206                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16207                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16208         done
16209
16210         echo "$files_on_starting_mdt files on MDT0"
16211
16212         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16213         $LFS getdirstripe $DIR/$tdir
16214
16215         files_on_starting_mdt=0
16216         for i in $(seq $total); do
16217                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16218                         error "file $tfile.$i mismatch after migration"
16219                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16220                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16221         done
16222
16223         echo "$files_on_starting_mdt files on MDT1 after migration"
16224         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16225
16226         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16227         $LFS getdirstripe $DIR/$tdir
16228
16229         files_on_starting_mdt=0
16230         for i in $(seq $total); do
16231                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16232                         error "file $tfile.$i mismatch after 2nd migration"
16233                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16234                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16235         done
16236
16237         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16238         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16239
16240         true
16241 }
16242 run_test 230k "file data not changed after dir migration"
16243
16244 test_230l() {
16245         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16246         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16247                 skip "Need MDS version at least 2.11.56"
16248
16249         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16250         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16251                 error "create files under remote dir failed $i"
16252         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16253 }
16254 run_test 230l "readdir between MDTs won't crash"
16255
16256 test_231a()
16257 {
16258         # For simplicity this test assumes that max_pages_per_rpc
16259         # is the same across all OSCs
16260         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16261         local bulk_size=$((max_pages * PAGE_SIZE))
16262         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16263                                        head -n 1)
16264
16265         mkdir -p $DIR/$tdir
16266         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16267                 error "failed to set stripe with -S ${brw_size}M option"
16268
16269         # clear the OSC stats
16270         $LCTL set_param osc.*.stats=0 &>/dev/null
16271         stop_writeback
16272
16273         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16274         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16275                 oflag=direct &>/dev/null || error "dd failed"
16276
16277         sync; sleep 1; sync # just to be safe
16278         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16279         if [ x$nrpcs != "x1" ]; then
16280                 $LCTL get_param osc.*.stats
16281                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16282         fi
16283
16284         start_writeback
16285         # Drop the OSC cache, otherwise we will read from it
16286         cancel_lru_locks osc
16287
16288         # clear the OSC stats
16289         $LCTL set_param osc.*.stats=0 &>/dev/null
16290
16291         # Client reads $bulk_size.
16292         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16293                 iflag=direct &>/dev/null || error "dd failed"
16294
16295         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16296         if [ x$nrpcs != "x1" ]; then
16297                 $LCTL get_param osc.*.stats
16298                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16299         fi
16300 }
16301 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16302
16303 test_231b() {
16304         mkdir -p $DIR/$tdir
16305         local i
16306         for i in {0..1023}; do
16307                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16308                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16309                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16310         done
16311         sync
16312 }
16313 run_test 231b "must not assert on fully utilized OST request buffer"
16314
16315 test_232a() {
16316         mkdir -p $DIR/$tdir
16317         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16318
16319         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16320         do_facet ost1 $LCTL set_param fail_loc=0x31c
16321
16322         # ignore dd failure
16323         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16324
16325         do_facet ost1 $LCTL set_param fail_loc=0
16326         umount_client $MOUNT || error "umount failed"
16327         mount_client $MOUNT || error "mount failed"
16328         stop ost1 || error "cannot stop ost1"
16329         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16330 }
16331 run_test 232a "failed lock should not block umount"
16332
16333 test_232b() {
16334         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16335                 skip "Need MDS version at least 2.10.58"
16336
16337         mkdir -p $DIR/$tdir
16338         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16339         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16340         sync
16341         cancel_lru_locks osc
16342
16343         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16344         do_facet ost1 $LCTL set_param fail_loc=0x31c
16345
16346         # ignore failure
16347         $LFS data_version $DIR/$tdir/$tfile || true
16348
16349         do_facet ost1 $LCTL set_param fail_loc=0
16350         umount_client $MOUNT || error "umount failed"
16351         mount_client $MOUNT || error "mount failed"
16352         stop ost1 || error "cannot stop ost1"
16353         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16354 }
16355 run_test 232b "failed data version lock should not block umount"
16356
16357 test_233a() {
16358         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16359                 skip "Need MDS version at least 2.3.64"
16360         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16361
16362         local fid=$($LFS path2fid $MOUNT)
16363
16364         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16365                 error "cannot access $MOUNT using its FID '$fid'"
16366 }
16367 run_test 233a "checking that OBF of the FS root succeeds"
16368
16369 test_233b() {
16370         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16371                 skip "Need MDS version at least 2.5.90"
16372         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16373
16374         local fid=$($LFS path2fid $MOUNT/.lustre)
16375
16376         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16377                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16378
16379         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16380         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16381                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16382 }
16383 run_test 233b "checking that OBF of the FS .lustre succeeds"
16384
16385 test_234() {
16386         local p="$TMP/sanityN-$TESTNAME.parameters"
16387         save_lustre_params client "llite.*.xattr_cache" > $p
16388         lctl set_param llite.*.xattr_cache 1 ||
16389                 skip_env "xattr cache is not supported"
16390
16391         mkdir -p $DIR/$tdir || error "mkdir failed"
16392         touch $DIR/$tdir/$tfile || error "touch failed"
16393         # OBD_FAIL_LLITE_XATTR_ENOMEM
16394         $LCTL set_param fail_loc=0x1405
16395         getfattr -n user.attr $DIR/$tdir/$tfile &&
16396                 error "getfattr should have failed with ENOMEM"
16397         $LCTL set_param fail_loc=0x0
16398         rm -rf $DIR/$tdir
16399
16400         restore_lustre_params < $p
16401         rm -f $p
16402 }
16403 run_test 234 "xattr cache should not crash on ENOMEM"
16404
16405 test_235() {
16406         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16407                 skip "Need MDS version at least 2.4.52"
16408
16409         flock_deadlock $DIR/$tfile
16410         local RC=$?
16411         case $RC in
16412                 0)
16413                 ;;
16414                 124) error "process hangs on a deadlock"
16415                 ;;
16416                 *) error "error executing flock_deadlock $DIR/$tfile"
16417                 ;;
16418         esac
16419 }
16420 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16421
16422 #LU-2935
16423 test_236() {
16424         check_swap_layouts_support
16425
16426         local ref1=/etc/passwd
16427         local ref2=/etc/group
16428         local file1=$DIR/$tdir/f1
16429         local file2=$DIR/$tdir/f2
16430
16431         test_mkdir -c1 $DIR/$tdir
16432         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16433         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16434         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16435         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16436         local fd=$(free_fd)
16437         local cmd="exec $fd<>$file2"
16438         eval $cmd
16439         rm $file2
16440         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16441                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16442         cmd="exec $fd>&-"
16443         eval $cmd
16444         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16445
16446         #cleanup
16447         rm -rf $DIR/$tdir
16448 }
16449 run_test 236 "Layout swap on open unlinked file"
16450
16451 # LU-4659 linkea consistency
16452 test_238() {
16453         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16454                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16455                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16456                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16457
16458         touch $DIR/$tfile
16459         ln $DIR/$tfile $DIR/$tfile.lnk
16460         touch $DIR/$tfile.new
16461         mv $DIR/$tfile.new $DIR/$tfile
16462         local fid1=$($LFS path2fid $DIR/$tfile)
16463         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16464         local path1=$($LFS fid2path $FSNAME "$fid1")
16465         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16466         local path2=$($LFS fid2path $FSNAME "$fid2")
16467         [ $tfile.lnk == $path2 ] ||
16468                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16469         rm -f $DIR/$tfile*
16470 }
16471 run_test 238 "Verify linkea consistency"
16472
16473 test_239A() { # was test_239
16474         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16475                 skip "Need MDS version at least 2.5.60"
16476
16477         local list=$(comma_list $(mdts_nodes))
16478
16479         mkdir -p $DIR/$tdir
16480         createmany -o $DIR/$tdir/f- 5000
16481         unlinkmany $DIR/$tdir/f- 5000
16482         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16483                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16484         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16485                         osp.*MDT*.sync_in_flight" | calc_sum)
16486         [ "$changes" -eq 0 ] || error "$changes not synced"
16487 }
16488 run_test 239A "osp_sync test"
16489
16490 test_239a() { #LU-5297
16491         remote_mds_nodsh && skip "remote MDS with nodsh"
16492
16493         touch $DIR/$tfile
16494         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16495         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16496         chgrp $RUNAS_GID $DIR/$tfile
16497         wait_delete_completed
16498 }
16499 run_test 239a "process invalid osp sync record correctly"
16500
16501 test_239b() { #LU-5297
16502         remote_mds_nodsh && skip "remote MDS with nodsh"
16503
16504         touch $DIR/$tfile1
16505         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16506         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16507         chgrp $RUNAS_GID $DIR/$tfile1
16508         wait_delete_completed
16509         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16510         touch $DIR/$tfile2
16511         chgrp $RUNAS_GID $DIR/$tfile2
16512         wait_delete_completed
16513 }
16514 run_test 239b "process osp sync record with ENOMEM error correctly"
16515
16516 test_240() {
16517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16518         remote_mds_nodsh && skip "remote MDS with nodsh"
16519
16520         mkdir -p $DIR/$tdir
16521
16522         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16523                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16524         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16525                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16526
16527         umount_client $MOUNT || error "umount failed"
16528         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16529         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16530         mount_client $MOUNT || error "failed to mount client"
16531
16532         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16533         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16534 }
16535 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16536
16537 test_241_bio() {
16538         local count=$1
16539         local bsize=$2
16540
16541         for LOOP in $(seq $count); do
16542                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16543                 cancel_lru_locks $OSC || true
16544         done
16545 }
16546
16547 test_241_dio() {
16548         local count=$1
16549         local bsize=$2
16550
16551         for LOOP in $(seq $1); do
16552                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16553                         2>/dev/null
16554         done
16555 }
16556
16557 test_241a() { # was test_241
16558         local bsize=$PAGE_SIZE
16559
16560         (( bsize < 40960 )) && bsize=40960
16561         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16562         ls -la $DIR/$tfile
16563         cancel_lru_locks $OSC
16564         test_241_bio 1000 $bsize &
16565         PID=$!
16566         test_241_dio 1000 $bsize
16567         wait $PID
16568 }
16569 run_test 241a "bio vs dio"
16570
16571 test_241b() {
16572         local bsize=$PAGE_SIZE
16573
16574         (( bsize < 40960 )) && bsize=40960
16575         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16576         ls -la $DIR/$tfile
16577         test_241_dio 1000 $bsize &
16578         PID=$!
16579         test_241_dio 1000 $bsize
16580         wait $PID
16581 }
16582 run_test 241b "dio vs dio"
16583
16584 test_242() {
16585         remote_mds_nodsh && skip "remote MDS with nodsh"
16586
16587         mkdir -p $DIR/$tdir
16588         touch $DIR/$tdir/$tfile
16589
16590         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16591         do_facet mds1 lctl set_param fail_loc=0x105
16592         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16593
16594         do_facet mds1 lctl set_param fail_loc=0
16595         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16596 }
16597 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16598
16599 test_243()
16600 {
16601         test_mkdir $DIR/$tdir
16602         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16603 }
16604 run_test 243 "various group lock tests"
16605
16606 test_244()
16607 {
16608         test_mkdir $DIR/$tdir
16609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16610         sendfile_grouplock $DIR/$tdir/$tfile || \
16611                 error "sendfile+grouplock failed"
16612         rm -rf $DIR/$tdir
16613 }
16614 run_test 244 "sendfile with group lock tests"
16615
16616 test_245() {
16617         local flagname="multi_mod_rpcs"
16618         local connect_data_name="max_mod_rpcs"
16619         local out
16620
16621         # check if multiple modify RPCs flag is set
16622         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16623                 grep "connect_flags:")
16624         echo "$out"
16625
16626         echo "$out" | grep -qw $flagname
16627         if [ $? -ne 0 ]; then
16628                 echo "connect flag $flagname is not set"
16629                 return
16630         fi
16631
16632         # check if multiple modify RPCs data is set
16633         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16634         echo "$out"
16635
16636         echo "$out" | grep -qw $connect_data_name ||
16637                 error "import should have connect data $connect_data_name"
16638 }
16639 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16640
16641 test_246() { # LU-7371
16642         remote_ost_nodsh && skip "remote OST with nodsh"
16643         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16644                 skip "Need OST version >= 2.7.62"
16645
16646         do_facet ost1 $LCTL set_param fail_val=4095
16647 #define OBD_FAIL_OST_READ_SIZE          0x234
16648         do_facet ost1 $LCTL set_param fail_loc=0x234
16649         $LFS setstripe $DIR/$tfile -i 0 -c 1
16650         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16651         cancel_lru_locks $FSNAME-OST0000
16652         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16653 }
16654 run_test 246 "Read file of size 4095 should return right length"
16655
16656 cleanup_247() {
16657         local submount=$1
16658
16659         trap 0
16660         umount_client $submount
16661         rmdir $submount
16662 }
16663
16664 test_247a() {
16665         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16666                 grep -q subtree ||
16667                 skip_env "Fileset feature is not supported"
16668
16669         local submount=${MOUNT}_$tdir
16670
16671         mkdir $MOUNT/$tdir
16672         mkdir -p $submount || error "mkdir $submount failed"
16673         FILESET="$FILESET/$tdir" mount_client $submount ||
16674                 error "mount $submount failed"
16675         trap "cleanup_247 $submount" EXIT
16676         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16677         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16678                 error "read $MOUNT/$tdir/$tfile failed"
16679         cleanup_247 $submount
16680 }
16681 run_test 247a "mount subdir as fileset"
16682
16683 test_247b() {
16684         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16685                 skip_env "Fileset feature is not supported"
16686
16687         local submount=${MOUNT}_$tdir
16688
16689         rm -rf $MOUNT/$tdir
16690         mkdir -p $submount || error "mkdir $submount failed"
16691         SKIP_FILESET=1
16692         FILESET="$FILESET/$tdir" mount_client $submount &&
16693                 error "mount $submount should fail"
16694         rmdir $submount
16695 }
16696 run_test 247b "mount subdir that dose not exist"
16697
16698 test_247c() {
16699         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16700                 skip_env "Fileset feature is not supported"
16701
16702         local submount=${MOUNT}_$tdir
16703
16704         mkdir -p $MOUNT/$tdir/dir1
16705         mkdir -p $submount || error "mkdir $submount failed"
16706         trap "cleanup_247 $submount" EXIT
16707         FILESET="$FILESET/$tdir" mount_client $submount ||
16708                 error "mount $submount failed"
16709         local fid=$($LFS path2fid $MOUNT/)
16710         $LFS fid2path $submount $fid && error "fid2path should fail"
16711         cleanup_247 $submount
16712 }
16713 run_test 247c "running fid2path outside root"
16714
16715 test_247d() {
16716         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16717                 skip "Fileset feature is not supported"
16718
16719         local submount=${MOUNT}_$tdir
16720
16721         mkdir -p $MOUNT/$tdir/dir1
16722         mkdir -p $submount || error "mkdir $submount failed"
16723         FILESET="$FILESET/$tdir" mount_client $submount ||
16724                 error "mount $submount failed"
16725         trap "cleanup_247 $submount" EXIT
16726         local fid=$($LFS path2fid $submount/dir1)
16727         $LFS fid2path $submount $fid || error "fid2path should succeed"
16728         cleanup_247 $submount
16729 }
16730 run_test 247d "running fid2path inside root"
16731
16732 # LU-8037
16733 test_247e() {
16734         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16735                 grep -q subtree ||
16736                 skip "Fileset feature is not supported"
16737
16738         local submount=${MOUNT}_$tdir
16739
16740         mkdir $MOUNT/$tdir
16741         mkdir -p $submount || error "mkdir $submount failed"
16742         FILESET="$FILESET/.." mount_client $submount &&
16743                 error "mount $submount should fail"
16744         rmdir $submount
16745 }
16746 run_test 247e "mount .. as fileset"
16747
16748 test_248() {
16749         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16750         [ -z "$fast_read_sav" ] && skip "no fast read support"
16751
16752         # create a large file for fast read verification
16753         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16754
16755         # make sure the file is created correctly
16756         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16757                 { rm -f $DIR/$tfile; skip "file creation error"; }
16758
16759         echo "Test 1: verify that fast read is 4 times faster on cache read"
16760
16761         # small read with fast read enabled
16762         $LCTL set_param -n llite.*.fast_read=1
16763         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16764                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16765                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16766         # small read with fast read disabled
16767         $LCTL set_param -n llite.*.fast_read=0
16768         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16769                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16770                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16771
16772         # verify that fast read is 4 times faster for cache read
16773         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16774                 error_not_in_vm "fast read was not 4 times faster: " \
16775                            "$t_fast vs $t_slow"
16776
16777         echo "Test 2: verify the performance between big and small read"
16778         $LCTL set_param -n llite.*.fast_read=1
16779
16780         # 1k non-cache read
16781         cancel_lru_locks osc
16782         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16783                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16784                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16785
16786         # 1M non-cache read
16787         cancel_lru_locks osc
16788         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16789                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16790                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16791
16792         # verify that big IO is not 4 times faster than small IO
16793         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16794                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16795
16796         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16797         rm -f $DIR/$tfile
16798 }
16799 run_test 248 "fast read verification"
16800
16801 test_249() { # LU-7890
16802         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16803                 skip "Need at least version 2.8.54"
16804
16805         rm -f $DIR/$tfile
16806         $LFS setstripe -c 1 $DIR/$tfile
16807         # Offset 2T == 4k * 512M
16808         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16809                 error "dd to 2T offset failed"
16810 }
16811 run_test 249 "Write above 2T file size"
16812
16813 test_250() {
16814         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16815          && skip "no 16TB file size limit on ZFS"
16816
16817         $LFS setstripe -c 1 $DIR/$tfile
16818         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16819         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16820         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16821         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16822                 conv=notrunc,fsync && error "append succeeded"
16823         return 0
16824 }
16825 run_test 250 "Write above 16T limit"
16826
16827 test_251() {
16828         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16829
16830         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16831         #Skip once - writing the first stripe will succeed
16832         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16833         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16834                 error "short write happened"
16835
16836         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16837         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16838                 error "short read happened"
16839
16840         rm -f $DIR/$tfile
16841 }
16842 run_test 251 "Handling short read and write correctly"
16843
16844 test_252() {
16845         remote_mds_nodsh && skip "remote MDS with nodsh"
16846         remote_ost_nodsh && skip "remote OST with nodsh"
16847         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16848                 skip_env "ldiskfs only test"
16849         fi
16850
16851         local tgt
16852         local dev
16853         local out
16854         local uuid
16855         local num
16856         local gen
16857
16858         # check lr_reader on OST0000
16859         tgt=ost1
16860         dev=$(facet_device $tgt)
16861         out=$(do_facet $tgt $LR_READER $dev)
16862         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16863         echo "$out"
16864         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16865         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16866                 error "Invalid uuid returned by $LR_READER on target $tgt"
16867         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16868
16869         # check lr_reader -c on MDT0000
16870         tgt=mds1
16871         dev=$(facet_device $tgt)
16872         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16873                 skip "$LR_READER does not support additional options"
16874         fi
16875         out=$(do_facet $tgt $LR_READER -c $dev)
16876         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16877         echo "$out"
16878         num=$(echo "$out" | grep -c "mdtlov")
16879         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16880                 error "Invalid number of mdtlov clients returned by $LR_READER"
16881         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16882
16883         # check lr_reader -cr on MDT0000
16884         out=$(do_facet $tgt $LR_READER -cr $dev)
16885         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16886         echo "$out"
16887         echo "$out" | grep -q "^reply_data:$" ||
16888                 error "$LR_READER should have returned 'reply_data' section"
16889         num=$(echo "$out" | grep -c "client_generation")
16890         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16891 }
16892 run_test 252 "check lr_reader tool"
16893
16894 test_253_fill_ost() {
16895         local size_mb #how many MB should we write to pass watermark
16896         local lwm=$3  #low watermark
16897         local free_10mb #10% of free space
16898
16899         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16900         size_mb=$((free_kb / 1024 - lwm))
16901         free_10mb=$((free_kb / 10240))
16902         #If 10% of free space cross low watermark use it
16903         if (( free_10mb > size_mb )); then
16904                 size_mb=$free_10mb
16905         else
16906                 #At least we need to store 1.1 of difference between
16907                 #free space and low watermark
16908                 size_mb=$((size_mb + size_mb / 10))
16909         fi
16910         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16911                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16912                          oflag=append conv=notrunc
16913         fi
16914
16915         sleep_maxage
16916
16917         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16918         echo "OST still has $((free_kb / 1024)) mbytes free"
16919 }
16920
16921 test_253() {
16922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16923         remote_mds_nodsh && skip "remote MDS with nodsh"
16924         remote_mgs_nodsh && skip "remote MGS with nodsh"
16925
16926         local ostidx=0
16927         local rc=0
16928
16929         local ost_name=$($LFS osts |
16930                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16931         # on the mdt's osc
16932         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16933         do_facet $SINGLEMDS $LCTL get_param -n \
16934                 osp.$mdtosc_proc1.reserved_mb_high ||
16935                 skip  "remote MDS does not support reserved_mb_high"
16936
16937         rm -rf $DIR/$tdir
16938         wait_mds_ost_sync
16939         wait_delete_completed
16940         mkdir $DIR/$tdir
16941
16942         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16943                         osp.$mdtosc_proc1.reserved_mb_high)
16944         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16945                         osp.$mdtosc_proc1.reserved_mb_low)
16946         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16947
16948         if ! combined_mgs_mds ; then
16949                 mount_mgs_client
16950         fi
16951         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16952         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16953                 error "Adding $ost_name to pool failed"
16954
16955         # Wait for client to see a OST at pool
16956         wait_update $HOSTNAME "$LCTL get_param -n
16957                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16958                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16959                 error "Client can not see the pool"
16960         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16961                 error "Setstripe failed"
16962
16963         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16964         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16965         echo "OST still has $((blocks/1024)) mbytes free"
16966
16967         local new_lwm=$((blocks/1024-10))
16968         do_facet $SINGLEMDS $LCTL set_param \
16969                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16970         do_facet $SINGLEMDS $LCTL set_param \
16971                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16972
16973         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16974
16975         #First enospc could execute orphan deletion so repeat.
16976         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16977
16978         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16979                         osp.$mdtosc_proc1.prealloc_status)
16980         echo "prealloc_status $oa_status"
16981
16982         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16983                 error "File creation should fail"
16984         #object allocation was stopped, but we still able to append files
16985         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16986                 error "Append failed"
16987         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16988
16989         wait_delete_completed
16990
16991         sleep_maxage
16992
16993         for i in $(seq 10 12); do
16994                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16995                         error "File creation failed after rm";
16996         done
16997
16998         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16999                         osp.$mdtosc_proc1.prealloc_status)
17000         echo "prealloc_status $oa_status"
17001
17002         if (( oa_status != 0 )); then
17003                 error "Object allocation still disable after rm"
17004         fi
17005         do_facet $SINGLEMDS $LCTL set_param \
17006                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
17007         do_facet $SINGLEMDS $LCTL set_param \
17008                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
17009
17010
17011         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
17012                 error "Remove $ost_name from pool failed"
17013         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17014                 error "Pool destroy fialed"
17015
17016         if ! combined_mgs_mds ; then
17017                 umount_mgs_client
17018         fi
17019 }
17020 run_test 253 "Check object allocation limit"
17021
17022 test_254() {
17023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17024         remote_mds_nodsh && skip "remote MDS with nodsh"
17025         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17026                 skip "MDS does not support changelog_size"
17027
17028         local cl_user
17029         local MDT0=$(facet_svc $SINGLEMDS)
17030
17031         changelog_register || error "changelog_register failed"
17032
17033         changelog_clear 0 || error "changelog_clear failed"
17034
17035         local size1=$(do_facet $SINGLEMDS \
17036                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17037         echo "Changelog size $size1"
17038
17039         rm -rf $DIR/$tdir
17040         $LFS mkdir -i 0 $DIR/$tdir
17041         # change something
17042         mkdir -p $DIR/$tdir/pics/2008/zachy
17043         touch $DIR/$tdir/pics/2008/zachy/timestamp
17044         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17045         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17046         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17047         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17048         rm $DIR/$tdir/pics/desktop.jpg
17049
17050         local size2=$(do_facet $SINGLEMDS \
17051                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17052         echo "Changelog size after work $size2"
17053
17054         (( $size2 > $size1 )) ||
17055                 error "new Changelog size=$size2 less than old size=$size1"
17056 }
17057 run_test 254 "Check changelog size"
17058
17059 ladvise_no_type()
17060 {
17061         local type=$1
17062         local file=$2
17063
17064         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17065                 awk -F: '{print $2}' | grep $type > /dev/null
17066         if [ $? -ne 0 ]; then
17067                 return 0
17068         fi
17069         return 1
17070 }
17071
17072 ladvise_no_ioctl()
17073 {
17074         local file=$1
17075
17076         lfs ladvise -a willread $file > /dev/null 2>&1
17077         if [ $? -eq 0 ]; then
17078                 return 1
17079         fi
17080
17081         lfs ladvise -a willread $file 2>&1 |
17082                 grep "Inappropriate ioctl for device" > /dev/null
17083         if [ $? -eq 0 ]; then
17084                 return 0
17085         fi
17086         return 1
17087 }
17088
17089 percent() {
17090         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17091 }
17092
17093 # run a random read IO workload
17094 # usage: random_read_iops <filename> <filesize> <iosize>
17095 random_read_iops() {
17096         local file=$1
17097         local fsize=$2
17098         local iosize=${3:-4096}
17099
17100         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17101                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17102 }
17103
17104 drop_file_oss_cache() {
17105         local file="$1"
17106         local nodes="$2"
17107
17108         $LFS ladvise -a dontneed $file 2>/dev/null ||
17109                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17110 }
17111
17112 ladvise_willread_performance()
17113 {
17114         local repeat=10
17115         local average_origin=0
17116         local average_cache=0
17117         local average_ladvise=0
17118
17119         for ((i = 1; i <= $repeat; i++)); do
17120                 echo "Iter $i/$repeat: reading without willread hint"
17121                 cancel_lru_locks osc
17122                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17123                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17124                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17125                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17126
17127                 cancel_lru_locks osc
17128                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17129                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17130                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17131
17132                 cancel_lru_locks osc
17133                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17134                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17135                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17136                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17137                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17138         done
17139         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17140         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17141         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17142
17143         speedup_cache=$(percent $average_cache $average_origin)
17144         speedup_ladvise=$(percent $average_ladvise $average_origin)
17145
17146         echo "Average uncached read: $average_origin"
17147         echo "Average speedup with OSS cached read: " \
17148                 "$average_cache = +$speedup_cache%"
17149         echo "Average speedup with ladvise willread: " \
17150                 "$average_ladvise = +$speedup_ladvise%"
17151
17152         local lowest_speedup=20
17153         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17154                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17155                         "got $average_cache%. Skipping ladvise willread check."
17156                 return 0
17157         fi
17158
17159         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17160         # it is still good to run until then to exercise 'ladvise willread'
17161         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17162                 [ "$ost1_FSTYPE" = "zfs" ] &&
17163                 echo "osd-zfs does not support dontneed or drop_caches" &&
17164                 return 0
17165
17166         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17167         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17168                 error_not_in_vm "Speedup with willread is less than " \
17169                         "$lowest_speedup%, got $average_ladvise%"
17170 }
17171
17172 test_255a() {
17173         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17174                 skip "lustre < 2.8.54 does not support ladvise "
17175         remote_ost_nodsh && skip "remote OST with nodsh"
17176
17177         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17178
17179         ladvise_no_type willread $DIR/$tfile &&
17180                 skip "willread ladvise is not supported"
17181
17182         ladvise_no_ioctl $DIR/$tfile &&
17183                 skip "ladvise ioctl is not supported"
17184
17185         local size_mb=100
17186         local size=$((size_mb * 1048576))
17187         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17188                 error "dd to $DIR/$tfile failed"
17189
17190         lfs ladvise -a willread $DIR/$tfile ||
17191                 error "Ladvise failed with no range argument"
17192
17193         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17194                 error "Ladvise failed with no -l or -e argument"
17195
17196         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17197                 error "Ladvise failed with only -e argument"
17198
17199         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17200                 error "Ladvise failed with only -l argument"
17201
17202         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17203                 error "End offset should not be smaller than start offset"
17204
17205         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17206                 error "End offset should not be equal to start offset"
17207
17208         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17209                 error "Ladvise failed with overflowing -s argument"
17210
17211         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17212                 error "Ladvise failed with overflowing -e argument"
17213
17214         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17215                 error "Ladvise failed with overflowing -l argument"
17216
17217         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17218                 error "Ladvise succeeded with conflicting -l and -e arguments"
17219
17220         echo "Synchronous ladvise should wait"
17221         local delay=4
17222 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17223         do_nodes $(comma_list $(osts_nodes)) \
17224                 $LCTL set_param fail_val=$delay fail_loc=0x237
17225
17226         local start_ts=$SECONDS
17227         lfs ladvise -a willread $DIR/$tfile ||
17228                 error "Ladvise failed with no range argument"
17229         local end_ts=$SECONDS
17230         local inteval_ts=$((end_ts - start_ts))
17231
17232         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17233                 error "Synchronous advice didn't wait reply"
17234         fi
17235
17236         echo "Asynchronous ladvise shouldn't wait"
17237         local start_ts=$SECONDS
17238         lfs ladvise -a willread -b $DIR/$tfile ||
17239                 error "Ladvise failed with no range argument"
17240         local end_ts=$SECONDS
17241         local inteval_ts=$((end_ts - start_ts))
17242
17243         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17244                 error "Asynchronous advice blocked"
17245         fi
17246
17247         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17248         ladvise_willread_performance
17249 }
17250 run_test 255a "check 'lfs ladvise -a willread'"
17251
17252 facet_meminfo() {
17253         local facet=$1
17254         local info=$2
17255
17256         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17257 }
17258
17259 test_255b() {
17260         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17261                 skip "lustre < 2.8.54 does not support ladvise "
17262         remote_ost_nodsh && skip "remote OST with nodsh"
17263
17264         lfs setstripe -c 1 -i 0 $DIR/$tfile
17265
17266         ladvise_no_type dontneed $DIR/$tfile &&
17267                 skip "dontneed ladvise is not supported"
17268
17269         ladvise_no_ioctl $DIR/$tfile &&
17270                 skip "ladvise ioctl is not supported"
17271
17272         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17273                 [ "$ost1_FSTYPE" = "zfs" ] &&
17274                 skip "zfs-osd does not support 'ladvise dontneed'"
17275
17276         local size_mb=100
17277         local size=$((size_mb * 1048576))
17278         # In order to prevent disturbance of other processes, only check 3/4
17279         # of the memory usage
17280         local kibibytes=$((size_mb * 1024 * 3 / 4))
17281
17282         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17283                 error "dd to $DIR/$tfile failed"
17284
17285         #force write to complete before dropping OST cache & checking memory
17286         sync
17287
17288         local total=$(facet_meminfo ost1 MemTotal)
17289         echo "Total memory: $total KiB"
17290
17291         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17292         local before_read=$(facet_meminfo ost1 Cached)
17293         echo "Cache used before read: $before_read KiB"
17294
17295         lfs ladvise -a willread $DIR/$tfile ||
17296                 error "Ladvise willread failed"
17297         local after_read=$(facet_meminfo ost1 Cached)
17298         echo "Cache used after read: $after_read KiB"
17299
17300         lfs ladvise -a dontneed $DIR/$tfile ||
17301                 error "Ladvise dontneed again failed"
17302         local no_read=$(facet_meminfo ost1 Cached)
17303         echo "Cache used after dontneed ladvise: $no_read KiB"
17304
17305         if [ $total -lt $((before_read + kibibytes)) ]; then
17306                 echo "Memory is too small, abort checking"
17307                 return 0
17308         fi
17309
17310         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17311                 error "Ladvise willread should use more memory" \
17312                         "than $kibibytes KiB"
17313         fi
17314
17315         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17316                 error "Ladvise dontneed should release more memory" \
17317                         "than $kibibytes KiB"
17318         fi
17319 }
17320 run_test 255b "check 'lfs ladvise -a dontneed'"
17321
17322 test_255c() {
17323         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17324                 skip "lustre < 2.10.53 does not support lockahead"
17325
17326         local count
17327         local new_count
17328         local difference
17329         local i
17330         local rc
17331
17332         test_mkdir -p $DIR/$tdir
17333         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17334
17335         #test 10 returns only success/failure
17336         i=10
17337         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17338         rc=$?
17339         if [ $rc -eq 255 ]; then
17340                 error "Ladvise test${i} failed, ${rc}"
17341         fi
17342
17343         #test 11 counts lock enqueue requests, all others count new locks
17344         i=11
17345         count=$(do_facet ost1 \
17346                 $LCTL get_param -n ost.OSS.ost.stats)
17347         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17348
17349         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17350         rc=$?
17351         if [ $rc -eq 255 ]; then
17352                 error "Ladvise test${i} failed, ${rc}"
17353         fi
17354
17355         new_count=$(do_facet ost1 \
17356                 $LCTL get_param -n ost.OSS.ost.stats)
17357         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17358                    awk '{ print $2 }')
17359
17360         difference="$((new_count - count))"
17361         if [ $difference -ne $rc ]; then
17362                 error "Ladvise test${i}, bad enqueue count, returned " \
17363                       "${rc}, actual ${difference}"
17364         fi
17365
17366         for i in $(seq 12 21); do
17367                 # If we do not do this, we run the risk of having too many
17368                 # locks and starting lock cancellation while we are checking
17369                 # lock counts.
17370                 cancel_lru_locks osc
17371
17372                 count=$($LCTL get_param -n \
17373                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17374
17375                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17376                 rc=$?
17377                 if [ $rc -eq 255 ]; then
17378                         error "Ladvise test ${i} failed, ${rc}"
17379                 fi
17380
17381                 new_count=$($LCTL get_param -n \
17382                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17383                 difference="$((new_count - count))"
17384
17385                 # Test 15 output is divided by 100 to map down to valid return
17386                 if [ $i -eq 15 ]; then
17387                         rc="$((rc * 100))"
17388                 fi
17389
17390                 if [ $difference -ne $rc ]; then
17391                         error "Ladvise test ${i}, bad lock count, returned " \
17392                               "${rc}, actual ${difference}"
17393                 fi
17394         done
17395
17396         #test 22 returns only success/failure
17397         i=22
17398         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17399         rc=$?
17400         if [ $rc -eq 255 ]; then
17401                 error "Ladvise test${i} failed, ${rc}"
17402         fi
17403 }
17404 run_test 255c "suite of ladvise lockahead tests"
17405
17406 test_256() {
17407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17408         remote_mds_nodsh && skip "remote MDS with nodsh"
17409         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17410         changelog_users $SINGLEMDS | grep "^cl" &&
17411                 skip "active changelog user"
17412
17413         local cl_user
17414         local cat_sl
17415         local mdt_dev
17416
17417         mdt_dev=$(mdsdevname 1)
17418         echo $mdt_dev
17419
17420         changelog_register || error "changelog_register failed"
17421
17422         rm -rf $DIR/$tdir
17423         mkdir -p $DIR/$tdir
17424
17425         changelog_clear 0 || error "changelog_clear failed"
17426
17427         # change something
17428         touch $DIR/$tdir/{1..10}
17429
17430         # stop the MDT
17431         stop $SINGLEMDS || error "Fail to stop MDT"
17432
17433         # remount the MDT
17434
17435         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17436
17437         #after mount new plainllog is used
17438         touch $DIR/$tdir/{11..19}
17439         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17440         cat_sl=$(do_facet $SINGLEMDS "sync; \
17441                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17442                  llog_reader $tmpfile | grep -c type=1064553b")
17443         do_facet $SINGLEMDS llog_reader $tmpfile
17444
17445         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17446
17447         changelog_clear 0 || error "changelog_clear failed"
17448
17449         cat_sl=$(do_facet $SINGLEMDS "sync; \
17450                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17451                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17452
17453         if (( cat_sl == 2 )); then
17454                 error "Empty plain llog was not deleted from changelog catalog"
17455         elif (( cat_sl != 1 )); then
17456                 error "Active plain llog shouldn't be deleted from catalog"
17457         fi
17458 }
17459 run_test 256 "Check llog delete for empty and not full state"
17460
17461 test_257() {
17462         remote_mds_nodsh && skip "remote MDS with nodsh"
17463         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17464                 skip "Need MDS version at least 2.8.55"
17465
17466         test_mkdir $DIR/$tdir
17467
17468         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17469                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17470         stat $DIR/$tdir
17471
17472 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17473         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17474         local facet=mds$((mdtidx + 1))
17475         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17476         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17477
17478         stop $facet || error "stop MDS failed"
17479         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17480                 error "start MDS fail"
17481         wait_recovery_complete $facet
17482 }
17483 run_test 257 "xattr locks are not lost"
17484
17485 # Verify we take the i_mutex when security requires it
17486 test_258a() {
17487 #define OBD_FAIL_IMUTEX_SEC 0x141c
17488         $LCTL set_param fail_loc=0x141c
17489         touch $DIR/$tfile
17490         chmod u+s $DIR/$tfile
17491         chmod a+rwx $DIR/$tfile
17492         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17493         RC=$?
17494         if [ $RC -ne 0 ]; then
17495                 error "error, failed to take i_mutex, rc=$?"
17496         fi
17497         rm -f $DIR/$tfile
17498 }
17499 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17500
17501 # Verify we do NOT take the i_mutex in the normal case
17502 test_258b() {
17503 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17504         $LCTL set_param fail_loc=0x141d
17505         touch $DIR/$tfile
17506         chmod a+rwx $DIR
17507         chmod a+rw $DIR/$tfile
17508         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17509         RC=$?
17510         if [ $RC -ne 0 ]; then
17511                 error "error, took i_mutex unnecessarily, rc=$?"
17512         fi
17513         rm -f $DIR/$tfile
17514
17515 }
17516 run_test 258b "verify i_mutex security behavior"
17517
17518 test_259() {
17519         local file=$DIR/$tfile
17520         local before
17521         local after
17522
17523         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17524
17525         stack_trap "rm -f $file" EXIT
17526
17527         wait_delete_completed
17528         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17529         echo "before: $before"
17530
17531         $LFS setstripe -i 0 -c 1 $file
17532         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17533         sync_all_data
17534         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17535         echo "after write: $after"
17536
17537 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17538         do_facet ost1 $LCTL set_param fail_loc=0x2301
17539         $TRUNCATE $file 0
17540         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17541         echo "after truncate: $after"
17542
17543         stop ost1
17544         do_facet ost1 $LCTL set_param fail_loc=0
17545         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17546         sleep 2
17547         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17548         echo "after restart: $after"
17549         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17550                 error "missing truncate?"
17551
17552         return 0
17553 }
17554 run_test 259 "crash at delayed truncate"
17555
17556 test_260() {
17557 #define OBD_FAIL_MDC_CLOSE               0x806
17558         $LCTL set_param fail_loc=0x80000806
17559         touch $DIR/$tfile
17560
17561 }
17562 run_test 260 "Check mdc_close fail"
17563
17564 ### Data-on-MDT sanity tests ###
17565 test_270a() {
17566         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17567                 skip "Need MDS version at least 2.10.55 for DoM"
17568
17569         # create DoM file
17570         local dom=$DIR/$tdir/dom_file
17571         local tmp=$DIR/$tdir/tmp_file
17572
17573         mkdir -p $DIR/$tdir
17574
17575         # basic checks for DoM component creation
17576         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17577                 error "Can set MDT layout to non-first entry"
17578
17579         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17580                 error "Can define multiple entries as MDT layout"
17581
17582         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17583
17584         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17585         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17586         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17587
17588         local mdtidx=$($LFS getstripe -m $dom)
17589         local mdtname=MDT$(printf %04x $mdtidx)
17590         local facet=mds$((mdtidx + 1))
17591         local space_check=1
17592
17593         # Skip free space checks with ZFS
17594         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17595
17596         # write
17597         sync
17598         local size_tmp=$((65536 * 3))
17599         local mdtfree1=$(do_facet $facet \
17600                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17601
17602         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17603         # check also direct IO along write
17604         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17605         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17606         sync
17607         cmp $tmp $dom || error "file data is different"
17608         [ $(stat -c%s $dom) == $size_tmp ] ||
17609                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17610         if [ $space_check == 1 ]; then
17611                 local mdtfree2=$(do_facet $facet \
17612                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17613
17614                 # increase in usage from by $size_tmp
17615                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17616                         error "MDT free space wrong after write: " \
17617                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17618         fi
17619
17620         # truncate
17621         local size_dom=10000
17622
17623         $TRUNCATE $dom $size_dom
17624         [ $(stat -c%s $dom) == $size_dom ] ||
17625                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17626         if [ $space_check == 1 ]; then
17627                 mdtfree1=$(do_facet $facet \
17628                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17629                 # decrease in usage from $size_tmp to new $size_dom
17630                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17631                   $(((size_tmp - size_dom) / 1024)) ] ||
17632                         error "MDT free space is wrong after truncate: " \
17633                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17634         fi
17635
17636         # append
17637         cat $tmp >> $dom
17638         sync
17639         size_dom=$((size_dom + size_tmp))
17640         [ $(stat -c%s $dom) == $size_dom ] ||
17641                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17642         if [ $space_check == 1 ]; then
17643                 mdtfree2=$(do_facet $facet \
17644                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17645                 # increase in usage by $size_tmp from previous
17646                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17647                         error "MDT free space is wrong after append: " \
17648                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17649         fi
17650
17651         # delete
17652         rm $dom
17653         if [ $space_check == 1 ]; then
17654                 mdtfree1=$(do_facet $facet \
17655                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17656                 # decrease in usage by $size_dom from previous
17657                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17658                         error "MDT free space is wrong after removal: " \
17659                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17660         fi
17661
17662         # combined striping
17663         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17664                 error "Can't create DoM + OST striping"
17665
17666         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17667         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17668         # check also direct IO along write
17669         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17670         sync
17671         cmp $tmp $dom || error "file data is different"
17672         [ $(stat -c%s $dom) == $size_tmp ] ||
17673                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17674         rm $dom $tmp
17675
17676         return 0
17677 }
17678 run_test 270a "DoM: basic functionality tests"
17679
17680 test_270b() {
17681         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17682                 skip "Need MDS version at least 2.10.55"
17683
17684         local dom=$DIR/$tdir/dom_file
17685         local max_size=1048576
17686
17687         mkdir -p $DIR/$tdir
17688         $LFS setstripe -E $max_size -L mdt $dom
17689
17690         # truncate over the limit
17691         $TRUNCATE $dom $(($max_size + 1)) &&
17692                 error "successful truncate over the maximum size"
17693         # write over the limit
17694         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17695                 error "successful write over the maximum size"
17696         # append over the limit
17697         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17698         echo "12345" >> $dom && error "successful append over the maximum size"
17699         rm $dom
17700
17701         return 0
17702 }
17703 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17704
17705 test_270c() {
17706         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17707                 skip "Need MDS version at least 2.10.55"
17708
17709         mkdir -p $DIR/$tdir
17710         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17711
17712         # check files inherit DoM EA
17713         touch $DIR/$tdir/first
17714         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17715                 error "bad pattern"
17716         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17717                 error "bad stripe count"
17718         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17719                 error "bad stripe size"
17720
17721         # check directory inherits DoM EA and uses it as default
17722         mkdir $DIR/$tdir/subdir
17723         touch $DIR/$tdir/subdir/second
17724         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17725                 error "bad pattern in sub-directory"
17726         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17727                 error "bad stripe count in sub-directory"
17728         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17729                 error "bad stripe size in sub-directory"
17730         return 0
17731 }
17732 run_test 270c "DoM: DoM EA inheritance tests"
17733
17734 test_270d() {
17735         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17736                 skip "Need MDS version at least 2.10.55"
17737
17738         mkdir -p $DIR/$tdir
17739         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17740
17741         # inherit default DoM striping
17742         mkdir $DIR/$tdir/subdir
17743         touch $DIR/$tdir/subdir/f1
17744
17745         # change default directory striping
17746         $LFS setstripe -c 1 $DIR/$tdir/subdir
17747         touch $DIR/$tdir/subdir/f2
17748         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17749                 error "wrong default striping in file 2"
17750         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17751                 error "bad pattern in file 2"
17752         return 0
17753 }
17754 run_test 270d "DoM: change striping from DoM to RAID0"
17755
17756 test_270e() {
17757         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17758                 skip "Need MDS version at least 2.10.55"
17759
17760         mkdir -p $DIR/$tdir/dom
17761         mkdir -p $DIR/$tdir/norm
17762         DOMFILES=20
17763         NORMFILES=10
17764         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17765         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17766
17767         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17768         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17769
17770         # find DoM files by layout
17771         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17772         [ $NUM -eq  $DOMFILES ] ||
17773                 error "lfs find -L: found $NUM, expected $DOMFILES"
17774         echo "Test 1: lfs find 20 DOM files by layout: OK"
17775
17776         # there should be 1 dir with default DOM striping
17777         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17778         [ $NUM -eq  1 ] ||
17779                 error "lfs find -L: found $NUM, expected 1 dir"
17780         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17781
17782         # find DoM files by stripe size
17783         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17784         [ $NUM -eq  $DOMFILES ] ||
17785                 error "lfs find -S: found $NUM, expected $DOMFILES"
17786         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17787
17788         # find files by stripe offset except DoM files
17789         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17790         [ $NUM -eq  $NORMFILES ] ||
17791                 error "lfs find -i: found $NUM, expected $NORMFILES"
17792         echo "Test 5: lfs find no DOM files by stripe index: OK"
17793         return 0
17794 }
17795 run_test 270e "DoM: lfs find with DoM files test"
17796
17797 test_270f() {
17798         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17799                 skip "Need MDS version at least 2.10.55"
17800
17801         local mdtname=${FSNAME}-MDT0000-mdtlov
17802         local dom=$DIR/$tdir/dom_file
17803         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17804                                                 lod.$mdtname.dom_stripesize)
17805         local dom_limit=131072
17806
17807         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17808         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17809                                                 lod.$mdtname.dom_stripesize)
17810         [ ${dom_limit} -eq ${dom_current} ] ||
17811                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17812
17813         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17814         $LFS setstripe -d $DIR/$tdir
17815         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17816                 error "Can't set directory default striping"
17817
17818         # exceed maximum stripe size
17819         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17820                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17821         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17822                 error "Able to create DoM component size more than LOD limit"
17823
17824         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17825         dom_current=$(do_facet mds1 $LCTL get_param -n \
17826                                                 lod.$mdtname.dom_stripesize)
17827         [ 0 -eq ${dom_current} ] ||
17828                 error "Can't set zero DoM stripe limit"
17829         rm $dom
17830
17831         # attempt to create DoM file on server with disabled DoM should
17832         # remove DoM entry from layout and be succeed
17833         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17834                 error "Can't create DoM file (DoM is disabled)"
17835         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17836                 error "File has DoM component while DoM is disabled"
17837         rm $dom
17838
17839         # attempt to create DoM file with only DoM stripe should return error
17840         $LFS setstripe -E $dom_limit -L mdt $dom &&
17841                 error "Able to create DoM-only file while DoM is disabled"
17842
17843         # too low values to be aligned with smallest stripe size 64K
17844         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17845         dom_current=$(do_facet mds1 $LCTL get_param -n \
17846                                                 lod.$mdtname.dom_stripesize)
17847         [ 30000 -eq ${dom_current} ] &&
17848                 error "Can set too small DoM stripe limit"
17849
17850         # 64K is a minimal stripe size in Lustre, expect limit of that size
17851         [ 65536 -eq ${dom_current} ] ||
17852                 error "Limit is not set to 64K but ${dom_current}"
17853
17854         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17855         dom_current=$(do_facet mds1 $LCTL get_param -n \
17856                                                 lod.$mdtname.dom_stripesize)
17857         echo $dom_current
17858         [ 2147483648 -eq ${dom_current} ] &&
17859                 error "Can set too large DoM stripe limit"
17860
17861         do_facet mds1 $LCTL set_param -n \
17862                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17863         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17864                 error "Can't create DoM component size after limit change"
17865         do_facet mds1 $LCTL set_param -n \
17866                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17867         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17868                 error "Can't create DoM file after limit decrease"
17869         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17870                 error "Can create big DoM component after limit decrease"
17871         touch ${dom}_def ||
17872                 error "Can't create file with old default layout"
17873
17874         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17875         return 0
17876 }
17877 run_test 270f "DoM: maximum DoM stripe size checks"
17878
17879 test_271a() {
17880         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17881                 skip "Need MDS version at least 2.10.55"
17882
17883         local dom=$DIR/$tdir/dom
17884
17885         mkdir -p $DIR/$tdir
17886
17887         $LFS setstripe -E 1024K -L mdt $dom
17888
17889         lctl set_param -n mdc.*.stats=clear
17890         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17891         cat $dom > /dev/null
17892         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17893         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17894         ls $dom
17895         rm -f $dom
17896 }
17897 run_test 271a "DoM: data is cached for read after write"
17898
17899 test_271b() {
17900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17901                 skip "Need MDS version at least 2.10.55"
17902
17903         local dom=$DIR/$tdir/dom
17904
17905         mkdir -p $DIR/$tdir
17906
17907         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17908
17909         lctl set_param -n mdc.*.stats=clear
17910         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17911         cancel_lru_locks mdc
17912         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17913         # second stat to check size is cached on client
17914         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17915         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17916         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17917         rm -f $dom
17918 }
17919 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17920
17921 test_271ba() {
17922         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17923                 skip "Need MDS version at least 2.10.55"
17924
17925         local dom=$DIR/$tdir/dom
17926
17927         mkdir -p $DIR/$tdir
17928
17929         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17930
17931         lctl set_param -n mdc.*.stats=clear
17932         lctl set_param -n osc.*.stats=clear
17933         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17934         cancel_lru_locks mdc
17935         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17936         # second stat to check size is cached on client
17937         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17938         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17939         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17940         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17941         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17942         rm -f $dom
17943 }
17944 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17945
17946
17947 get_mdc_stats() {
17948         local mdtidx=$1
17949         local param=$2
17950         local mdt=MDT$(printf %04x $mdtidx)
17951
17952         if [ -z $param ]; then
17953                 lctl get_param -n mdc.*$mdt*.stats
17954         else
17955                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17956         fi
17957 }
17958
17959 test_271c() {
17960         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17961                 skip "Need MDS version at least 2.10.55"
17962
17963         local dom=$DIR/$tdir/dom
17964
17965         mkdir -p $DIR/$tdir
17966
17967         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17968
17969         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17970         local facet=mds$((mdtidx + 1))
17971
17972         cancel_lru_locks mdc
17973         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17974         createmany -o $dom 1000
17975         lctl set_param -n mdc.*.stats=clear
17976         smalliomany -w $dom 1000 200
17977         get_mdc_stats $mdtidx
17978         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17979         # Each file has 1 open, 1 IO enqueues, total 2000
17980         # but now we have also +1 getxattr for security.capability, total 3000
17981         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17982         unlinkmany $dom 1000
17983
17984         cancel_lru_locks mdc
17985         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17986         createmany -o $dom 1000
17987         lctl set_param -n mdc.*.stats=clear
17988         smalliomany -w $dom 1000 200
17989         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17990         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17991         # for OPEN and IO lock.
17992         [ $((enq - enq_2)) -ge 1000 ] ||
17993                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17994         unlinkmany $dom 1000
17995         return 0
17996 }
17997 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17998
17999 cleanup_271def_tests() {
18000         trap 0
18001         rm -f $1
18002 }
18003
18004 test_271d() {
18005         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18006                 skip "Need MDS version at least 2.10.57"
18007
18008         local dom=$DIR/$tdir/dom
18009         local tmp=$TMP/$tfile
18010         trap "cleanup_271def_tests $tmp" EXIT
18011
18012         mkdir -p $DIR/$tdir
18013
18014         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18015
18016         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18017
18018         cancel_lru_locks mdc
18019         dd if=/dev/urandom of=$tmp bs=1000 count=1
18020         dd if=$tmp of=$dom bs=1000 count=1
18021         cancel_lru_locks mdc
18022
18023         cat /etc/hosts >> $tmp
18024         lctl set_param -n mdc.*.stats=clear
18025
18026         # append data to the same file it should update local page
18027         echo "Append to the same page"
18028         cat /etc/hosts >> $dom
18029         local num=$(get_mdc_stats $mdtidx ost_read)
18030         local ra=$(get_mdc_stats $mdtidx req_active)
18031         local rw=$(get_mdc_stats $mdtidx req_waittime)
18032
18033         [ -z $num ] || error "$num READ RPC occured"
18034         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18035         echo "... DONE"
18036
18037         # compare content
18038         cmp $tmp $dom || error "file miscompare"
18039
18040         cancel_lru_locks mdc
18041         lctl set_param -n mdc.*.stats=clear
18042
18043         echo "Open and read file"
18044         cat $dom > /dev/null
18045         local num=$(get_mdc_stats $mdtidx ost_read)
18046         local ra=$(get_mdc_stats $mdtidx req_active)
18047         local rw=$(get_mdc_stats $mdtidx req_waittime)
18048
18049         [ -z $num ] || error "$num READ RPC occured"
18050         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18051         echo "... DONE"
18052
18053         # compare content
18054         cmp $tmp $dom || error "file miscompare"
18055
18056         return 0
18057 }
18058 run_test 271d "DoM: read on open (1K file in reply buffer)"
18059
18060 test_271f() {
18061         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18062                 skip "Need MDS version at least 2.10.57"
18063
18064         local dom=$DIR/$tdir/dom
18065         local tmp=$TMP/$tfile
18066         trap "cleanup_271def_tests $tmp" EXIT
18067
18068         mkdir -p $DIR/$tdir
18069
18070         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18071
18072         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18073
18074         cancel_lru_locks mdc
18075         dd if=/dev/urandom of=$tmp bs=200000 count=1
18076         dd if=$tmp of=$dom bs=200000 count=1
18077         cancel_lru_locks mdc
18078         cat /etc/hosts >> $tmp
18079         lctl set_param -n mdc.*.stats=clear
18080
18081         echo "Append to the same page"
18082         cat /etc/hosts >> $dom
18083         local num=$(get_mdc_stats $mdtidx ost_read)
18084         local ra=$(get_mdc_stats $mdtidx req_active)
18085         local rw=$(get_mdc_stats $mdtidx req_waittime)
18086
18087         [ -z $num ] || error "$num READ RPC occured"
18088         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18089         echo "... DONE"
18090
18091         # compare content
18092         cmp $tmp $dom || error "file miscompare"
18093
18094         cancel_lru_locks mdc
18095         lctl set_param -n mdc.*.stats=clear
18096
18097         echo "Open and read file"
18098         cat $dom > /dev/null
18099         local num=$(get_mdc_stats $mdtidx ost_read)
18100         local ra=$(get_mdc_stats $mdtidx req_active)
18101         local rw=$(get_mdc_stats $mdtidx req_waittime)
18102
18103         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18104         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18105         echo "... DONE"
18106
18107         # compare content
18108         cmp $tmp $dom || error "file miscompare"
18109
18110         return 0
18111 }
18112 run_test 271f "DoM: read on open (200K file and read tail)"
18113
18114 test_271g() {
18115         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18116                 skip "Skipping due to old client or server version"
18117
18118         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18119         # to get layout
18120         $CHECKSTAT -t file $DIR1/$tfile
18121
18122         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18123         MULTIOP_PID=$!
18124         sleep 1
18125         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18126         $LCTL set_param fail_loc=0x80000314
18127         rm $DIR1/$tfile || error "Unlink fails"
18128         RC=$?
18129         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18130         [ $RC -eq 0 ] || error "Failed write to stale object"
18131 }
18132 run_test 271g "Discard DoM data vs client flush race"
18133
18134 test_272a() {
18135         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18136                 skip "Need MDS version at least 2.11.50"
18137
18138         local dom=$DIR/$tdir/dom
18139         mkdir -p $DIR/$tdir
18140
18141         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18142         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18143                 error "failed to write data into $dom"
18144         local old_md5=$(md5sum $dom)
18145
18146         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18147                 error "failed to migrate to the same DoM component"
18148
18149         local new_md5=$(md5sum $dom)
18150
18151         [ "$old_md5" == "$new_md5" ] ||
18152                 error "md5sum differ: $old_md5, $new_md5"
18153
18154         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18155                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18156 }
18157 run_test 272a "DoM migration: new layout with the same DOM component"
18158
18159 test_272b() {
18160         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18161                 skip "Need MDS version at least 2.11.50"
18162
18163         local dom=$DIR/$tdir/dom
18164         mkdir -p $DIR/$tdir
18165         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18166
18167         local mdtidx=$($LFS getstripe -m $dom)
18168         local mdtname=MDT$(printf %04x $mdtidx)
18169         local facet=mds$((mdtidx + 1))
18170
18171         local mdtfree1=$(do_facet $facet \
18172                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18173         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18174                 error "failed to write data into $dom"
18175         local old_md5=$(md5sum $dom)
18176         cancel_lru_locks mdc
18177         local mdtfree1=$(do_facet $facet \
18178                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18179
18180         $LFS migrate -c2 $dom ||
18181                 error "failed to migrate to the new composite layout"
18182         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18183                 error "MDT stripe was not removed"
18184
18185         cancel_lru_locks mdc
18186         local new_md5=$(md5sum $dom)
18187         [ "$old_md5" != "$new_md5" ] &&
18188                 error "$old_md5 != $new_md5"
18189
18190         # Skip free space checks with ZFS
18191         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18192                 local mdtfree2=$(do_facet $facet \
18193                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18194                 [ $mdtfree2 -gt $mdtfree1 ] ||
18195                         error "MDT space is not freed after migration"
18196         fi
18197         return 0
18198 }
18199 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18200
18201 test_272c() {
18202         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18203                 skip "Need MDS version at least 2.11.50"
18204
18205         local dom=$DIR/$tdir/$tfile
18206         mkdir -p $DIR/$tdir
18207         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18208
18209         local mdtidx=$($LFS getstripe -m $dom)
18210         local mdtname=MDT$(printf %04x $mdtidx)
18211         local facet=mds$((mdtidx + 1))
18212
18213         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18214                 error "failed to write data into $dom"
18215         local old_md5=$(md5sum $dom)
18216         cancel_lru_locks mdc
18217         local mdtfree1=$(do_facet $facet \
18218                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18219
18220         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18221                 error "failed to migrate to the new composite layout"
18222         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18223                 error "MDT stripe was not removed"
18224
18225         cancel_lru_locks mdc
18226         local new_md5=$(md5sum $dom)
18227         [ "$old_md5" != "$new_md5" ] &&
18228                 error "$old_md5 != $new_md5"
18229
18230         # Skip free space checks with ZFS
18231         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18232                 local mdtfree2=$(do_facet $facet \
18233                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18234                 [ $mdtfree2 -gt $mdtfree1 ] ||
18235                         error "MDS space is not freed after migration"
18236         fi
18237         return 0
18238 }
18239 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18240
18241 test_273a() {
18242         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18243                 skip "Need MDS version at least 2.11.50"
18244
18245         # Layout swap cannot be done if either file has DOM component,
18246         # this will never be supported, migration should be used instead
18247
18248         local dom=$DIR/$tdir/$tfile
18249         mkdir -p $DIR/$tdir
18250
18251         $LFS setstripe -c2 ${dom}_plain
18252         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18253         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18254                 error "can swap layout with DoM component"
18255         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18256                 error "can swap layout with DoM component"
18257
18258         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18259         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18260                 error "can swap layout with DoM component"
18261         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18262                 error "can swap layout with DoM component"
18263         return 0
18264 }
18265 run_test 273a "DoM: layout swapping should fail with DOM"
18266
18267 test_275() {
18268         remote_ost_nodsh && skip "remote OST with nodsh"
18269         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18270                 skip "Need OST version >= 2.10.57"
18271
18272         local file=$DIR/$tfile
18273         local oss
18274
18275         oss=$(comma_list $(osts_nodes))
18276
18277         dd if=/dev/urandom of=$file bs=1M count=2 ||
18278                 error "failed to create a file"
18279         cancel_lru_locks osc
18280
18281         #lock 1
18282         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18283                 error "failed to read a file"
18284
18285 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18286         $LCTL set_param fail_loc=0x8000031f
18287
18288         cancel_lru_locks osc &
18289         sleep 1
18290
18291 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18292         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18293         #IO takes another lock, but matches the PENDING one
18294         #and places it to the IO RPC
18295         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18296                 error "failed to read a file with PENDING lock"
18297 }
18298 run_test 275 "Read on a canceled duplicate lock"
18299
18300 test_276() {
18301         remote_ost_nodsh && skip "remote OST with nodsh"
18302         local pid
18303
18304         do_facet ost1 "(while true; do \
18305                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18306                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18307         pid=$!
18308
18309         for LOOP in $(seq 20); do
18310                 stop ost1
18311                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18312         done
18313         kill -9 $pid
18314         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18315                 rm $TMP/sanity_276_pid"
18316 }
18317 run_test 276 "Race between mount and obd_statfs"
18318
18319 cleanup_test_300() {
18320         trap 0
18321         umask $SAVE_UMASK
18322 }
18323 test_striped_dir() {
18324         local mdt_index=$1
18325         local stripe_count
18326         local stripe_index
18327
18328         mkdir -p $DIR/$tdir
18329
18330         SAVE_UMASK=$(umask)
18331         trap cleanup_test_300 RETURN EXIT
18332
18333         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18334                                                 $DIR/$tdir/striped_dir ||
18335                 error "set striped dir error"
18336
18337         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18338         [ "$mode" = "755" ] || error "expect 755 got $mode"
18339
18340         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18341                 error "getdirstripe failed"
18342         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18343         if [ "$stripe_count" != "2" ]; then
18344                 error "1:stripe_count is $stripe_count, expect 2"
18345         fi
18346         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18347         if [ "$stripe_count" != "2" ]; then
18348                 error "2:stripe_count is $stripe_count, expect 2"
18349         fi
18350
18351         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18352         if [ "$stripe_index" != "$mdt_index" ]; then
18353                 error "stripe_index is $stripe_index, expect $mdt_index"
18354         fi
18355
18356         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18357                 error "nlink error after create striped dir"
18358
18359         mkdir $DIR/$tdir/striped_dir/a
18360         mkdir $DIR/$tdir/striped_dir/b
18361
18362         stat $DIR/$tdir/striped_dir/a ||
18363                 error "create dir under striped dir failed"
18364         stat $DIR/$tdir/striped_dir/b ||
18365                 error "create dir under striped dir failed"
18366
18367         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18368                 error "nlink error after mkdir"
18369
18370         rmdir $DIR/$tdir/striped_dir/a
18371         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18372                 error "nlink error after rmdir"
18373
18374         rmdir $DIR/$tdir/striped_dir/b
18375         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18376                 error "nlink error after rmdir"
18377
18378         chattr +i $DIR/$tdir/striped_dir
18379         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18380                 error "immutable flags not working under striped dir!"
18381         chattr -i $DIR/$tdir/striped_dir
18382
18383         rmdir $DIR/$tdir/striped_dir ||
18384                 error "rmdir striped dir error"
18385
18386         cleanup_test_300
18387
18388         true
18389 }
18390
18391 test_300a() {
18392         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18393                 skip "skipped for lustre < 2.7.0"
18394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18395         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18396
18397         test_striped_dir 0 || error "failed on striped dir on MDT0"
18398         test_striped_dir 1 || error "failed on striped dir on MDT0"
18399 }
18400 run_test 300a "basic striped dir sanity test"
18401
18402 test_300b() {
18403         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18404                 skip "skipped for lustre < 2.7.0"
18405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18407
18408         local i
18409         local mtime1
18410         local mtime2
18411         local mtime3
18412
18413         test_mkdir $DIR/$tdir || error "mkdir fail"
18414         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18415                 error "set striped dir error"
18416         for i in {0..9}; do
18417                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18418                 sleep 1
18419                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18420                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18421                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18422                 sleep 1
18423                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18424                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18425                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18426         done
18427         true
18428 }
18429 run_test 300b "check ctime/mtime for striped dir"
18430
18431 test_300c() {
18432         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18433                 skip "skipped for lustre < 2.7.0"
18434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18436
18437         local file_count
18438
18439         mkdir -p $DIR/$tdir
18440         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18441                 error "set striped dir error"
18442
18443         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18444                 error "chown striped dir failed"
18445
18446         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18447                 error "create 5k files failed"
18448
18449         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18450
18451         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18452
18453         rm -rf $DIR/$tdir
18454 }
18455 run_test 300c "chown && check ls under striped directory"
18456
18457 test_300d() {
18458         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18459                 skip "skipped for lustre < 2.7.0"
18460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18461         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18462
18463         local stripe_count
18464         local file
18465
18466         mkdir -p $DIR/$tdir
18467         $LFS setstripe -c 2 $DIR/$tdir
18468
18469         #local striped directory
18470         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18471                 error "set striped dir error"
18472         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18473                 error "create 10 files failed"
18474
18475         #remote striped directory
18476         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18477                 error "set striped dir error"
18478         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18479                 error "create 10 files failed"
18480
18481         for file in $(find $DIR/$tdir); do
18482                 stripe_count=$($LFS getstripe -c $file)
18483                 [ $stripe_count -eq 2 ] ||
18484                         error "wrong stripe $stripe_count for $file"
18485         done
18486
18487         rm -rf $DIR/$tdir
18488 }
18489 run_test 300d "check default stripe under striped directory"
18490
18491 test_300e() {
18492         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18493                 skip "Need MDS version at least 2.7.55"
18494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18496
18497         local stripe_count
18498         local file
18499
18500         mkdir -p $DIR/$tdir
18501
18502         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18503                 error "set striped dir error"
18504
18505         touch $DIR/$tdir/striped_dir/a
18506         touch $DIR/$tdir/striped_dir/b
18507         touch $DIR/$tdir/striped_dir/c
18508
18509         mkdir $DIR/$tdir/striped_dir/dir_a
18510         mkdir $DIR/$tdir/striped_dir/dir_b
18511         mkdir $DIR/$tdir/striped_dir/dir_c
18512
18513         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18514                 error "set striped adir under striped dir error"
18515
18516         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18517                 error "set striped bdir under striped dir error"
18518
18519         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18520                 error "set striped cdir under striped dir error"
18521
18522         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18523                 error "rename dir under striped dir fails"
18524
18525         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18526                 error "rename dir under different stripes fails"
18527
18528         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18529                 error "rename file under striped dir should succeed"
18530
18531         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18532                 error "rename dir under striped dir should succeed"
18533
18534         rm -rf $DIR/$tdir
18535 }
18536 run_test 300e "check rename under striped directory"
18537
18538 test_300f() {
18539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18541         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18542                 skip "Need MDS version at least 2.7.55"
18543
18544         local stripe_count
18545         local file
18546
18547         rm -rf $DIR/$tdir
18548         mkdir -p $DIR/$tdir
18549
18550         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18551                 error "set striped dir error"
18552
18553         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18554                 error "set striped dir error"
18555
18556         touch $DIR/$tdir/striped_dir/a
18557         mkdir $DIR/$tdir/striped_dir/dir_a
18558         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18559                 error "create striped dir under striped dir fails"
18560
18561         touch $DIR/$tdir/striped_dir1/b
18562         mkdir $DIR/$tdir/striped_dir1/dir_b
18563         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18564                 error "create striped dir under striped dir fails"
18565
18566         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18567                 error "rename dir under different striped dir should fail"
18568
18569         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18570                 error "rename striped dir under diff striped dir should fail"
18571
18572         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18573                 error "rename file under diff striped dirs fails"
18574
18575         rm -rf $DIR/$tdir
18576 }
18577 run_test 300f "check rename cross striped directory"
18578
18579 test_300_check_default_striped_dir()
18580 {
18581         local dirname=$1
18582         local default_count=$2
18583         local default_index=$3
18584         local stripe_count
18585         local stripe_index
18586         local dir_stripe_index
18587         local dir
18588
18589         echo "checking $dirname $default_count $default_index"
18590         $LFS setdirstripe -D -c $default_count -i $default_index \
18591                                 -t all_char $DIR/$tdir/$dirname ||
18592                 error "set default stripe on striped dir error"
18593         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18594         [ $stripe_count -eq $default_count ] ||
18595                 error "expect $default_count get $stripe_count for $dirname"
18596
18597         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18598         [ $stripe_index -eq $default_index ] ||
18599                 error "expect $default_index get $stripe_index for $dirname"
18600
18601         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18602                                                 error "create dirs failed"
18603
18604         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18605         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18606         for dir in $(find $DIR/$tdir/$dirname/*); do
18607                 stripe_count=$($LFS getdirstripe -c $dir)
18608                 [ $stripe_count -eq $default_count ] ||
18609                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18610                 error "stripe count $default_count != $stripe_count for $dir"
18611
18612                 stripe_index=$($LFS getdirstripe -i $dir)
18613                 [ $default_index -eq -1 ] ||
18614                         [ $stripe_index -eq $default_index ] ||
18615                         error "$stripe_index != $default_index for $dir"
18616
18617                 #check default stripe
18618                 stripe_count=$($LFS getdirstripe -D -c $dir)
18619                 [ $stripe_count -eq $default_count ] ||
18620                 error "default count $default_count != $stripe_count for $dir"
18621
18622                 stripe_index=$($LFS getdirstripe -D -i $dir)
18623                 [ $stripe_index -eq $default_index ] ||
18624                 error "default index $default_index != $stripe_index for $dir"
18625         done
18626         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18627 }
18628
18629 test_300g() {
18630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18631         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18632                 skip "Need MDS version at least 2.7.55"
18633
18634         local dir
18635         local stripe_count
18636         local stripe_index
18637
18638         mkdir $DIR/$tdir
18639         mkdir $DIR/$tdir/normal_dir
18640
18641         #Checking when client cache stripe index
18642         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18643         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18644                 error "create striped_dir failed"
18645
18646         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18647                 error "create dir0 fails"
18648         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18649         [ $stripe_index -eq 0 ] ||
18650                 error "dir0 expect index 0 got $stripe_index"
18651
18652         mkdir $DIR/$tdir/striped_dir/dir1 ||
18653                 error "create dir1 fails"
18654         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18655         [ $stripe_index -eq 1 ] ||
18656                 error "dir1 expect index 1 got $stripe_index"
18657
18658         #check default stripe count/stripe index
18659         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18660         test_300_check_default_striped_dir normal_dir 1 0
18661         test_300_check_default_striped_dir normal_dir 2 1
18662         test_300_check_default_striped_dir normal_dir 2 -1
18663
18664         #delete default stripe information
18665         echo "delete default stripeEA"
18666         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18667                 error "set default stripe on striped dir error"
18668
18669         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18670         for dir in $(find $DIR/$tdir/normal_dir/*); do
18671                 stripe_count=$($LFS getdirstripe -c $dir)
18672                 [ $stripe_count -eq 0 ] ||
18673                         error "expect 1 get $stripe_count for $dir"
18674                 stripe_index=$($LFS getdirstripe -i $dir)
18675                 [ $stripe_index -eq 0 ] ||
18676                         error "expect 0 get $stripe_index for $dir"
18677         done
18678 }
18679 run_test 300g "check default striped directory for normal directory"
18680
18681 test_300h() {
18682         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18683         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18684                 skip "Need MDS version at least 2.7.55"
18685
18686         local dir
18687         local stripe_count
18688
18689         mkdir $DIR/$tdir
18690         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18691                 error "set striped dir error"
18692
18693         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18694         test_300_check_default_striped_dir striped_dir 1 0
18695         test_300_check_default_striped_dir striped_dir 2 1
18696         test_300_check_default_striped_dir striped_dir 2 -1
18697
18698         #delete default stripe information
18699         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18700                 error "set default stripe on striped dir error"
18701
18702         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18703         for dir in $(find $DIR/$tdir/striped_dir/*); do
18704                 stripe_count=$($LFS getdirstripe -c $dir)
18705                 [ $stripe_count -eq 0 ] ||
18706                         error "expect 1 get $stripe_count for $dir"
18707         done
18708 }
18709 run_test 300h "check default striped directory for striped directory"
18710
18711 test_300i() {
18712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18714         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18715                 skip "Need MDS version at least 2.7.55"
18716
18717         local stripe_count
18718         local file
18719
18720         mkdir $DIR/$tdir
18721
18722         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18723                 error "set striped dir error"
18724
18725         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18726                 error "create files under striped dir failed"
18727
18728         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18729                 error "set striped hashdir error"
18730
18731         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18732                 error "create dir0 under hash dir failed"
18733         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18734                 error "create dir1 under hash dir failed"
18735
18736         # unfortunately, we need to umount to clear dir layout cache for now
18737         # once we fully implement dir layout, we can drop this
18738         umount_client $MOUNT || error "umount failed"
18739         mount_client $MOUNT || error "mount failed"
18740
18741         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18742         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18743         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18744
18745         #set the stripe to be unknown hash type
18746         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18747         $LCTL set_param fail_loc=0x1901
18748         for ((i = 0; i < 10; i++)); do
18749                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18750                         error "stat f-$i failed"
18751                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18752         done
18753
18754         touch $DIR/$tdir/striped_dir/f0 &&
18755                 error "create under striped dir with unknown hash should fail"
18756
18757         $LCTL set_param fail_loc=0
18758
18759         umount_client $MOUNT || error "umount failed"
18760         mount_client $MOUNT || error "mount failed"
18761
18762         return 0
18763 }
18764 run_test 300i "client handle unknown hash type striped directory"
18765
18766 test_300j() {
18767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18769         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18770                 skip "Need MDS version at least 2.7.55"
18771
18772         local stripe_count
18773         local file
18774
18775         mkdir $DIR/$tdir
18776
18777         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18778         $LCTL set_param fail_loc=0x1702
18779         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18780                 error "set striped dir error"
18781
18782         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18783                 error "create files under striped dir failed"
18784
18785         $LCTL set_param fail_loc=0
18786
18787         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18788
18789         return 0
18790 }
18791 run_test 300j "test large update record"
18792
18793 test_300k() {
18794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18796         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18797                 skip "Need MDS version at least 2.7.55"
18798
18799         # this test needs a huge transaction
18800         local kb
18801         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18802         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18803
18804         local stripe_count
18805         local file
18806
18807         mkdir $DIR/$tdir
18808
18809         #define OBD_FAIL_LARGE_STRIPE   0x1703
18810         $LCTL set_param fail_loc=0x1703
18811         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18812                 error "set striped dir error"
18813         $LCTL set_param fail_loc=0
18814
18815         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18816                 error "getstripeddir fails"
18817         rm -rf $DIR/$tdir/striped_dir ||
18818                 error "unlink striped dir fails"
18819
18820         return 0
18821 }
18822 run_test 300k "test large striped directory"
18823
18824 test_300l() {
18825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18826         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18827         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18828                 skip "Need MDS version at least 2.7.55"
18829
18830         local stripe_index
18831
18832         test_mkdir -p $DIR/$tdir/striped_dir
18833         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18834                         error "chown $RUNAS_ID failed"
18835         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18836                 error "set default striped dir failed"
18837
18838         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18839         $LCTL set_param fail_loc=0x80000158
18840         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18841
18842         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18843         [ $stripe_index -eq 1 ] ||
18844                 error "expect 1 get $stripe_index for $dir"
18845 }
18846 run_test 300l "non-root user to create dir under striped dir with stale layout"
18847
18848 test_300m() {
18849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18850         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18851         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18852                 skip "Need MDS version at least 2.7.55"
18853
18854         mkdir -p $DIR/$tdir/striped_dir
18855         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18856                 error "set default stripes dir error"
18857
18858         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18859
18860         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18861         [ $stripe_count -eq 0 ] ||
18862                         error "expect 0 get $stripe_count for a"
18863
18864         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18865                 error "set default stripes dir error"
18866
18867         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18868
18869         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18870         [ $stripe_count -eq 0 ] ||
18871                         error "expect 0 get $stripe_count for b"
18872
18873         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18874                 error "set default stripes dir error"
18875
18876         mkdir $DIR/$tdir/striped_dir/c &&
18877                 error "default stripe_index is invalid, mkdir c should fails"
18878
18879         rm -rf $DIR/$tdir || error "rmdir fails"
18880 }
18881 run_test 300m "setstriped directory on single MDT FS"
18882
18883 cleanup_300n() {
18884         local list=$(comma_list $(mdts_nodes))
18885
18886         trap 0
18887         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18888 }
18889
18890 test_300n() {
18891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18893         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18894                 skip "Need MDS version at least 2.7.55"
18895         remote_mds_nodsh && skip "remote MDS with nodsh"
18896
18897         local stripe_index
18898         local list=$(comma_list $(mdts_nodes))
18899
18900         trap cleanup_300n RETURN EXIT
18901         mkdir -p $DIR/$tdir
18902         chmod 777 $DIR/$tdir
18903         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18904                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18905                 error "create striped dir succeeds with gid=0"
18906
18907         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18908         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18909                 error "create striped dir fails with gid=-1"
18910
18911         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18912         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18913                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18914                 error "set default striped dir succeeds with gid=0"
18915
18916
18917         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18918         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18919                 error "set default striped dir fails with gid=-1"
18920
18921
18922         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18923         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18924                                         error "create test_dir fails"
18925         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18926                                         error "create test_dir1 fails"
18927         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18928                                         error "create test_dir2 fails"
18929         cleanup_300n
18930 }
18931 run_test 300n "non-root user to create dir under striped dir with default EA"
18932
18933 test_300o() {
18934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18936         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18937                 skip "Need MDS version at least 2.7.55"
18938
18939         local numfree1
18940         local numfree2
18941
18942         mkdir -p $DIR/$tdir
18943
18944         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18945         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18946         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18947                 skip "not enough free inodes $numfree1 $numfree2"
18948         fi
18949
18950         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18951         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18952         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18953                 skip "not enough free space $numfree1 $numfree2"
18954         fi
18955
18956         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18957                 error "setdirstripe fails"
18958
18959         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18960                 error "create dirs fails"
18961
18962         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18963         ls $DIR/$tdir/striped_dir > /dev/null ||
18964                 error "ls striped dir fails"
18965         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18966                 error "unlink big striped dir fails"
18967 }
18968 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18969
18970 test_300p() {
18971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18973         remote_mds_nodsh && skip "remote MDS with nodsh"
18974
18975         mkdir -p $DIR/$tdir
18976
18977         #define OBD_FAIL_OUT_ENOSPC     0x1704
18978         do_facet mds2 lctl set_param fail_loc=0x80001704
18979         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18980                  && error "create striped directory should fail"
18981
18982         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18983
18984         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18985         true
18986 }
18987 run_test 300p "create striped directory without space"
18988
18989 test_300q() {
18990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18991         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18992
18993         local fd=$(free_fd)
18994         local cmd="exec $fd<$tdir"
18995         cd $DIR
18996         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18997         eval $cmd
18998         cmd="exec $fd<&-"
18999         trap "eval $cmd" EXIT
19000         cd $tdir || error "cd $tdir fails"
19001         rmdir  ../$tdir || error "rmdir $tdir fails"
19002         mkdir local_dir && error "create dir succeeds"
19003         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19004         eval $cmd
19005         return 0
19006 }
19007 run_test 300q "create remote directory under orphan directory"
19008
19009 test_300r() {
19010         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19011                 skip "Need MDS version at least 2.7.55" && return
19012         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19013
19014         mkdir $DIR/$tdir
19015
19016         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19017                 error "set striped dir error"
19018
19019         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19020                 error "getstripeddir fails"
19021
19022         local stripe_count
19023         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19024                       awk '/lmv_stripe_count:/ { print $2 }')
19025
19026         [ $MDSCOUNT -ne $stripe_count ] &&
19027                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19028
19029         rm -rf $DIR/$tdir/striped_dir ||
19030                 error "unlink striped dir fails"
19031 }
19032 run_test 300r "test -1 striped directory"
19033
19034 prepare_remote_file() {
19035         mkdir $DIR/$tdir/src_dir ||
19036                 error "create remote source failed"
19037
19038         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19039                  error "cp to remote source failed"
19040         touch $DIR/$tdir/src_dir/a
19041
19042         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19043                 error "create remote target dir failed"
19044
19045         touch $DIR/$tdir/tgt_dir/b
19046
19047         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19048                 error "rename dir cross MDT failed!"
19049
19050         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19051                 error "src_child still exists after rename"
19052
19053         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19054                 error "missing file(a) after rename"
19055
19056         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19057                 error "diff after rename"
19058 }
19059
19060 test_310a() {
19061         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19063
19064         local remote_file=$DIR/$tdir/tgt_dir/b
19065
19066         mkdir -p $DIR/$tdir
19067
19068         prepare_remote_file || error "prepare remote file failed"
19069
19070         #open-unlink file
19071         $OPENUNLINK $remote_file $remote_file ||
19072                 error "openunlink $remote_file failed"
19073         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19074 }
19075 run_test 310a "open unlink remote file"
19076
19077 test_310b() {
19078         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19080
19081         local remote_file=$DIR/$tdir/tgt_dir/b
19082
19083         mkdir -p $DIR/$tdir
19084
19085         prepare_remote_file || error "prepare remote file failed"
19086
19087         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19088         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19089         $CHECKSTAT -t file $remote_file || error "check file failed"
19090 }
19091 run_test 310b "unlink remote file with multiple links while open"
19092
19093 test_310c() {
19094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19095         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19096
19097         local remote_file=$DIR/$tdir/tgt_dir/b
19098
19099         mkdir -p $DIR/$tdir
19100
19101         prepare_remote_file || error "prepare remote file failed"
19102
19103         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19104         multiop_bg_pause $remote_file O_uc ||
19105                         error "mulitop failed for remote file"
19106         MULTIPID=$!
19107         $MULTIOP $DIR/$tfile Ouc
19108         kill -USR1 $MULTIPID
19109         wait $MULTIPID
19110 }
19111 run_test 310c "open-unlink remote file with multiple links"
19112
19113 #LU-4825
19114 test_311() {
19115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19116         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19117         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19118                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19119         remote_mds_nodsh && skip "remote MDS with nodsh"
19120
19121         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19122         local mdts=$(comma_list $(mdts_nodes))
19123
19124         mkdir -p $DIR/$tdir
19125         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19126         createmany -o $DIR/$tdir/$tfile. 1000
19127
19128         # statfs data is not real time, let's just calculate it
19129         old_iused=$((old_iused + 1000))
19130
19131         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19132                         osp.*OST0000*MDT0000.create_count")
19133         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19134                                 osp.*OST0000*MDT0000.max_create_count")
19135         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19136
19137         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19138         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19139         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19140
19141         unlinkmany $DIR/$tdir/$tfile. 1000
19142
19143         do_nodes $mdts "$LCTL set_param -n \
19144                         osp.*OST0000*.max_create_count=$max_count"
19145         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19146                 do_nodes $mdts "$LCTL set_param -n \
19147                                 osp.*OST0000*.create_count=$count"
19148         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19149                         grep "=0" && error "create_count is zero"
19150
19151         local new_iused
19152         for i in $(seq 120); do
19153                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19154                 # system may be too busy to destroy all objs in time, use
19155                 # a somewhat small value to not fail autotest
19156                 [ $((old_iused - new_iused)) -gt 400 ] && break
19157                 sleep 1
19158         done
19159
19160         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19161         [ $((old_iused - new_iused)) -gt 400 ] ||
19162                 error "objs not destroyed after unlink"
19163 }
19164 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19165
19166 zfs_oid_to_objid()
19167 {
19168         local ost=$1
19169         local objid=$2
19170
19171         local vdevdir=$(dirname $(facet_vdevice $ost))
19172         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19173         local zfs_zapid=$(do_facet $ost $cmd |
19174                           grep -w "/O/0/d$((objid%32))" -C 5 |
19175                           awk '/Object/{getline; print $1}')
19176         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19177                           awk "/$objid = /"'{printf $3}')
19178
19179         echo $zfs_objid
19180 }
19181
19182 zfs_object_blksz() {
19183         local ost=$1
19184         local objid=$2
19185
19186         local vdevdir=$(dirname $(facet_vdevice $ost))
19187         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19188         local blksz=$(do_facet $ost $cmd $objid |
19189                       awk '/dblk/{getline; printf $4}')
19190
19191         case "${blksz: -1}" in
19192                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19193                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19194                 *) ;;
19195         esac
19196
19197         echo $blksz
19198 }
19199
19200 test_312() { # LU-4856
19201         remote_ost_nodsh && skip "remote OST with nodsh"
19202         [ "$ost1_FSTYPE" = "zfs" ] ||
19203                 skip_env "the test only applies to zfs"
19204
19205         local max_blksz=$(do_facet ost1 \
19206                           $ZFS get -p recordsize $(facet_device ost1) |
19207                           awk '!/VALUE/{print $3}')
19208
19209         # to make life a little bit easier
19210         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19211         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19212
19213         local tf=$DIR/$tdir/$tfile
19214         touch $tf
19215         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19216
19217         # Get ZFS object id
19218         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19219         # block size change by sequential overwrite
19220         local bs
19221
19222         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19223                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19224
19225                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19226                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19227         done
19228         rm -f $tf
19229
19230         # block size change by sequential append write
19231         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19232         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19233         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19234         local count
19235
19236         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19237                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19238                         oflag=sync conv=notrunc
19239
19240                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19241                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19242                         error "blksz error, actual $blksz, " \
19243                                 "expected: 2 * $count * $PAGE_SIZE"
19244         done
19245         rm -f $tf
19246
19247         # random write
19248         touch $tf
19249         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19250         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19251
19252         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19253         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19254         [ $blksz -eq $PAGE_SIZE ] ||
19255                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19256
19257         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19258         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19259         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19260
19261         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19262         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19263         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19264 }
19265 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19266
19267 test_313() {
19268         remote_ost_nodsh && skip "remote OST with nodsh"
19269
19270         local file=$DIR/$tfile
19271
19272         rm -f $file
19273         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19274
19275         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19276         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19277         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19278                 error "write should failed"
19279         do_facet ost1 "$LCTL set_param fail_loc=0"
19280         rm -f $file
19281 }
19282 run_test 313 "io should fail after last_rcvd update fail"
19283
19284 test_314() {
19285         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19286
19287         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19288         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19289         rm -f $DIR/$tfile
19290         wait_delete_completed
19291         do_facet ost1 "$LCTL set_param fail_loc=0"
19292 }
19293 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19294
19295 test_315() { # LU-618
19296         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19297
19298         local file=$DIR/$tfile
19299         rm -f $file
19300
19301         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19302                 error "multiop file write failed"
19303         $MULTIOP $file oO_RDONLY:r4063232_c &
19304         PID=$!
19305
19306         sleep 2
19307
19308         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19309         kill -USR1 $PID
19310
19311         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19312         rm -f $file
19313 }
19314 run_test 315 "read should be accounted"
19315
19316 test_316() {
19317         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19318         large_xattr_enabled || skip_env "ea_inode feature disabled"
19319
19320         rm -rf $DIR/$tdir/d
19321         mkdir -p $DIR/$tdir/d
19322         chown nobody $DIR/$tdir/d
19323         touch $DIR/$tdir/d/file
19324
19325         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19326 }
19327 run_test 316 "lfs mv"
19328
19329 test_317() {
19330         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19331                 skip "Need MDS version at least 2.11.53"
19332         local trunc_sz
19333         local grant_blk_size
19334
19335         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19336                 skip "LU-10370: no implementation for ZFS" && return
19337         fi
19338
19339         stack_trap "rm -f $DIR/$tfile" EXIT
19340         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19341                         awk '/grant_block_size:/ { print $2; exit; }')
19342         #
19343         # Create File of size 5M. Truncate it to below size's and verify
19344         # blocks count.
19345         #
19346         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19347                 error "Create file : $DIR/$tfile"
19348
19349         for trunc_sz in 2097152 4097 4000 509 0; do
19350                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19351                         error "truncate $tfile to $trunc_sz failed"
19352                 local sz=$(stat --format=%s $DIR/$tfile)
19353                 local blk=$(stat --format=%b $DIR/$tfile)
19354                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19355                                      grant_blk_size) * 8))
19356
19357                 if [[ $blk -ne $trunc_blk ]]; then
19358                         $(which stat) $DIR/$tfile
19359                         error "Expected Block $trunc_blk got $blk for $tfile"
19360                 fi
19361
19362                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19363                         error "Expected Size $trunc_sz got $sz for $tfile"
19364         done
19365
19366         #
19367         # sparse file test
19368         # Create file with a hole and write actual two blocks. Block count
19369         # must be 16.
19370         #
19371         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19372                 conv=fsync || error "Create file : $DIR/$tfile"
19373
19374         # Calculate the final truncate size.
19375         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19376
19377         #
19378         # truncate to size $trunc_sz bytes. Strip the last block
19379         # The block count must drop to 8
19380         #
19381         $TRUNCATE $DIR/$tfile $trunc_sz ||
19382                 error "truncate $tfile to $trunc_sz failed"
19383
19384         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19385         sz=$(stat --format=%s $DIR/$tfile)
19386         blk=$(stat --format=%b $DIR/$tfile)
19387
19388         if [[ $blk -ne $trunc_bsz ]]; then
19389                 $(which stat) $DIR/$tfile
19390                 error "Expected Block $trunc_bsz got $blk for $tfile"
19391         fi
19392
19393         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19394                 error "Expected Size $trunc_sz got $sz for $tfile"
19395 }
19396 run_test 317 "Verify blocks get correctly update after truncate"
19397
19398 test_319() {
19399         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19400
19401         local before=$(date +%s)
19402         local evict
19403         local mdir=$DIR/$tdir
19404         local file=$mdir/xxx
19405
19406         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19407         touch $file
19408
19409 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19410         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19411         $LFS mv -m1 $file &
19412
19413         sleep 1
19414         dd if=$file of=/dev/null
19415         wait
19416         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19417           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19418
19419         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19420 }
19421 run_test 319 "lost lease lock on migrate error"
19422
19423 test_fake_rw() {
19424         local read_write=$1
19425         if [ "$read_write" = "write" ]; then
19426                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19427         elif [ "$read_write" = "read" ]; then
19428                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19429         else
19430                 error "argument error"
19431         fi
19432
19433         # turn off debug for performance testing
19434         local saved_debug=$($LCTL get_param -n debug)
19435         $LCTL set_param debug=0
19436
19437         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19438
19439         # get ost1 size - lustre-OST0000
19440         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19441         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19442         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19443
19444         if [ "$read_write" = "read" ]; then
19445                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19446         fi
19447
19448         local start_time=$(date +%s.%N)
19449         $dd_cmd bs=1M count=$blocks oflag=sync ||
19450                 error "real dd $read_write error"
19451         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19452
19453         if [ "$read_write" = "write" ]; then
19454                 rm -f $DIR/$tfile
19455         fi
19456
19457         # define OBD_FAIL_OST_FAKE_RW           0x238
19458         do_facet ost1 $LCTL set_param fail_loc=0x238
19459
19460         local start_time=$(date +%s.%N)
19461         $dd_cmd bs=1M count=$blocks oflag=sync ||
19462                 error "fake dd $read_write error"
19463         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19464
19465         if [ "$read_write" = "write" ]; then
19466                 # verify file size
19467                 cancel_lru_locks osc
19468                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19469                         error "$tfile size not $blocks MB"
19470         fi
19471         do_facet ost1 $LCTL set_param fail_loc=0
19472
19473         echo "fake $read_write $duration_fake vs. normal $read_write" \
19474                 "$duration in seconds"
19475         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19476                 error_not_in_vm "fake write is slower"
19477
19478         $LCTL set_param -n debug="$saved_debug"
19479         rm -f $DIR/$tfile
19480 }
19481 test_399a() { # LU-7655 for OST fake write
19482         remote_ost_nodsh && skip "remote OST with nodsh"
19483
19484         test_fake_rw write
19485 }
19486 run_test 399a "fake write should not be slower than normal write"
19487
19488 test_399b() { # LU-8726 for OST fake read
19489         remote_ost_nodsh && skip "remote OST with nodsh"
19490         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19491                 skip_env "ldiskfs only test"
19492         fi
19493
19494         test_fake_rw read
19495 }
19496 run_test 399b "fake read should not be slower than normal read"
19497
19498 test_400a() { # LU-1606, was conf-sanity test_74
19499         if ! which $CC > /dev/null 2>&1; then
19500                 skip_env "$CC is not installed"
19501         fi
19502
19503         local extra_flags=''
19504         local out=$TMP/$tfile
19505         local prefix=/usr/include/lustre
19506         local prog
19507
19508         if ! [[ -d $prefix ]]; then
19509                 # Assume we're running in tree and fixup the include path.
19510                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19511                 extra_flags+=" -L$LUSTRE/utils/.lib"
19512         fi
19513
19514         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19515                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19516                         error "client api broken"
19517         done
19518         rm -f $out
19519 }
19520 run_test 400a "Lustre client api program can compile and link"
19521
19522 test_400b() { # LU-1606, LU-5011
19523         local header
19524         local out=$TMP/$tfile
19525         local prefix=/usr/include/linux/lustre
19526
19527         # We use a hard coded prefix so that this test will not fail
19528         # when run in tree. There are headers in lustre/include/lustre/
19529         # that are not packaged (like lustre_idl.h) and have more
19530         # complicated include dependencies (like config.h and lnet/types.h).
19531         # Since this test about correct packaging we just skip them when
19532         # they don't exist (see below) rather than try to fixup cppflags.
19533
19534         if ! which $CC > /dev/null 2>&1; then
19535                 skip_env "$CC is not installed"
19536         fi
19537
19538         for header in $prefix/*.h; do
19539                 if ! [[ -f "$header" ]]; then
19540                         continue
19541                 fi
19542
19543                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19544                         continue # lustre_ioctl.h is internal header
19545                 fi
19546
19547                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19548                         error "cannot compile '$header'"
19549         done
19550         rm -f $out
19551 }
19552 run_test 400b "packaged headers can be compiled"
19553
19554 test_401a() { #LU-7437
19555         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19556         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19557
19558         #count the number of parameters by "list_param -R"
19559         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19560         #count the number of parameters by listing proc files
19561         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19562         echo "proc_dirs='$proc_dirs'"
19563         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19564         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19565                       sort -u | wc -l)
19566
19567         [ $params -eq $procs ] ||
19568                 error "found $params parameters vs. $procs proc files"
19569
19570         # test the list_param -D option only returns directories
19571         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19572         #count the number of parameters by listing proc directories
19573         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19574                 sort -u | wc -l)
19575
19576         [ $params -eq $procs ] ||
19577                 error "found $params parameters vs. $procs proc files"
19578 }
19579 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19580
19581 test_401b() {
19582         local save=$($LCTL get_param -n jobid_var)
19583         local tmp=testing
19584
19585         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19586                 error "no error returned when setting bad parameters"
19587
19588         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19589         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19590
19591         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19592         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19593         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19594 }
19595 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19596
19597 test_401c() {
19598         local jobid_var_old=$($LCTL get_param -n jobid_var)
19599         local jobid_var_new
19600
19601         $LCTL set_param jobid_var= &&
19602                 error "no error returned for 'set_param a='"
19603
19604         jobid_var_new=$($LCTL get_param -n jobid_var)
19605         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19606                 error "jobid_var was changed by setting without value"
19607
19608         $LCTL set_param jobid_var &&
19609                 error "no error returned for 'set_param a'"
19610
19611         jobid_var_new=$($LCTL get_param -n jobid_var)
19612         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19613                 error "jobid_var was changed by setting without value"
19614 }
19615 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19616
19617 test_401d() {
19618         local jobid_var_old=$($LCTL get_param -n jobid_var)
19619         local jobid_var_new
19620         local new_value="foo=bar"
19621
19622         $LCTL set_param jobid_var=$new_value ||
19623                 error "'set_param a=b' did not accept a value containing '='"
19624
19625         jobid_var_new=$($LCTL get_param -n jobid_var)
19626         [[ "$jobid_var_new" == "$new_value" ]] ||
19627                 error "'set_param a=b' failed on a value containing '='"
19628
19629         # Reset the jobid_var to test the other format
19630         $LCTL set_param jobid_var=$jobid_var_old
19631         jobid_var_new=$($LCTL get_param -n jobid_var)
19632         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19633                 error "failed to reset jobid_var"
19634
19635         $LCTL set_param jobid_var $new_value ||
19636                 error "'set_param a b' did not accept a value containing '='"
19637
19638         jobid_var_new=$($LCTL get_param -n jobid_var)
19639         [[ "$jobid_var_new" == "$new_value" ]] ||
19640                 error "'set_param a b' failed on a value containing '='"
19641
19642         $LCTL set_param jobid_var $jobid_var_old
19643         jobid_var_new=$($LCTL get_param -n jobid_var)
19644         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19645                 error "failed to reset jobid_var"
19646 }
19647 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19648
19649 test_402() {
19650         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19651         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19652                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19653         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19654                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19655                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19656         remote_mds_nodsh && skip "remote MDS with nodsh"
19657
19658         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19659 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19660         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19661         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19662                 echo "Touch failed - OK"
19663 }
19664 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19665
19666 test_403() {
19667         local file1=$DIR/$tfile.1
19668         local file2=$DIR/$tfile.2
19669         local tfile=$TMP/$tfile
19670
19671         rm -f $file1 $file2 $tfile
19672
19673         touch $file1
19674         ln $file1 $file2
19675
19676         # 30 sec OBD_TIMEOUT in ll_getattr()
19677         # right before populating st_nlink
19678         $LCTL set_param fail_loc=0x80001409
19679         stat -c %h $file1 > $tfile &
19680
19681         # create an alias, drop all locks and reclaim the dentry
19682         < $file2
19683         cancel_lru_locks mdc
19684         cancel_lru_locks osc
19685         sysctl -w vm.drop_caches=2
19686
19687         wait
19688
19689         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19690
19691         rm -f $tfile $file1 $file2
19692 }
19693 run_test 403 "i_nlink should not drop to zero due to aliasing"
19694
19695 test_404() { # LU-6601
19696         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19697                 skip "Need server version newer than 2.8.52"
19698         remote_mds_nodsh && skip "remote MDS with nodsh"
19699
19700         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19701                 awk '/osp .*-osc-MDT/ { print $4}')
19702
19703         local osp
19704         for osp in $mosps; do
19705                 echo "Deactivate: " $osp
19706                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19707                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19708                         awk -vp=$osp '$4 == p { print $2 }')
19709                 [ $stat = IN ] || {
19710                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19711                         error "deactivate error"
19712                 }
19713                 echo "Activate: " $osp
19714                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19715                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19716                         awk -vp=$osp '$4 == p { print $2 }')
19717                 [ $stat = UP ] || {
19718                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19719                         error "activate error"
19720                 }
19721         done
19722 }
19723 run_test 404 "validate manual {de}activated works properly for OSPs"
19724
19725 test_405() {
19726         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19727         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19728                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19729                         skip "Layout swap lock is not supported"
19730
19731         check_swap_layouts_support
19732
19733         test_mkdir $DIR/$tdir
19734         swap_lock_test -d $DIR/$tdir ||
19735                 error "One layout swap locked test failed"
19736 }
19737 run_test 405 "Various layout swap lock tests"
19738
19739 test_406() {
19740         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19741         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19742         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19744         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19745                 skip "Need MDS version at least 2.8.50"
19746
19747         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19748         local test_pool=$TESTNAME
19749
19750         if ! combined_mgs_mds ; then
19751                 mount_mgs_client
19752         fi
19753         pool_add $test_pool || error "pool_add failed"
19754         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19755                 error "pool_add_targets failed"
19756
19757         save_layout_restore_at_exit $MOUNT
19758
19759         # parent set default stripe count only, child will stripe from both
19760         # parent and fs default
19761         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19762                 error "setstripe $MOUNT failed"
19763         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19764         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19765         for i in $(seq 10); do
19766                 local f=$DIR/$tdir/$tfile.$i
19767                 touch $f || error "touch failed"
19768                 local count=$($LFS getstripe -c $f)
19769                 [ $count -eq $OSTCOUNT ] ||
19770                         error "$f stripe count $count != $OSTCOUNT"
19771                 local offset=$($LFS getstripe -i $f)
19772                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19773                 local size=$($LFS getstripe -S $f)
19774                 [ $size -eq $((def_stripe_size * 2)) ] ||
19775                         error "$f stripe size $size != $((def_stripe_size * 2))"
19776                 local pool=$($LFS getstripe -p $f)
19777                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19778         done
19779
19780         # change fs default striping, delete parent default striping, now child
19781         # will stripe from new fs default striping only
19782         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19783                 error "change $MOUNT default stripe failed"
19784         $LFS setstripe -c 0 $DIR/$tdir ||
19785                 error "delete $tdir default stripe failed"
19786         for i in $(seq 11 20); do
19787                 local f=$DIR/$tdir/$tfile.$i
19788                 touch $f || error "touch $f failed"
19789                 local count=$($LFS getstripe -c $f)
19790                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19791                 local offset=$($LFS getstripe -i $f)
19792                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19793                 local size=$($LFS getstripe -S $f)
19794                 [ $size -eq $def_stripe_size ] ||
19795                         error "$f stripe size $size != $def_stripe_size"
19796                 local pool=$($LFS getstripe -p $f)
19797                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19798         done
19799
19800         unlinkmany $DIR/$tdir/$tfile. 1 20
19801
19802         local f=$DIR/$tdir/$tfile
19803         pool_remove_all_targets $test_pool $f
19804         pool_remove $test_pool $f
19805
19806         if ! combined_mgs_mds ; then
19807                 umount_mgs_client
19808         fi
19809 }
19810 run_test 406 "DNE support fs default striping"
19811
19812 test_407() {
19813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19814         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19815                 skip "Need MDS version at least 2.8.55"
19816         remote_mds_nodsh && skip "remote MDS with nodsh"
19817
19818         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19819                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19820         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19821                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19822         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19823
19824         #define OBD_FAIL_DT_TXN_STOP    0x2019
19825         for idx in $(seq $MDSCOUNT); do
19826                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19827         done
19828         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19829         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19830                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19831         true
19832 }
19833 run_test 407 "transaction fail should cause operation fail"
19834
19835 test_408() {
19836         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19837
19838         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19839         lctl set_param fail_loc=0x8000040a
19840         # let ll_prepare_partial_page() fail
19841         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19842
19843         rm -f $DIR/$tfile
19844
19845         # create at least 100 unused inodes so that
19846         # shrink_icache_memory(0) should not return 0
19847         touch $DIR/$tfile-{0..100}
19848         rm -f $DIR/$tfile-{0..100}
19849         sync
19850
19851         echo 2 > /proc/sys/vm/drop_caches
19852 }
19853 run_test 408 "drop_caches should not hang due to page leaks"
19854
19855 test_409()
19856 {
19857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19858
19859         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19860         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19861         touch $DIR/$tdir/guard || error "(2) Fail to create"
19862
19863         local PREFIX=$(str_repeat 'A' 128)
19864         echo "Create 1K hard links start at $(date)"
19865         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19866                 error "(3) Fail to hard link"
19867
19868         echo "Links count should be right although linkEA overflow"
19869         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19870         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19871         [ $linkcount -eq 1001 ] ||
19872                 error "(5) Unexpected hard links count: $linkcount"
19873
19874         echo "List all links start at $(date)"
19875         ls -l $DIR/$tdir/foo > /dev/null ||
19876                 error "(6) Fail to list $DIR/$tdir/foo"
19877
19878         echo "Unlink hard links start at $(date)"
19879         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19880                 error "(7) Fail to unlink"
19881         echo "Unlink hard links finished at $(date)"
19882 }
19883 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19884
19885 test_410()
19886 {
19887         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19888                 skip "Need client version at least 2.9.59"
19889
19890         # Create a file, and stat it from the kernel
19891         local testfile=$DIR/$tfile
19892         touch $testfile
19893
19894         local run_id=$RANDOM
19895         local my_ino=$(stat --format "%i" $testfile)
19896
19897         # Try to insert the module. This will always fail as the
19898         # module is designed to not be inserted.
19899         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19900             &> /dev/null
19901
19902         # Anything but success is a test failure
19903         dmesg | grep -q \
19904             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19905             error "no inode match"
19906 }
19907 run_test 410 "Test inode number returned from kernel thread"
19908
19909 cleanup_test411_cgroup() {
19910         trap 0
19911         rmdir "$1"
19912 }
19913
19914 test_411() {
19915         local cg_basedir=/sys/fs/cgroup/memory
19916         # LU-9966
19917         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19918                 skip "no setup for cgroup"
19919
19920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19921                 error "test file creation failed"
19922         cancel_lru_locks osc
19923
19924         # Create a very small memory cgroup to force a slab allocation error
19925         local cgdir=$cg_basedir/osc_slab_alloc
19926         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19927         trap "cleanup_test411_cgroup $cgdir" EXIT
19928         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19929         echo 1M > $cgdir/memory.limit_in_bytes
19930
19931         # Should not LBUG, just be killed by oom-killer
19932         # dd will return 0 even allocation failure in some environment.
19933         # So don't check return value
19934         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19935         cleanup_test411_cgroup $cgdir
19936
19937         return 0
19938 }
19939 run_test 411 "Slab allocation error with cgroup does not LBUG"
19940
19941 test_412() {
19942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19943         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19944                 skip "Need server version at least 2.10.55"
19945         fi
19946
19947         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19948                 error "mkdir failed"
19949         $LFS getdirstripe $DIR/$tdir
19950         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19951         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19952                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19953         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19954         [ $stripe_count -eq 2 ] ||
19955                 error "expect 2 get $stripe_count"
19956 }
19957 run_test 412 "mkdir on specific MDTs"
19958
19959 test_413a() {
19960         [ $MDSCOUNT -lt 2 ] &&
19961                 skip "We need at least 2 MDTs for this test"
19962
19963         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19964                 skip "Need server version at least 2.10.55"
19965         fi
19966
19967         mkdir $DIR/$tdir || error "mkdir failed"
19968
19969         # find MDT that is the most full
19970         local max=$($LFS df | grep MDT |
19971                 awk 'BEGIN { a=0 }
19972                         { sub("%", "", $5)
19973                           if (0+$5 >= a)
19974                           {
19975                                 a = $5
19976                                 b = $6
19977                           }
19978                         }
19979                      END { split(b, c, ":")
19980                            sub("]", "", c[2])
19981                            print c[2]
19982                          }')
19983
19984         for i in $(seq $((MDSCOUNT - 1))); do
19985                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19986                         error "mkdir d$i failed"
19987                 $LFS getdirstripe $DIR/$tdir/d$i
19988                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19989                 [ $stripe_index -ne $max ] ||
19990                         error "don't expect $max"
19991         done
19992 }
19993 run_test 413a "mkdir on less full MDTs"
19994
19995 test_413b() {
19996         [ $MDSCOUNT -lt 2 ] &&
19997                 skip "We need at least 2 MDTs for this test"
19998
19999         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20000                 skip "Need server version at least 2.12.52"
20001
20002         mkdir $DIR/$tdir || error "mkdir failed"
20003         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20004                 error "setdirstripe failed"
20005
20006         local qos_prio_free
20007         local qos_threshold_rr
20008         local count
20009
20010         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20011         qos_prio_free=${qos_prio_free%%%}
20012         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20013         qos_threshold_rr=${qos_threshold_rr%%%}
20014
20015         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20016         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20017                 EXIT
20018
20019         echo "mkdir with roundrobin"
20020
20021         $LCTL set_param lmv.*.qos_threshold_rr=100
20022         for i in $(seq $((100 * MDSCOUNT))); do
20023                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20024         done
20025         for i in $(seq $MDSCOUNT); do
20026                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20027                         wc -w)
20028                 echo "$count directories created on MDT$((i - 1))"
20029                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20030         done
20031
20032         rm -rf $DIR/$tdir/*
20033
20034         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20035
20036         local ffree
20037         local max
20038         local min
20039         local max_index
20040         local min_index
20041
20042         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20043         echo "MDT filesfree available: ${ffree[@]}"
20044         max=${ffree[0]}
20045         min=${ffree[0]}
20046         max_index=0
20047         min_index=0
20048         for ((i = 0; i < ${#ffree[@]}; i++)); do
20049                 if [[ ${ffree[i]} -gt $max ]]; then
20050                         max=${ffree[i]}
20051                         max_index=$i
20052                 fi
20053                 if [[ ${ffree[i]} -lt $min ]]; then
20054                         min=${ffree[i]}
20055                         min_index=$i
20056                 fi
20057         done
20058         echo "Min free files: MDT$min_index: $min"
20059         echo "Max free files: MDT$max_index: $max"
20060
20061         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20062         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20063
20064         # Check if we need to generate uneven MDTs
20065         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20066         local threshold=10
20067         local diff=$((max - min))
20068         local diff2=$((diff * 100 / min))
20069
20070         echo -n "Check for uneven MDTs: "
20071         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20072
20073         if [ $diff2 -gt $threshold ]; then
20074                 echo "ok"
20075                 echo "Don't need to fill MDT$min_index"
20076         else
20077                 # generate uneven MDTs, create till 25% diff
20078                 echo "no"
20079                 diff2=$((threshold - diff2))
20080                 diff=$((min * diff2 / 100))
20081                 # 50 sec per 10000 files in vm
20082                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20083                         skip "$diff files to create"
20084                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20085                 local i
20086                 local value="$(generate_string 1024)"
20087                 for i in $(seq $diff); do
20088                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20089                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20090                                 error "create f$i failed"
20091                         setfattr -n user.413b -v $value \
20092                                 $DIR/$tdir-MDT$min_index/f$i ||
20093                                 error "setfattr f$i failed"
20094                 done
20095         fi
20096
20097         min=$((100 *MDSCOUNT))
20098         max=0
20099
20100         echo "mkdir with balanced space usage"
20101         $LCTL set_param lmv.*.qos_prio_free=100
20102         for i in $(seq $((100 * MDSCOUNT))); do
20103                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20104         done
20105         for i in $(seq $MDSCOUNT); do
20106                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20107                         wc -w)
20108                 echo "$count directories created on MDT$((i - 1))"
20109                 [ $min -gt $count ] && min=$count
20110                 [ $max -lt $count ] && max=$count
20111         done
20112         [ $((max - min)) -gt $MDSCOUNT ] ||
20113                 error "subdirs shouldn't be evenly distributed"
20114 }
20115 run_test 413b "mkdir with balanced space usage"
20116
20117 test_414() {
20118 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20119         $LCTL set_param fail_loc=0x80000521
20120         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20121         rm -f $DIR/$tfile
20122 }
20123 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20124
20125 test_415() {
20126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20127         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20128                 skip "Need server version at least 2.11.52"
20129
20130         # LU-11102
20131         local total
20132         local setattr_pid
20133         local start_time
20134         local end_time
20135         local duration
20136
20137         total=500
20138         # this test may be slow on ZFS
20139         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20140
20141         # though this test is designed for striped directory, let's test normal
20142         # directory too since lock is always saved as CoS lock.
20143         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20144         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20145
20146         (
20147                 while true; do
20148                         touch $DIR/$tdir
20149                 done
20150         ) &
20151         setattr_pid=$!
20152
20153         start_time=$(date +%s)
20154         for i in $(seq $total); do
20155                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20156                         > /dev/null
20157         done
20158         end_time=$(date +%s)
20159         duration=$((end_time - start_time))
20160
20161         kill -9 $setattr_pid
20162
20163         echo "rename $total files took $duration sec"
20164         [ $duration -lt 100 ] || error "rename took $duration sec"
20165 }
20166 run_test 415 "lock revoke is not missing"
20167
20168 test_416() {
20169         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20170                 skip "Need server version at least 2.11.55"
20171
20172         # define OBD_FAIL_OSD_TXN_START    0x19a
20173         do_facet mds1 lctl set_param fail_loc=0x19a
20174
20175         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20176
20177         true
20178 }
20179 run_test 416 "transaction start failure won't cause system hung"
20180
20181 cleanup_417() {
20182         trap 0
20183         do_nodes $(comma_list $(mdts_nodes)) \
20184                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20185         do_nodes $(comma_list $(mdts_nodes)) \
20186                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20187         do_nodes $(comma_list $(mdts_nodes)) \
20188                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20189 }
20190
20191 test_417() {
20192         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20193         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20194                 skip "Need MDS version at least 2.11.56"
20195
20196         trap cleanup_417 RETURN EXIT
20197
20198         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20199         do_nodes $(comma_list $(mdts_nodes)) \
20200                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20201         $LFS migrate -m 0 $DIR/$tdir.1 &&
20202                 error "migrate dir $tdir.1 should fail"
20203
20204         do_nodes $(comma_list $(mdts_nodes)) \
20205                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20206         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20207                 error "create remote dir $tdir.2 should fail"
20208
20209         do_nodes $(comma_list $(mdts_nodes)) \
20210                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20211         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20212                 error "create striped dir $tdir.3 should fail"
20213         true
20214 }
20215 run_test 417 "disable remote dir, striped dir and dir migration"
20216
20217 # Checks that the outputs of df [-i] and lfs df [-i] match
20218 #
20219 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20220 check_lfs_df() {
20221         local dir=$2
20222         local inodes
20223         local df_out
20224         local lfs_df_out
20225         local count
20226         local passed=false
20227
20228         # blocks or inodes
20229         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20230
20231         for count in {1..100}; do
20232                 cancel_lru_locks
20233                 sync; sleep 0.2
20234
20235                 # read the lines of interest
20236                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20237                         error "df $inodes $dir | tail -n +2 failed"
20238                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20239                         error "lfs df $inodes $dir | grep summary: failed"
20240
20241                 # skip first substrings of each output as they are different
20242                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20243                 # compare the two outputs
20244                 passed=true
20245                 for i in {1..5}; do
20246                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20247                 done
20248                 $passed && break
20249         done
20250
20251         if ! $passed; then
20252                 df -P $inodes $dir
20253                 echo
20254                 lfs df $inodes $dir
20255                 error "df and lfs df $1 output mismatch: "      \
20256                       "df ${inodes}: ${df_out[*]}, "            \
20257                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20258         fi
20259 }
20260
20261 test_418() {
20262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20263
20264         local dir=$DIR/$tdir
20265         local numfiles=$((RANDOM % 4096 + 2))
20266         local numblocks=$((RANDOM % 256 + 1))
20267
20268         wait_delete_completed
20269         test_mkdir $dir
20270
20271         # check block output
20272         check_lfs_df blocks $dir
20273         # check inode output
20274         check_lfs_df inodes $dir
20275
20276         # create a single file and retest
20277         echo "Creating a single file and testing"
20278         createmany -o $dir/$tfile- 1 &>/dev/null ||
20279                 error "creating 1 file in $dir failed"
20280         check_lfs_df blocks $dir
20281         check_lfs_df inodes $dir
20282
20283         # create a random number of files
20284         echo "Creating $((numfiles - 1)) files and testing"
20285         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20286                 error "creating $((numfiles - 1)) files in $dir failed"
20287
20288         # write a random number of blocks to the first test file
20289         echo "Writing $numblocks 4K blocks and testing"
20290         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20291                 count=$numblocks &>/dev/null ||
20292                 error "dd to $dir/${tfile}-0 failed"
20293
20294         # retest
20295         check_lfs_df blocks $dir
20296         check_lfs_df inodes $dir
20297
20298         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20299                 error "unlinking $numfiles files in $dir failed"
20300 }
20301 run_test 418 "df and lfs df outputs match"
20302
20303 test_419()
20304 {
20305         local dir=$DIR/$tdir
20306
20307         mkdir -p $dir
20308         touch $dir/file
20309
20310         cancel_lru_locks mdc
20311
20312         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20313         $LCTL set_param fail_loc=0x1410
20314         cat $dir/file
20315         $LCTL set_param fail_loc=0
20316         rm -rf $dir
20317 }
20318 run_test 419 "Verify open file by name doesn't crash kernel"
20319
20320 test_420()
20321 {
20322         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20323                 skip "Need MDS version at least 2.12.53"
20324
20325         local SAVE_UMASK=$(umask)
20326         local dir=$DIR/$tdir
20327         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20328
20329         mkdir -p $dir
20330         umask 0000
20331         mkdir -m03777 $dir/testdir
20332         ls -dn $dir/testdir
20333         local dirperms=$(ls -dn $dir/testdir | awk '{print $1}')
20334         [ $dirperms == "drwxrwsrwt" ] ||
20335                 error "incorrect perms on $dir/testdir"
20336
20337         $PDSH ${uname}@localhost "PATH=$LUSTRE/tests:\$PATH; \
20338                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20339         ls -n $dir/testdir/testfile
20340         local fileperms=$(ls -n $dir/testdir/testfile | awk '{print $1}')
20341         [ $fileperms == "-rwxr-xr-x" ] ||
20342                 error "incorrect perms on $dir/testdir/testfile"
20343
20344         umask $SAVE_UMASK
20345 }
20346 run_test 420 "clear SGID bit on non-directories for non-members"
20347
20348 prep_801() {
20349         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20350         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20351                 skip "Need server version at least 2.9.55"
20352
20353         start_full_debug_logging
20354 }
20355
20356 post_801() {
20357         stop_full_debug_logging
20358 }
20359
20360 barrier_stat() {
20361         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20362                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20363                            awk '/The barrier for/ { print $7 }')
20364                 echo $st
20365         else
20366                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20367                 echo \'$st\'
20368         fi
20369 }
20370
20371 barrier_expired() {
20372         local expired
20373
20374         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20375                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20376                           awk '/will be expired/ { print $7 }')
20377         else
20378                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20379         fi
20380
20381         echo $expired
20382 }
20383
20384 test_801a() {
20385         prep_801
20386
20387         echo "Start barrier_freeze at: $(date)"
20388         #define OBD_FAIL_BARRIER_DELAY          0x2202
20389         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20390         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20391
20392         sleep 2
20393         local b_status=$(barrier_stat)
20394         echo "Got barrier status at: $(date)"
20395         [ "$b_status" = "'freezing_p1'" ] ||
20396                 error "(1) unexpected barrier status $b_status"
20397
20398         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20399         wait
20400         b_status=$(barrier_stat)
20401         [ "$b_status" = "'frozen'" ] ||
20402                 error "(2) unexpected barrier status $b_status"
20403
20404         local expired=$(barrier_expired)
20405         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20406         sleep $((expired + 3))
20407
20408         b_status=$(barrier_stat)
20409         [ "$b_status" = "'expired'" ] ||
20410                 error "(3) unexpected barrier status $b_status"
20411
20412         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20413                 error "(4) fail to freeze barrier"
20414
20415         b_status=$(barrier_stat)
20416         [ "$b_status" = "'frozen'" ] ||
20417                 error "(5) unexpected barrier status $b_status"
20418
20419         echo "Start barrier_thaw at: $(date)"
20420         #define OBD_FAIL_BARRIER_DELAY          0x2202
20421         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20422         do_facet mgs $LCTL barrier_thaw $FSNAME &
20423
20424         sleep 2
20425         b_status=$(barrier_stat)
20426         echo "Got barrier status at: $(date)"
20427         [ "$b_status" = "'thawing'" ] ||
20428                 error "(6) unexpected barrier status $b_status"
20429
20430         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20431         wait
20432         b_status=$(barrier_stat)
20433         [ "$b_status" = "'thawed'" ] ||
20434                 error "(7) unexpected barrier status $b_status"
20435
20436         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20437         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20438         do_facet mgs $LCTL barrier_freeze $FSNAME
20439
20440         b_status=$(barrier_stat)
20441         [ "$b_status" = "'failed'" ] ||
20442                 error "(8) unexpected barrier status $b_status"
20443
20444         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20445         do_facet mgs $LCTL barrier_thaw $FSNAME
20446
20447         post_801
20448 }
20449 run_test 801a "write barrier user interfaces and stat machine"
20450
20451 test_801b() {
20452         prep_801
20453
20454         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20455         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20456         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20457         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20458         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20459
20460         cancel_lru_locks mdc
20461
20462         # 180 seconds should be long enough
20463         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20464
20465         local b_status=$(barrier_stat)
20466         [ "$b_status" = "'frozen'" ] ||
20467                 error "(6) unexpected barrier status $b_status"
20468
20469         mkdir $DIR/$tdir/d0/d10 &
20470         mkdir_pid=$!
20471
20472         touch $DIR/$tdir/d1/f13 &
20473         touch_pid=$!
20474
20475         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20476         ln_pid=$!
20477
20478         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20479         mv_pid=$!
20480
20481         rm -f $DIR/$tdir/d4/f12 &
20482         rm_pid=$!
20483
20484         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20485
20486         # To guarantee taht the 'stat' is not blocked
20487         b_status=$(barrier_stat)
20488         [ "$b_status" = "'frozen'" ] ||
20489                 error "(8) unexpected barrier status $b_status"
20490
20491         # let above commands to run at background
20492         sleep 5
20493
20494         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20495         ps -p $touch_pid || error "(10) touch should be blocked"
20496         ps -p $ln_pid || error "(11) link should be blocked"
20497         ps -p $mv_pid || error "(12) rename should be blocked"
20498         ps -p $rm_pid || error "(13) unlink should be blocked"
20499
20500         b_status=$(barrier_stat)
20501         [ "$b_status" = "'frozen'" ] ||
20502                 error "(14) unexpected barrier status $b_status"
20503
20504         do_facet mgs $LCTL barrier_thaw $FSNAME
20505         b_status=$(barrier_stat)
20506         [ "$b_status" = "'thawed'" ] ||
20507                 error "(15) unexpected barrier status $b_status"
20508
20509         wait $mkdir_pid || error "(16) mkdir should succeed"
20510         wait $touch_pid || error "(17) touch should succeed"
20511         wait $ln_pid || error "(18) link should succeed"
20512         wait $mv_pid || error "(19) rename should succeed"
20513         wait $rm_pid || error "(20) unlink should succeed"
20514
20515         post_801
20516 }
20517 run_test 801b "modification will be blocked by write barrier"
20518
20519 test_801c() {
20520         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20521
20522         prep_801
20523
20524         stop mds2 || error "(1) Fail to stop mds2"
20525
20526         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20527
20528         local b_status=$(barrier_stat)
20529         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20530                 do_facet mgs $LCTL barrier_thaw $FSNAME
20531                 error "(2) unexpected barrier status $b_status"
20532         }
20533
20534         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20535                 error "(3) Fail to rescan barrier bitmap"
20536
20537         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20538
20539         b_status=$(barrier_stat)
20540         [ "$b_status" = "'frozen'" ] ||
20541                 error "(4) unexpected barrier status $b_status"
20542
20543         do_facet mgs $LCTL barrier_thaw $FSNAME
20544         b_status=$(barrier_stat)
20545         [ "$b_status" = "'thawed'" ] ||
20546                 error "(5) unexpected barrier status $b_status"
20547
20548         local devname=$(mdsdevname 2)
20549
20550         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20551
20552         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20553                 error "(7) Fail to rescan barrier bitmap"
20554
20555         post_801
20556 }
20557 run_test 801c "rescan barrier bitmap"
20558
20559 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20560 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20561 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20562
20563 cleanup_802a() {
20564         trap 0
20565
20566         stopall
20567         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20568         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20569         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20570         setupall
20571 }
20572
20573 test_802a() {
20574
20575         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20576         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20577                 skip "Need server version at least 2.9.55"
20578
20579         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20580
20581         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20582
20583         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20584                 error "(2) Fail to copy"
20585
20586         trap cleanup_802a EXIT
20587
20588         # sync by force before remount as readonly
20589         sync; sync_all_data; sleep 3; sync_all_data
20590
20591         stopall
20592
20593         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20594         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20595         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20596
20597         echo "Mount the server as read only"
20598         setupall server_only || error "(3) Fail to start servers"
20599
20600         echo "Mount client without ro should fail"
20601         mount_client $MOUNT &&
20602                 error "(4) Mount client without 'ro' should fail"
20603
20604         echo "Mount client with ro should succeed"
20605         mount_client $MOUNT ro ||
20606                 error "(5) Mount client with 'ro' should succeed"
20607
20608         echo "Modify should be refused"
20609         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20610
20611         echo "Read should be allowed"
20612         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20613                 error "(7) Read should succeed under ro mode"
20614
20615         cleanup_802a
20616 }
20617 run_test 802a "simulate readonly device"
20618
20619 test_802b() {
20620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20621         remote_mds_nodsh && skip "remote MDS with nodsh"
20622
20623         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20624                 skip "readonly option not available"
20625
20626         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20627
20628         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20629                 error "(2) Fail to copy"
20630
20631         # write back all cached data before setting MDT to readonly
20632         cancel_lru_locks
20633         sync_all_data
20634
20635         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20636         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20637
20638         echo "Modify should be refused"
20639         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20640
20641         echo "Read should be allowed"
20642         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20643                 error "(7) Read should succeed under ro mode"
20644
20645         # disable readonly
20646         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20647 }
20648 run_test 802b "be able to set MDTs to readonly"
20649
20650 test_803() {
20651         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20652         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20653                 skip "MDS needs to be newer than 2.10.54"
20654
20655         mkdir -p $DIR/$tdir
20656         # Create some objects on all MDTs to trigger related logs objects
20657         for idx in $(seq $MDSCOUNT); do
20658                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20659                         $DIR/$tdir/dir${idx} ||
20660                         error "Fail to create $DIR/$tdir/dir${idx}"
20661         done
20662
20663         sync; sleep 3
20664         wait_delete_completed # ensure old test cleanups are finished
20665         echo "before create:"
20666         $LFS df -i $MOUNT
20667         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20668
20669         for i in {1..10}; do
20670                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20671                         error "Fail to create $DIR/$tdir/foo$i"
20672         done
20673
20674         sync; sleep 3
20675         echo "after create:"
20676         $LFS df -i $MOUNT
20677         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20678
20679         # allow for an llog to be cleaned up during the test
20680         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20681                 error "before ($before_used) + 10 > after ($after_used)"
20682
20683         for i in {1..10}; do
20684                 rm -rf $DIR/$tdir/foo$i ||
20685                         error "Fail to remove $DIR/$tdir/foo$i"
20686         done
20687
20688         sleep 3 # avoid MDT return cached statfs
20689         wait_delete_completed
20690         echo "after unlink:"
20691         $LFS df -i $MOUNT
20692         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20693
20694         # allow for an llog to be created during the test
20695         [ $after_used -le $((before_used + 1)) ] ||
20696                 error "after ($after_used) > before ($before_used) + 1"
20697 }
20698 run_test 803 "verify agent object for remote object"
20699
20700 test_804() {
20701         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20702         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20703                 skip "MDS needs to be newer than 2.10.54"
20704         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20705
20706         mkdir -p $DIR/$tdir
20707         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20708                 error "Fail to create $DIR/$tdir/dir0"
20709
20710         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20711         local dev=$(mdsdevname 2)
20712
20713         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20714                 grep ${fid} || error "NOT found agent entry for dir0"
20715
20716         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20717                 error "Fail to create $DIR/$tdir/dir1"
20718
20719         touch $DIR/$tdir/dir1/foo0 ||
20720                 error "Fail to create $DIR/$tdir/dir1/foo0"
20721         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20722         local rc=0
20723
20724         for idx in $(seq $MDSCOUNT); do
20725                 dev=$(mdsdevname $idx)
20726                 do_facet mds${idx} \
20727                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20728                         grep ${fid} && rc=$idx
20729         done
20730
20731         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20732                 error "Fail to rename foo0 to foo1"
20733         if [ $rc -eq 0 ]; then
20734                 for idx in $(seq $MDSCOUNT); do
20735                         dev=$(mdsdevname $idx)
20736                         do_facet mds${idx} \
20737                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20738                         grep ${fid} && rc=$idx
20739                 done
20740         fi
20741
20742         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20743                 error "Fail to rename foo1 to foo2"
20744         if [ $rc -eq 0 ]; then
20745                 for idx in $(seq $MDSCOUNT); do
20746                         dev=$(mdsdevname $idx)
20747                         do_facet mds${idx} \
20748                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20749                         grep ${fid} && rc=$idx
20750                 done
20751         fi
20752
20753         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20754
20755         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20756                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20757         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20758                 error "Fail to rename foo2 to foo0"
20759         unlink $DIR/$tdir/dir1/foo0 ||
20760                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20761         rm -rf $DIR/$tdir/dir0 ||
20762                 error "Fail to rm $DIR/$tdir/dir0"
20763
20764         for idx in $(seq $MDSCOUNT); do
20765                 dev=$(mdsdevname $idx)
20766                 rc=0
20767
20768                 stop mds${idx}
20769                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20770                         rc=$?
20771                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20772                         error "mount mds$idx failed"
20773                 df $MOUNT > /dev/null 2>&1
20774
20775                 # e2fsck should not return error
20776                 [ $rc -eq 0 ] ||
20777                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20778         done
20779 }
20780 run_test 804 "verify agent entry for remote entry"
20781
20782 cleanup_805() {
20783         do_facet $SINGLEMDS zfs set quota=$old $fsset
20784         unlinkmany $DIR/$tdir/f- 1000000
20785         trap 0
20786 }
20787
20788 test_805() {
20789         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20790         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20791         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20792                 skip "netfree not implemented before 0.7"
20793         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20794                 skip "Need MDS version at least 2.10.57"
20795
20796         local fsset
20797         local freekb
20798         local usedkb
20799         local old
20800         local quota
20801         local pref="osd-zfs.lustre-MDT0000."
20802
20803         # limit available space on MDS dataset to meet nospace issue
20804         # quickly. then ZFS 0.7.2 can use reserved space if asked
20805         # properly (using netfree flag in osd_declare_destroy()
20806         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20807         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20808                 gawk '{print $3}')
20809         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20810         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20811         let "usedkb=usedkb-freekb"
20812         let "freekb=freekb/2"
20813         if let "freekb > 5000"; then
20814                 let "freekb=5000"
20815         fi
20816         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20817         trap cleanup_805 EXIT
20818         mkdir $DIR/$tdir
20819         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20820         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20821         rm -rf $DIR/$tdir || error "not able to remove"
20822         do_facet $SINGLEMDS zfs set quota=$old $fsset
20823         trap 0
20824 }
20825 run_test 805 "ZFS can remove from full fs"
20826
20827 # Size-on-MDS test
20828 check_lsom_data()
20829 {
20830         local file=$1
20831         local size=$($LFS getsom -s $file)
20832         local expect=$(stat -c %s $file)
20833
20834         [[ $size == $expect ]] ||
20835                 error "$file expected size: $expect, got: $size"
20836
20837         local blocks=$($LFS getsom -b $file)
20838         expect=$(stat -c %b $file)
20839         [[ $blocks == $expect ]] ||
20840                 error "$file expected blocks: $expect, got: $blocks"
20841 }
20842
20843 check_lsom_size()
20844 {
20845         local size=$($LFS getsom -s $1)
20846         local expect=$2
20847
20848         [[ $size == $expect ]] ||
20849                 error "$file expected size: $expect, got: $size"
20850 }
20851
20852 test_806() {
20853         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20854                 skip "Need MDS version at least 2.11.52"
20855
20856         local bs=1048576
20857
20858         touch $DIR/$tfile || error "touch $tfile failed"
20859
20860         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20861         save_lustre_params client "llite.*.xattr_cache" > $save
20862         lctl set_param llite.*.xattr_cache=0
20863         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20864
20865         # single-threaded write
20866         echo "Test SOM for single-threaded write"
20867         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20868                 error "write $tfile failed"
20869         check_lsom_size $DIR/$tfile $bs
20870
20871         local num=32
20872         local size=$(($num * $bs))
20873         local offset=0
20874         local i
20875
20876         echo "Test SOM for single client multi-threaded($num) write"
20877         $TRUNCATE $DIR/$tfile 0
20878         for ((i = 0; i < $num; i++)); do
20879                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20880                 local pids[$i]=$!
20881                 offset=$((offset + $bs))
20882         done
20883         for (( i=0; i < $num; i++ )); do
20884                 wait ${pids[$i]}
20885         done
20886         check_lsom_size $DIR/$tfile $size
20887
20888         $TRUNCATE $DIR/$tfile 0
20889         for ((i = 0; i < $num; i++)); do
20890                 offset=$((offset - $bs))
20891                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20892                 local pids[$i]=$!
20893         done
20894         for (( i=0; i < $num; i++ )); do
20895                 wait ${pids[$i]}
20896         done
20897         check_lsom_size $DIR/$tfile $size
20898
20899         # multi-client wirtes
20900         num=$(get_node_count ${CLIENTS//,/ })
20901         size=$(($num * $bs))
20902         offset=0
20903         i=0
20904
20905         echo "Test SOM for multi-client ($num) writes"
20906         $TRUNCATE $DIR/$tfile 0
20907         for client in ${CLIENTS//,/ }; do
20908                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20909                 local pids[$i]=$!
20910                 i=$((i + 1))
20911                 offset=$((offset + $bs))
20912         done
20913         for (( i=0; i < $num; i++ )); do
20914                 wait ${pids[$i]}
20915         done
20916         check_lsom_size $DIR/$tfile $offset
20917
20918         i=0
20919         $TRUNCATE $DIR/$tfile 0
20920         for client in ${CLIENTS//,/ }; do
20921                 offset=$((offset - $bs))
20922                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20923                 local pids[$i]=$!
20924                 i=$((i + 1))
20925         done
20926         for (( i=0; i < $num; i++ )); do
20927                 wait ${pids[$i]}
20928         done
20929         check_lsom_size $DIR/$tfile $size
20930
20931         # verify truncate
20932         echo "Test SOM for truncate"
20933         $TRUNCATE $DIR/$tfile 1048576
20934         check_lsom_size $DIR/$tfile 1048576
20935         $TRUNCATE $DIR/$tfile 1234
20936         check_lsom_size $DIR/$tfile 1234
20937
20938         # verify SOM blocks count
20939         echo "Verify SOM block count"
20940         $TRUNCATE $DIR/$tfile 0
20941         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20942                 error "failed to write file $tfile"
20943         check_lsom_data $DIR/$tfile
20944 }
20945 run_test 806 "Verify Lazy Size on MDS"
20946
20947 test_807() {
20948         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20949         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20950                 skip "Need MDS version at least 2.11.52"
20951
20952         # Registration step
20953         changelog_register || error "changelog_register failed"
20954         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20955         changelog_users $SINGLEMDS | grep -q $cl_user ||
20956                 error "User $cl_user not found in changelog_users"
20957
20958         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20959         save_lustre_params client "llite.*.xattr_cache" > $save
20960         lctl set_param llite.*.xattr_cache=0
20961         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20962
20963         rm -rf $DIR/$tdir || error "rm $tdir failed"
20964         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20965         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20966         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20967         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20968                 error "truncate $tdir/trunc failed"
20969
20970         local bs=1048576
20971         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20972                 error "write $tfile failed"
20973
20974         # multi-client wirtes
20975         local num=$(get_node_count ${CLIENTS//,/ })
20976         local offset=0
20977         local i=0
20978
20979         echo "Test SOM for multi-client ($num) writes"
20980         touch $DIR/$tfile || error "touch $tfile failed"
20981         $TRUNCATE $DIR/$tfile 0
20982         for client in ${CLIENTS//,/ }; do
20983                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20984                 local pids[$i]=$!
20985                 i=$((i + 1))
20986                 offset=$((offset + $bs))
20987         done
20988         for (( i=0; i < $num; i++ )); do
20989                 wait ${pids[$i]}
20990         done
20991
20992         sleep 5
20993         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20994         check_lsom_data $DIR/$tdir/trunc
20995         check_lsom_data $DIR/$tdir/single_dd
20996         check_lsom_data $DIR/$tfile
20997
20998         rm -rf $DIR/$tdir
20999         # Deregistration step
21000         changelog_deregister || error "changelog_deregister failed"
21001 }
21002 run_test 807 "verify LSOM syncing tool"
21003
21004 check_som_nologged()
21005 {
21006         local lines=$($LFS changelog $FSNAME-MDT0000 |
21007                 grep 'x=trusted.som' | wc -l)
21008         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21009 }
21010
21011 test_808() {
21012         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21013                 skip "Need MDS version at least 2.11.55"
21014
21015         # Registration step
21016         changelog_register || error "changelog_register failed"
21017
21018         touch $DIR/$tfile || error "touch $tfile failed"
21019         check_som_nologged
21020
21021         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21022                 error "write $tfile failed"
21023         check_som_nologged
21024
21025         $TRUNCATE $DIR/$tfile 1234
21026         check_som_nologged
21027
21028         $TRUNCATE $DIR/$tfile 1048576
21029         check_som_nologged
21030
21031         # Deregistration step
21032         changelog_deregister || error "changelog_deregister failed"
21033 }
21034 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21035
21036 check_som_nodata()
21037 {
21038         $LFS getsom $1
21039         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21040 }
21041
21042 test_809() {
21043         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21044                 skip "Need MDS version at least 2.11.56"
21045
21046         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21047                 error "failed to create DoM-only file $DIR/$tfile"
21048         touch $DIR/$tfile || error "touch $tfile failed"
21049         check_som_nodata $DIR/$tfile
21050
21051         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21052                 error "write $tfile failed"
21053         check_som_nodata $DIR/$tfile
21054
21055         $TRUNCATE $DIR/$tfile 1234
21056         check_som_nodata $DIR/$tfile
21057
21058         $TRUNCATE $DIR/$tfile 4097
21059         check_som_nodata $DIR/$file
21060 }
21061 run_test 809 "Verify no SOM xattr store for DoM-only files"
21062
21063 test_810() {
21064         local ORIG
21065         local CSUM
21066
21067         # t10 seem to dislike partial pages
21068         lctl set_param osc.*.checksum_type=adler
21069         lctl set_param fail_loc=0x411
21070         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21071         ORIG=$(md5sum $DIR/$tfile)
21072         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21073         CSUM=$(md5sum $DIR/$tfile)
21074         set_checksum_type adler
21075         if [ "$ORIG" != "$CSUM" ]; then
21076                 error "$ORIG != $CSUM"
21077         fi
21078 }
21079 run_test 810 "partial page writes on ZFS (LU-11663)"
21080
21081 test_811() {
21082         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21083                 skip "Need MDS version at least 2.11.56"
21084
21085         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21086         do_facet mds1 $LCTL set_param fail_loc=0x165
21087         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21088
21089         stop mds1
21090         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21091
21092         sleep 5
21093         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21094                 error "MDD orphan cleanup thread not quit"
21095 }
21096 run_test 811 "orphan name stub can be cleaned up in startup"
21097
21098 test_812() {
21099         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21100                 skip "OST < 2.12.51 doesn't support this fail_loc"
21101         [ "$SHARED_KEY" = true ] &&
21102                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21103
21104         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21105         # ensure ost1 is connected
21106         stat $DIR/$tfile >/dev/null || error "can't stat"
21107         wait_osc_import_state client ost1 FULL
21108         # no locks, no reqs to let the connection idle
21109         cancel_lru_locks osc
21110
21111         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21112 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21113         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21114         wait_osc_import_state client ost1 CONNECTING
21115         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21116
21117         stat $DIR/$tfile >/dev/null || error "can't stat file"
21118 }
21119 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21120
21121 test_813() {
21122         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21123         [ -z "$file_heat_sav" ] && skip "no file heat support"
21124
21125         local readsample
21126         local writesample
21127         local readbyte
21128         local writebyte
21129         local readsample1
21130         local writesample1
21131         local readbyte1
21132         local writebyte1
21133
21134         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21135         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21136
21137         $LCTL set_param -n llite.*.file_heat=1
21138         echo "Turn on file heat"
21139         echo "Period second: $period_second, Decay percentage: $decay_pct"
21140
21141         echo "QQQQ" > $DIR/$tfile
21142         echo "QQQQ" > $DIR/$tfile
21143         echo "QQQQ" > $DIR/$tfile
21144         cat $DIR/$tfile > /dev/null
21145         cat $DIR/$tfile > /dev/null
21146         cat $DIR/$tfile > /dev/null
21147         cat $DIR/$tfile > /dev/null
21148
21149         local out=$($LFS heat_get $DIR/$tfile)
21150
21151         $LFS heat_get $DIR/$tfile
21152         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21153         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21154         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21155         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21156
21157         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21158         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21159         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21160         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21161
21162         sleep $((period_second + 3))
21163         echo "Sleep $((period_second + 3)) seconds..."
21164         # The recursion formula to calculate the heat of the file f is as
21165         # follow:
21166         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21167         # Where Hi is the heat value in the period between time points i*I and
21168         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21169         # to the weight of Ci.
21170         out=$($LFS heat_get $DIR/$tfile)
21171         $LFS heat_get $DIR/$tfile
21172         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21173         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21174         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21175         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21176
21177         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21178                 error "read sample ($readsample) is wrong"
21179         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21180                 error "write sample ($writesample) is wrong"
21181         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21182                 error "read bytes ($readbyte) is wrong"
21183         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21184                 error "write bytes ($writebyte) is wrong"
21185
21186         echo "QQQQ" > $DIR/$tfile
21187         echo "QQQQ" > $DIR/$tfile
21188         echo "QQQQ" > $DIR/$tfile
21189         cat $DIR/$tfile > /dev/null
21190         cat $DIR/$tfile > /dev/null
21191         cat $DIR/$tfile > /dev/null
21192         cat $DIR/$tfile > /dev/null
21193
21194         sleep $((period_second + 3))
21195         echo "Sleep $((period_second + 3)) seconds..."
21196
21197         out=$($LFS heat_get $DIR/$tfile)
21198         $LFS heat_get $DIR/$tfile
21199         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21200         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21201         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21202         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21203
21204         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21205                 4 * $decay_pct) / 100") -eq 1 ] ||
21206                 error "read sample ($readsample1) is wrong"
21207         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21208                 3 * $decay_pct) / 100") -eq 1 ] ||
21209                 error "write sample ($writesample1) is wrong"
21210         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21211                 20 * $decay_pct) / 100") -eq 1 ] ||
21212                 error "read bytes ($readbyte1) is wrong"
21213         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21214                 15 * $decay_pct) / 100") -eq 1 ] ||
21215                 error "write bytes ($writebyte1) is wrong"
21216
21217         echo "Turn off file heat for the file $DIR/$tfile"
21218         $LFS heat_set -o $DIR/$tfile
21219
21220         echo "QQQQ" > $DIR/$tfile
21221         echo "QQQQ" > $DIR/$tfile
21222         echo "QQQQ" > $DIR/$tfile
21223         cat $DIR/$tfile > /dev/null
21224         cat $DIR/$tfile > /dev/null
21225         cat $DIR/$tfile > /dev/null
21226         cat $DIR/$tfile > /dev/null
21227
21228         out=$($LFS heat_get $DIR/$tfile)
21229         $LFS heat_get $DIR/$tfile
21230         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21231         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21232         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21233         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21234
21235         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21236         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21237         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21238         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21239
21240         echo "Trun on file heat for the file $DIR/$tfile"
21241         $LFS heat_set -O $DIR/$tfile
21242
21243         echo "QQQQ" > $DIR/$tfile
21244         echo "QQQQ" > $DIR/$tfile
21245         echo "QQQQ" > $DIR/$tfile
21246         cat $DIR/$tfile > /dev/null
21247         cat $DIR/$tfile > /dev/null
21248         cat $DIR/$tfile > /dev/null
21249         cat $DIR/$tfile > /dev/null
21250
21251         out=$($LFS heat_get $DIR/$tfile)
21252         $LFS heat_get $DIR/$tfile
21253         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21254         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21255         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21256         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21257
21258         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21259         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21260         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21261         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21262
21263         $LFS heat_set -c $DIR/$tfile
21264         $LCTL set_param -n llite.*.file_heat=0
21265         echo "Turn off file heat support for the Lustre filesystem"
21266
21267         echo "QQQQ" > $DIR/$tfile
21268         echo "QQQQ" > $DIR/$tfile
21269         echo "QQQQ" > $DIR/$tfile
21270         cat $DIR/$tfile > /dev/null
21271         cat $DIR/$tfile > /dev/null
21272         cat $DIR/$tfile > /dev/null
21273         cat $DIR/$tfile > /dev/null
21274
21275         out=$($LFS heat_get $DIR/$tfile)
21276         $LFS heat_get $DIR/$tfile
21277         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21278         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21279         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21280         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21281
21282         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21283         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21284         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21285         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21286
21287         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21288         rm -f $DIR/$tfile
21289 }
21290 run_test 813 "File heat verfication"
21291
21292 test_814()
21293 {
21294         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21295         echo -n y >> $DIR/$tfile
21296         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21297         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21298 }
21299 run_test 814 "sparse cp works as expected (LU-12361)"
21300
21301 #
21302 # tests that do cleanup/setup should be run at the end
21303 #
21304
21305 test_900() {
21306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21307         local ls
21308
21309         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21310         $LCTL set_param fail_loc=0x903
21311
21312         cancel_lru_locks MGC
21313
21314         FAIL_ON_ERROR=true cleanup
21315         FAIL_ON_ERROR=true setup
21316 }
21317 run_test 900 "umount should not race with any mgc requeue thread"
21318
21319 complete $SECONDS
21320 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21321 check_and_cleanup_lustre
21322 if [ "$I_MOUNTED" != "yes" ]; then
21323         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21324 fi
21325 exit_status