Whamcloud - gitweb
LU-11931 lnd: bring back concurrent_sends
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 # -*- tab-width: 8; indent-tabs-mode: t; -*-
3 #
4 # Run select tests by setting ONLY, or as arguments to the script.
5 # Skip specific tests by setting EXCEPT.
6 #
7 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
8 set -e
9
10 ONLY=${ONLY:-"$*"}
11 # bug number for skipped test: LU-9693 LU-6493 LU-9693
12 ALWAYS_EXCEPT="$SANITY_EXCEPT  42a     42b     42c"
13 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
14
15 # skipped tests: LU-8411 LU-9096 LU-9054 ..
16 ALWAYS_EXCEPT="  407     253     312     $ALWAYS_EXCEPT"
17
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795 (all below)
20         ALWAYS_EXCEPT="$ALWAYS_EXCEPT   17n     60a     133g    300f"
21 fi
22
23 # Check Grants after these tests
24 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
25
26 # skip the grant tests for ARM until they are fixed
27 if [[ $(uname -m) = aarch64 ]]; then
28         # bug number:    LU-11596 (all below)
29         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
30         # bug number:    LU-11671 LU-11594 LU-11667 LU-11729
31         ALWAYS_EXCEPT+=" 45       103a      317      810"
32 fi
33
34 SRCDIR=$(cd $(dirname $0); echo $PWD)
35 export PATH=$PATH:/sbin
36
37 TMP=${TMP:-/tmp}
38 OSC=${OSC:-"osc"}
39
40 CC=${CC:-cc}
41 CHECKSTAT=${CHECKSTAT:-"checkstat -v"}
42 CREATETEST=${CREATETEST:-createtest}
43 LFS=${LFS:-lfs}
44 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
45 LCTL=${LCTL:-lctl}
46 OPENFILE=${OPENFILE:-openfile}
47 OPENUNLINK=${OPENUNLINK:-openunlink}
48 export MULTIOP=${MULTIOP:-multiop}
49 READS=${READS:-"reads"}
50 MUNLINK=${MUNLINK:-munlink}
51 SOCKETSERVER=${SOCKETSERVER:-socketserver}
52 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
53 MEMHOG=${MEMHOG:-memhog}
54 DIRECTIO=${DIRECTIO:-directio}
55 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
56 DEF_STRIPE_COUNT=-1
57 CHECK_GRANT=${CHECK_GRANT:-"yes"}
58 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
59 export PARALLEL=${PARALLEL:-"no"}
60
61 export NAME=${NAME:-local}
62
63 SAVE_PWD=$PWD
64
65 CLEANUP=${CLEANUP:-:}
66 SETUP=${SETUP:-:}
67 TRACE=${TRACE:-""}
68 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
69 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
70 . $LUSTRE/tests/test-framework.sh
71 init_test_env $@
72 . ${CONFIG:=$LUSTRE/tests/cfg/${NAME}.sh}
73
74 init_logging
75
76 #                                  5          12          (min)"
77 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
78
79 if [ "$mds1_FSTYPE" = "zfs" ]; then
80         # bug number for skipped test: LU-1957
81         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
82         #                                               13    (min)"
83         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
84 fi
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 # bug number for skipped test: LU-4341
105                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 # bug number for skipped test: LU-3703
108                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         # bug number for skipped test:
118                         #                LU-10334 LU-10366
119                         ALWAYS_EXCEPT+=" 103a     410"
120                 fi
121         fi
122 fi
123
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_and_setup_lustre
145 DIR=${DIR:-$MOUNT}
146 assert_DIR
147
148 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
149
150 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
151 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
152 rm -rf $DIR/[Rdfs][0-9]*
153
154 # $RUNAS_ID may get set incorrectly somewhere else
155 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
156         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
157
158 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
159
160 build_test_filter
161
162 if [ "${ONLY}" = "MOUNT" ] ; then
163         echo "Lustre is up, please go on"
164         exit
165 fi
166
167 echo "preparing for tests involving mounts"
168 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
169 touch $EXT2_DEV
170 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
171 echo # add a newline after mke2fs.
172
173 umask 077
174
175 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
176 lctl set_param debug=-1 2> /dev/null || true
177 test_0a() {
178         touch $DIR/$tfile
179         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
180         rm $DIR/$tfile
181         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
182 }
183 run_test 0a "touch; rm ====================="
184
185 test_0b() {
186         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
187         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
188 }
189 run_test 0b "chmod 0755 $DIR ============================="
190
191 test_0c() {
192         $LCTL get_param mdc.*.import | grep "state: FULL" ||
193                 error "import not FULL"
194         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
195                 error "bad target"
196 }
197 run_test 0c "check import proc"
198
199 test_0d() { # LU-3397
200         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
201                 skip "proc exports not supported before 2.10.57"
202
203         local mgs_exp="mgs.MGS.exports"
204         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
205         local exp_client_nid
206         local exp_client_version
207         local exp_val
208         local imp_val
209         local temp_imp=$DIR/$tfile.import
210         local temp_exp=$DIR/$tfile.export
211
212         # save mgc import file to $temp_imp
213         $LCTL get_param mgc.*.import | tee $temp_imp
214         # Check if client uuid is found in MGS export
215         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
216                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
217                         $client_uuid ] &&
218                         break;
219         done
220         # save mgs export file to $temp_exp
221         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
222
223         # Compare the value of field "connect_flags"
224         imp_val=$(grep "connect_flags" $temp_imp)
225         exp_val=$(grep "connect_flags" $temp_exp)
226         [ "$exp_val" == "$imp_val" ] ||
227                 error "export flags '$exp_val' != import flags '$imp_val'"
228
229         # Compare the value of client version
230         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
231         exp_val=$(version_code $exp_client_version)
232         imp_val=$CLIENT_VERSION
233         [ "$exp_val" == "$imp_val" ] ||
234                 error "export client version '$exp_val' != '$imp_val'"
235 }
236 run_test 0d "check export proc ============================="
237
238 test_1() {
239         test_mkdir $DIR/$tdir
240         test_mkdir $DIR/$tdir/d2
241         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
242         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
243         rmdir $DIR/$tdir/d2
244         rmdir $DIR/$tdir
245         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
246 }
247 run_test 1 "mkdir; remkdir; rmdir"
248
249 test_2() {
250         test_mkdir $DIR/$tdir
251         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
252         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
253         rm -r $DIR/$tdir
254         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
255 }
256 run_test 2 "mkdir; touch; rmdir; check file"
257
258 test_3() {
259         test_mkdir $DIR/$tdir
260         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
261         touch $DIR/$tdir/$tfile
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
265 }
266 run_test 3 "mkdir; touch; rmdir; check dir"
267
268 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
269 test_4() {
270         test_mkdir -i 1 $DIR/$tdir
271
272         touch $DIR/$tdir/$tfile ||
273                 error "Create file under remote directory failed"
274
275         rmdir $DIR/$tdir &&
276                 error "Expect error removing in-use dir $DIR/$tdir"
277
278         test -d $DIR/$tdir || error "Remote directory disappeared"
279
280         rm -rf $DIR/$tdir || error "remove remote dir error"
281 }
282 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
283
284 test_5() {
285         test_mkdir $DIR/$tdir
286         test_mkdir $DIR/$tdir/d2
287         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
288         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
290 }
291 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
292
293 test_6a() {
294         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
295         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
296         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
297                 error "$tfile does not have perm 0666 or UID $UID"
298         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
299         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
300                 error "$tfile should be 0666 and owned by UID $UID"
301 }
302 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
303
304 test_6c() {
305         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
306
307         touch $DIR/$tfile
308         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
309         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
310                 error "$tfile should be owned by UID $RUNAS_ID"
311         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
312         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
313                 error "$tfile should be owned by UID $RUNAS_ID"
314 }
315 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
316
317 test_6e() {
318         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
319
320         touch $DIR/$tfile
321         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
322         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by GID $UID"
324         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
325         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
327 }
328 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
329
330 test_6g() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         test_mkdir $DIR/$tdir
334         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
335         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
336         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
337         test_mkdir $DIR/$tdir/d/subdir
338         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
339                 error "$tdir/d/subdir should be GID $RUNAS_GID"
340         if [[ $MDSCOUNT -gt 1 ]]; then
341                 # check remote dir sgid inherite
342                 $LFS mkdir -i 0 $DIR/$tdir.local ||
343                         error "mkdir $tdir.local failed"
344                 chmod g+s $DIR/$tdir.local ||
345                         error "chmod $tdir.local failed"
346                 chgrp $RUNAS_GID $DIR/$tdir.local ||
347                         error "chgrp $tdir.local failed"
348                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
349                         error "mkdir $tdir.remote failed"
350                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
351                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
352                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
353                         error "$tdir.remote should be mode 02755"
354         fi
355 }
356 run_test 6g "verify new dir in sgid dir inherits group"
357
358 test_6h() { # bug 7331
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile || error "touch failed"
362         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
363         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
364                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
365         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
366                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
367 }
368 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
369
370 test_7a() {
371         test_mkdir $DIR/$tdir
372         $MCREATE $DIR/$tdir/$tfile
373         chmod 0666 $DIR/$tdir/$tfile
374         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
375                 error "$tdir/$tfile should be mode 0666"
376 }
377 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
378
379 test_7b() {
380         if [ ! -d $DIR/$tdir ]; then
381                 test_mkdir $DIR/$tdir
382         fi
383         $MCREATE $DIR/$tdir/$tfile
384         echo -n foo > $DIR/$tdir/$tfile
385         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
386         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
387 }
388 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
389
390 test_8() {
391         test_mkdir $DIR/$tdir
392         touch $DIR/$tdir/$tfile
393         chmod 0666 $DIR/$tdir/$tfile
394         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
395                 error "$tfile mode not 0666"
396 }
397 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
398
399 test_9() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         test_mkdir $DIR/$tdir/d2/d3
403         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
404 }
405 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
406
407 test_10() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         touch $DIR/$tdir/d2/$tfile
411         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
412                 error "$tdir/d2/$tfile not a file"
413 }
414 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
415
416 test_11() {
417         test_mkdir $DIR/$tdir
418         test_mkdir $DIR/$tdir/d2
419         chmod 0666 $DIR/$tdir/d2
420         chmod 0705 $DIR/$tdir/d2
421         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
422                 error "$tdir/d2 mode not 0705"
423 }
424 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
425
426 test_12() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         chmod 0654 $DIR/$tdir/$tfile
431         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
432                 error "$tdir/d2 mode not 0654"
433 }
434 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
435
436 test_13() {
437         test_mkdir $DIR/$tdir
438         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
439         >  $DIR/$tdir/$tfile
440         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
441                 error "$tdir/$tfile size not 0 after truncate"
442 }
443 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
444
445 test_14() {
446         test_mkdir $DIR/$tdir
447         touch $DIR/$tdir/$tfile
448         rm $DIR/$tdir/$tfile
449         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
450 }
451 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
452
453 test_15() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
457         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
458                 error "$tdir/${tfile_2} not a file after rename"
459         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
460 }
461 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
462
463 test_16() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         rm -rf $DIR/$tdir/$tfile
467         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
468 }
469 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
470
471 test_17a() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
475         ls -l $DIR/$tdir
476         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
477                 error "$tdir/l-exist not a symlink"
478         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
479                 error "$tdir/l-exist not referencing a file"
480         rm -f $DIR/$tdir/l-exist
481         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
482 }
483 run_test 17a "symlinks: create, remove (real)"
484
485 test_17b() {
486         test_mkdir $DIR/$tdir
487         ln -s no-such-file $DIR/$tdir/l-dangle
488         ls -l $DIR/$tdir
489         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
490                 error "$tdir/l-dangle not referencing no-such-file"
491         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
492                 error "$tdir/l-dangle not referencing non-existent file"
493         rm -f $DIR/$tdir/l-dangle
494         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
495 }
496 run_test 17b "symlinks: create, remove (dangling)"
497
498 test_17c() { # bug 3440 - don't save failed open RPC for replay
499         test_mkdir $DIR/$tdir
500         ln -s foo $DIR/$tdir/$tfile
501         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
502 }
503 run_test 17c "symlinks: open dangling (should return error)"
504
505 test_17d() {
506         test_mkdir $DIR/$tdir
507         ln -s foo $DIR/$tdir/$tfile
508         touch $DIR/$tdir/$tfile || error "creating to new symlink"
509 }
510 run_test 17d "symlinks: create dangling"
511
512 test_17e() {
513         test_mkdir $DIR/$tdir
514         local foo=$DIR/$tdir/$tfile
515         ln -s $foo $foo || error "create symlink failed"
516         ls -l $foo || error "ls -l failed"
517         ls $foo && error "ls not failed" || true
518 }
519 run_test 17e "symlinks: create recursive symlink (should return error)"
520
521 test_17f() {
522         test_mkdir $DIR/$tdir
523         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
524         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
525         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
526         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
527         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
528         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
529         ls -l  $DIR/$tdir
530 }
531 run_test 17f "symlinks: long and very long symlink name"
532
533 # str_repeat(S, N) generate a string that is string S repeated N times
534 str_repeat() {
535         local s=$1
536         local n=$2
537         local ret=''
538         while [ $((n -= 1)) -ge 0 ]; do
539                 ret=$ret$s
540         done
541         echo $ret
542 }
543
544 # Long symlinks and LU-2241
545 test_17g() {
546         test_mkdir $DIR/$tdir
547         local TESTS="59 60 61 4094 4095"
548
549         # Fix for inode size boundary in 2.1.4
550         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
551                 TESTS="4094 4095"
552
553         # Patch not applied to 2.2 or 2.3 branches
554         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
555         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
556                 TESTS="4094 4095"
557
558         # skip long symlink name for rhel6.5.
559         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
560         grep -q '6.5' /etc/redhat-release &>/dev/null &&
561                 TESTS="59 60 61 4062 4063"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" -o -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles -o $num_uniq -ne $nrfiles -o \
1190              $num_all -ne $((nrfiles + 2)) ]; then
1191                 error "Expected $nrfiles files, got $num_ls " \
1192                         "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24A() { # LU-3182
1288         local NFILES=5000
1289
1290         rm -rf $DIR/$tdir
1291         test_mkdir $DIR/$tdir
1292         trap simple_cleanup_common EXIT
1293         createmany -m $DIR/$tdir/$tfile $NFILES
1294         local t=$(ls $DIR/$tdir | wc -l)
1295         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1296         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1297         if [ $t -ne $NFILES -o $u -ne $NFILES -o $v -ne $((NFILES + 2)) ] ; then
1298                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1299         fi
1300
1301         simple_cleanup_common || error "Can not delete directories"
1302 }
1303 run_test 24A "readdir() returns correct number of entries."
1304
1305 test_24B() { # LU-4805
1306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1307
1308         local count
1309
1310         test_mkdir $DIR/$tdir
1311         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1312                 error "create striped dir failed"
1313
1314         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1315         [ $count -eq 2 ] || error "Expected 2, got $count"
1316
1317         touch $DIR/$tdir/striped_dir/a
1318
1319         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1320         [ $count -eq 3 ] || error "Expected 3, got $count"
1321
1322         touch $DIR/$tdir/striped_dir/.f
1323
1324         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1325         [ $count -eq 4 ] || error "Expected 4, got $count"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24B "readdir for striped dir return correct number of entries"
1330
1331 test_24C() {
1332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1333
1334         mkdir $DIR/$tdir
1335         mkdir $DIR/$tdir/d0
1336         mkdir $DIR/$tdir/d1
1337
1338         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1339                 error "create striped dir failed"
1340
1341         cd $DIR/$tdir/d0/striped_dir
1342
1343         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1344         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1345         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1346
1347         [ "$d0_ino" = "$parent_ino" ] ||
1348                 error ".. wrong, expect $d0_ino, get $parent_ino"
1349
1350         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1351                 error "mv striped dir failed"
1352
1353         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1354
1355         [ "$d1_ino" = "$parent_ino" ] ||
1356                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1357 }
1358 run_test 24C "check .. in striped dir"
1359
1360 test_24E() {
1361         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1363
1364         mkdir -p $DIR/$tdir
1365         mkdir $DIR/$tdir/src_dir
1366         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1367                 error "create remote source failed"
1368
1369         touch $DIR/$tdir/src_dir/src_child/a
1370
1371         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1372                 error "create remote target dir failed"
1373
1374         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1375                 error "create remote target child failed"
1376
1377         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1378                 error "rename dir cross MDT failed!"
1379
1380         find $DIR/$tdir
1381
1382         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1383                 error "src_child still exists after rename"
1384
1385         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1386                 error "missing file(a) after rename"
1387
1388         rm -rf $DIR/$tdir || error "Can not delete directories"
1389 }
1390 run_test 24E "cross MDT rename/link"
1391
1392 test_24F () {
1393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1394
1395         local repeats=1000
1396         [ "$SLOW" = "no" ] && repeats=100
1397
1398         mkdir -p $DIR/$tdir
1399
1400         echo "$repeats repeats"
1401         for ((i = 0; i < repeats; i++)); do
1402                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1403                 touch $DIR/$tdir/test/a || error "touch fails"
1404                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1405                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1406         done
1407
1408         true
1409 }
1410 run_test 24F "hash order vs readdir (LU-11330)"
1411
1412 test_25a() {
1413         echo '== symlink sanity ============================================='
1414
1415         test_mkdir $DIR/d25
1416         ln -s d25 $DIR/s25
1417         touch $DIR/s25/foo ||
1418                 error "File creation in symlinked directory failed"
1419 }
1420 run_test 25a "create file in symlinked directory ==============="
1421
1422 test_25b() {
1423         [ ! -d $DIR/d25 ] && test_25a
1424         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1425 }
1426 run_test 25b "lookup file in symlinked directory ==============="
1427
1428 test_26a() {
1429         test_mkdir $DIR/d26
1430         test_mkdir $DIR/d26/d26-2
1431         ln -s d26/d26-2 $DIR/s26
1432         touch $DIR/s26/foo || error "File creation failed"
1433 }
1434 run_test 26a "multiple component symlink ======================="
1435
1436 test_26b() {
1437         test_mkdir -p $DIR/$tdir/d26-2
1438         ln -s $tdir/d26-2/foo $DIR/s26-2
1439         touch $DIR/s26-2 || error "File creation failed"
1440 }
1441 run_test 26b "multiple component symlink at end of lookup ======"
1442
1443 test_26c() {
1444         test_mkdir $DIR/d26.2
1445         touch $DIR/d26.2/foo
1446         ln -s d26.2 $DIR/s26.2-1
1447         ln -s s26.2-1 $DIR/s26.2-2
1448         ln -s s26.2-2 $DIR/s26.2-3
1449         chmod 0666 $DIR/s26.2-3/foo
1450 }
1451 run_test 26c "chain of symlinks"
1452
1453 # recursive symlinks (bug 439)
1454 test_26d() {
1455         ln -s d26-3/foo $DIR/d26-3
1456 }
1457 run_test 26d "create multiple component recursive symlink"
1458
1459 test_26e() {
1460         [ ! -h $DIR/d26-3 ] && test_26d
1461         rm $DIR/d26-3
1462 }
1463 run_test 26e "unlink multiple component recursive symlink"
1464
1465 # recursive symlinks (bug 7022)
1466 test_26f() {
1467         test_mkdir $DIR/$tdir
1468         test_mkdir $DIR/$tdir/$tfile
1469         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1470         test_mkdir -p lndir/bar1
1471         test_mkdir $DIR/$tdir/$tfile/$tfile
1472         cd $tfile                || error "cd $tfile failed"
1473         ln -s .. dotdot          || error "ln dotdot failed"
1474         ln -s dotdot/lndir lndir || error "ln lndir failed"
1475         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1476         output=`ls $tfile/$tfile/lndir/bar1`
1477         [ "$output" = bar1 ] && error "unexpected output"
1478         rm -r $tfile             || error "rm $tfile failed"
1479         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1480 }
1481 run_test 26f "rm -r of a directory which has recursive symlink"
1482
1483 test_27a() {
1484         test_mkdir $DIR/$tdir
1485         $LFS getstripe $DIR/$tdir
1486         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1487         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1488         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1489 }
1490 run_test 27a "one stripe file"
1491
1492 test_27b() {
1493         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1494
1495         test_mkdir $DIR/$tdir
1496         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1497         $LFS getstripe -c $DIR/$tdir/$tfile
1498         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1499                 error "two-stripe file doesn't have two stripes"
1500
1501         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1502 }
1503 run_test 27b "create and write to two stripe file"
1504
1505 test_27d() {
1506         test_mkdir $DIR/$tdir
1507         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1508                 error "setstripe failed"
1509         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1511 }
1512 run_test 27d "create file with default settings"
1513
1514 test_27e() {
1515         # LU-5839 adds check for existed layout before setting it
1516         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1517                 skip "Need MDS version at least 2.7.56"
1518
1519         test_mkdir $DIR/$tdir
1520         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1522         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1523 }
1524 run_test 27e "setstripe existing file (should return error)"
1525
1526 test_27f() {
1527         test_mkdir $DIR/$tdir
1528         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1529                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1530         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1531                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1532         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1533         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1534 }
1535 run_test 27f "setstripe with bad stripe size (should return error)"
1536
1537 test_27g() {
1538         test_mkdir $DIR/$tdir
1539         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1541                 error "$DIR/$tdir/$tfile has object"
1542 }
1543 run_test 27g "$LFS getstripe with no objects"
1544
1545 test_27i() {
1546         test_mkdir $DIR/$tdir
1547         touch $DIR/$tdir/$tfile || error "touch failed"
1548         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1549                 error "missing objects"
1550 }
1551 run_test 27i "$LFS getstripe with some objects"
1552
1553 test_27j() {
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1556                 error "setstripe failed" || true
1557 }
1558 run_test 27j "setstripe with bad stripe offset (should return error)"
1559
1560 test_27k() { # bug 2844
1561         test_mkdir $DIR/$tdir
1562         local file=$DIR/$tdir/$tfile
1563         local ll_max_blksize=$((4 * 1024 * 1024))
1564         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1565         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1566         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1567         dd if=/dev/zero of=$file bs=4k count=1
1568         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1569         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1570 }
1571 run_test 27k "limit i_blksize for broken user apps"
1572
1573 test_27l() {
1574         mcreate $DIR/$tfile || error "creating file"
1575         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1576                 error "setstripe should have failed" || true
1577 }
1578 run_test 27l "check setstripe permissions (should return error)"
1579
1580 test_27m() {
1581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1582
1583         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1584                    head -n1)
1585         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1586                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1587         fi
1588         trap simple_cleanup_common EXIT
1589         test_mkdir $DIR/$tdir
1590         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1592                 error "dd should fill OST0"
1593         i=2
1594         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1595                 i=$((i + 1))
1596                 [ $i -gt 256 ] && break
1597         done
1598         i=$((i + 1))
1599         touch $DIR/$tdir/$tfile.$i
1600         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1601             awk '{print $1}'| grep -w "0") ] &&
1602                 error "OST0 was full but new created file still use it"
1603         i=$((i + 1))
1604         touch $DIR/$tdir/$tfile.$i
1605         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1606             awk '{print $1}'| grep -w "0") ] &&
1607                 error "OST0 was full but new created file still use it"
1608         simple_cleanup_common
1609 }
1610 run_test 27m "create file while OST0 was full"
1611
1612 sleep_maxage() {
1613         local delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1614                       awk '{ print $1 * 2; exit; }')
1615         sleep $delay
1616 }
1617
1618 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1619 # if the OST isn't full anymore.
1620 reset_enospc() {
1621         local OSTIDX=${1:-""}
1622
1623         local list=$(comma_list $(osts_nodes))
1624         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1625
1626         do_nodes $list lctl set_param fail_loc=0
1627         sync    # initiate all OST_DESTROYs from MDS to OST
1628         sleep_maxage
1629 }
1630
1631 exhaust_precreations() {
1632         local OSTIDX=$1
1633         local FAILLOC=$2
1634         local FAILIDX=${3:-$OSTIDX}
1635         local ofacet=ost$((OSTIDX + 1))
1636
1637         test_mkdir -p -c1 $DIR/$tdir
1638         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1639         local mfacet=mds$((mdtidx + 1))
1640         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1641
1642         local OST=$(ostname_from_index $OSTIDX)
1643
1644         # on the mdt's osc
1645         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1646         local last_id=$(do_facet $mfacet lctl get_param -n \
1647                         osc.$mdtosc_proc1.prealloc_last_id)
1648         local next_id=$(do_facet $mfacet lctl get_param -n \
1649                         osc.$mdtosc_proc1.prealloc_next_id)
1650
1651         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1652         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1653
1654         test_mkdir -p $DIR/$tdir/${OST}
1655         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1656 #define OBD_FAIL_OST_ENOSPC              0x215
1657         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1658         echo "Creating to objid $last_id on ost $OST..."
1659         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1660         do_facet $mfacet lctl get_param osc.$mdtosc_proc2.prealloc*
1661         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1662         sleep_maxage
1663 }
1664
1665 exhaust_all_precreations() {
1666         local i
1667         for (( i=0; i < OSTCOUNT; i++ )) ; do
1668                 exhaust_precreations $i $1 -1
1669         done
1670 }
1671
1672 test_27n() {
1673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1675         remote_mds_nodsh && skip "remote MDS with nodsh"
1676         remote_ost_nodsh && skip "remote OST with nodsh"
1677
1678         reset_enospc
1679         rm -f $DIR/$tdir/$tfile
1680         exhaust_precreations 0 0x80000215
1681         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1682         touch $DIR/$tdir/$tfile || error "touch failed"
1683         $LFS getstripe $DIR/$tdir/$tfile
1684         reset_enospc
1685 }
1686 run_test 27n "create file with some full OSTs"
1687
1688 test_27o() {
1689         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1691         remote_mds_nodsh && skip "remote MDS with nodsh"
1692         remote_ost_nodsh && skip "remote OST with nodsh"
1693
1694         reset_enospc
1695         rm -f $DIR/$tdir/$tfile
1696         exhaust_all_precreations 0x215
1697
1698         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1699
1700         reset_enospc
1701         rm -rf $DIR/$tdir/*
1702 }
1703 run_test 27o "create file with all full OSTs (should error)"
1704
1705 test_27p() {
1706         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1708         remote_mds_nodsh && skip "remote MDS with nodsh"
1709         remote_ost_nodsh && skip "remote OST with nodsh"
1710
1711         reset_enospc
1712         rm -f $DIR/$tdir/$tfile
1713         test_mkdir $DIR/$tdir
1714
1715         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1716         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1717         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1718
1719         exhaust_precreations 0 0x80000215
1720         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1721         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1722         $LFS getstripe $DIR/$tdir/$tfile
1723
1724         reset_enospc
1725 }
1726 run_test 27p "append to a truncated file with some full OSTs"
1727
1728 test_27q() {
1729         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1731         remote_mds_nodsh && skip "remote MDS with nodsh"
1732         remote_ost_nodsh && skip "remote OST with nodsh"
1733
1734         reset_enospc
1735         rm -f $DIR/$tdir/$tfile
1736
1737         test_mkdir $DIR/$tdir
1738         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1739         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1740                 error "truncate $DIR/$tdir/$tfile failed"
1741         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1742
1743         exhaust_all_precreations 0x215
1744
1745         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1746         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1747
1748         reset_enospc
1749 }
1750 run_test 27q "append to truncated file with all OSTs full (should error)"
1751
1752 test_27r() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1755         remote_mds_nodsh && skip "remote MDS with nodsh"
1756         remote_ost_nodsh && skip "remote OST with nodsh"
1757
1758         reset_enospc
1759         rm -f $DIR/$tdir/$tfile
1760         exhaust_precreations 0 0x80000215
1761
1762         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1763
1764         reset_enospc
1765 }
1766 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1767
1768 test_27s() { # bug 10725
1769         test_mkdir $DIR/$tdir
1770         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1771         local stripe_count=0
1772         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1773         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1774                 error "stripe width >= 2^32 succeeded" || true
1775
1776 }
1777 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1778
1779 test_27t() { # bug 10864
1780         WDIR=$(pwd)
1781         WLFS=$(which lfs)
1782         cd $DIR
1783         touch $tfile
1784         $WLFS getstripe $tfile
1785         cd $WDIR
1786 }
1787 run_test 27t "check that utils parse path correctly"
1788
1789 test_27u() { # bug 4900
1790         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1791         remote_mds_nodsh && skip "remote MDS with nodsh"
1792
1793         local index
1794         local list=$(comma_list $(mdts_nodes))
1795
1796 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1797         do_nodes $list $LCTL set_param fail_loc=0x139
1798         test_mkdir -p $DIR/$tdir
1799         trap simple_cleanup_common EXIT
1800         createmany -o $DIR/$tdir/t- 1000
1801         do_nodes $list $LCTL set_param fail_loc=0
1802
1803         TLOG=$TMP/$tfile.getstripe
1804         $LFS getstripe $DIR/$tdir > $TLOG
1805         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1806         unlinkmany $DIR/$tdir/t- 1000
1807         trap 0
1808         [[ $OBJS -gt 0 ]] &&
1809                 error "$OBJS objects created on OST-0. See $TLOG" ||
1810                 rm -f $TLOG
1811 }
1812 run_test 27u "skip object creation on OSC w/o objects"
1813
1814 test_27v() { # bug 4900
1815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1817         remote_mds_nodsh && skip "remote MDS with nodsh"
1818         remote_ost_nodsh && skip "remote OST with nodsh"
1819
1820         exhaust_all_precreations 0x215
1821         reset_enospc
1822
1823         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1824
1825         touch $DIR/$tdir/$tfile
1826         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1827         # all except ost1
1828         for (( i=1; i < OSTCOUNT; i++ )); do
1829                 do_facet ost$i lctl set_param fail_loc=0x705
1830         done
1831         local START=`date +%s`
1832         createmany -o $DIR/$tdir/$tfile 32
1833
1834         local FINISH=`date +%s`
1835         local TIMEOUT=`lctl get_param -n timeout`
1836         local PROCESS=$((FINISH - START))
1837         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1838                error "$FINISH - $START >= $TIMEOUT / 2"
1839         sleep $((TIMEOUT / 2 - PROCESS))
1840         reset_enospc
1841 }
1842 run_test 27v "skip object creation on slow OST"
1843
1844 test_27w() { # bug 10997
1845         test_mkdir $DIR/$tdir
1846         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1847         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1848                 error "stripe size $size != 65536" || true
1849         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1850                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1851 }
1852 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1853
1854 test_27wa() {
1855         [[ $OSTCOUNT -lt 2 ]] &&
1856                 skip_env "skipping multiple stripe count/offset test"
1857
1858         test_mkdir $DIR/$tdir
1859         for i in $(seq 1 $OSTCOUNT); do
1860                 offset=$((i - 1))
1861                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1862                         error "setstripe -c $i -i $offset failed"
1863                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1864                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1865                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1866                 [ $index -ne $offset ] &&
1867                         error "stripe offset $index != $offset" || true
1868         done
1869 }
1870 run_test 27wa "check $LFS setstripe -c -i options"
1871
1872 test_27x() {
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1876
1877         OFFSET=$(($OSTCOUNT - 1))
1878         OSTIDX=0
1879         local OST=$(ostname_from_index $OSTIDX)
1880
1881         test_mkdir $DIR/$tdir
1882         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
1883         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
1884         sleep_maxage
1885         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
1886         for i in $(seq 0 $OFFSET); do
1887                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
1888                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
1889                 error "OST0 was degraded but new created file still use it"
1890         done
1891         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
1892 }
1893 run_test 27x "create files while OST0 is degraded"
1894
1895 test_27y() {
1896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1900
1901         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
1902         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
1903                 osc.$mdtosc.prealloc_last_id)
1904         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
1905                 osc.$mdtosc.prealloc_next_id)
1906         local fcount=$((last_id - next_id))
1907         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
1908         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
1909
1910         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
1911                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
1912         local OST_DEACTIVE_IDX=-1
1913         local OSC
1914         local OSTIDX
1915         local OST
1916
1917         for OSC in $MDS_OSCS; do
1918                 OST=$(osc_to_ost $OSC)
1919                 OSTIDX=$(index_from_ostuuid $OST)
1920                 if [ $OST_DEACTIVE_IDX == -1 ]; then
1921                         OST_DEACTIVE_IDX=$OSTIDX
1922                 fi
1923                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
1924                         echo $OSC "is Deactivated:"
1925                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
1926                 fi
1927         done
1928
1929         OSTIDX=$(index_from_ostuuid $OST)
1930         test_mkdir $DIR/$tdir
1931         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
1932
1933         for OSC in $MDS_OSCS; do
1934                 OST=$(osc_to_ost $OSC)
1935                 OSTIDX=$(index_from_ostuuid $OST)
1936                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1937                         echo $OST "is degraded:"
1938                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1939                                                 obdfilter.$OST.degraded=1
1940                 fi
1941         done
1942
1943         sleep_maxage
1944         createmany -o $DIR/$tdir/$tfile $fcount
1945
1946         for OSC in $MDS_OSCS; do
1947                 OST=$(osc_to_ost $OSC)
1948                 OSTIDX=$(index_from_ostuuid $OST)
1949                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
1950                         echo $OST "is recovered from degraded:"
1951                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
1952                                                 obdfilter.$OST.degraded=0
1953                 else
1954                         do_facet $SINGLEMDS lctl --device %$OSC activate
1955                 fi
1956         done
1957
1958         # all osp devices get activated, hence -1 stripe count restored
1959         local stripe_count=0
1960
1961         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
1962         # devices get activated.
1963         sleep_maxage
1964         $LFS setstripe -c -1 $DIR/$tfile
1965         stripe_count=$($LFS getstripe -c $DIR/$tfile)
1966         rm -f $DIR/$tfile
1967         [ $stripe_count -ne $OSTCOUNT ] &&
1968                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
1969         return 0
1970 }
1971 run_test 27y "create files while OST0 is degraded and the rest inactive"
1972
1973 check_seq_oid()
1974 {
1975         log "check file $1"
1976
1977         lmm_count=$($LFS getstripe -c $1)
1978         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
1979         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
1980
1981         local old_ifs="$IFS"
1982         IFS=$'[:]'
1983         fid=($($LFS path2fid $1))
1984         IFS="$old_ifs"
1985
1986         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
1987         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
1988
1989         # compare lmm_seq and lu_fid->f_seq
1990         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
1991         # compare lmm_object_id and lu_fid->oid
1992         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
1993
1994         # check the trusted.fid attribute of the OST objects of the file
1995         local have_obdidx=false
1996         local stripe_nr=0
1997         $LFS getstripe $1 | while read obdidx oid hex seq; do
1998                 # skip lines up to and including "obdidx"
1999                 [ -z "$obdidx" ] && break
2000                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2001                 $have_obdidx || continue
2002
2003                 local ost=$((obdidx + 1))
2004                 local dev=$(ostdevname $ost)
2005                 local oid_hex
2006
2007                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2008
2009                 seq=$(echo $seq | sed -e "s/^0x//g")
2010                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2011                         oid_hex=$(echo $oid)
2012                 else
2013                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2014                 fi
2015                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2016
2017                 local ff=""
2018                 #
2019                 # Don't unmount/remount the OSTs if we don't need to do that.
2020                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2021                 # update too, until that use mount/ll_decode_filter_fid/mount.
2022                 # Re-enable when debugfs will understand new filter_fid.
2023                 #
2024                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2025                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2026                                 $dev 2>/dev/null" | grep "parent=")
2027                 fi
2028                 if [ -z "$ff" ]; then
2029                         stop ost$ost
2030                         mount_fstype ost$ost
2031                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2032                                 $(facet_mntpt ost$ost)/$obj_file)
2033                         unmount_fstype ost$ost
2034                         start ost$ost $dev $OST_MOUNT_OPTS
2035                         clients_up
2036                 fi
2037
2038                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2039
2040                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2041
2042                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2043                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2044                 #
2045                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2046                 #       stripe_size=1048576 component_id=1 component_start=0 \
2047                 #       component_end=33554432
2048                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2049                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2050                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2051                 local ff_pstripe
2052                 if grep -q 'stripe=' <<<$ff; then
2053                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2054                 else
2055                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2056                         # into f_ver in this case.  See comment on ff_parent.
2057                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2058                 fi
2059
2060                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2061                 [ $ff_pseq = $lmm_seq ] ||
2062                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2063                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2064                 [ $ff_poid = $lmm_oid ] ||
2065                         error "FF parent OID $ff_poid != $lmm_oid"
2066                 (($ff_pstripe == $stripe_nr)) ||
2067                         error "FF stripe $ff_pstripe != $stripe_nr"
2068
2069                 stripe_nr=$((stripe_nr + 1))
2070                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2071                         continue
2072                 if grep -q 'stripe_count=' <<<$ff; then
2073                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2074                                             -e 's/ .*//' <<<$ff)
2075                         [ $lmm_count = $ff_scnt ] ||
2076                                 error "FF stripe count $lmm_count != $ff_scnt"
2077                 fi
2078         done
2079 }
2080
2081 test_27z() {
2082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         test_mkdir $DIR/$tdir
2086         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2087                 { error "setstripe -c -1 failed"; return 1; }
2088         # We need to send a write to every object to get parent FID info set.
2089         # This _should_ also work for setattr, but does not currently.
2090         # touch $DIR/$tdir/$tfile-1 ||
2091         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2092                 { error "dd $tfile-1 failed"; return 2; }
2093         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2094                 { error "setstripe -c -1 failed"; return 3; }
2095         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2096                 { error "dd $tfile-2 failed"; return 4; }
2097
2098         # make sure write RPCs have been sent to OSTs
2099         sync; sleep 5; sync
2100
2101         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2102         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2103 }
2104 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2105
2106 test_27A() { # b=19102
2107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2108
2109         save_layout_restore_at_exit $MOUNT
2110         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2111         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2112                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2113         local default_size=$($LFS getstripe -S $MOUNT)
2114         local default_offset=$($LFS getstripe -i $MOUNT)
2115         local dsize=$(do_facet $SINGLEMDS \
2116                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2117         [ $default_size -eq $dsize ] ||
2118                 error "stripe size $default_size != $dsize"
2119         [ $default_offset -eq -1 ] ||
2120                 error "stripe offset $default_offset != -1"
2121 }
2122 run_test 27A "check filesystem-wide default LOV EA values"
2123
2124 test_27B() { # LU-2523
2125         test_mkdir $DIR/$tdir
2126         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2127         touch $DIR/$tdir/f0
2128         # open f1 with O_LOV_DELAY_CREATE
2129         # rename f0 onto f1
2130         # call setstripe ioctl on open file descriptor for f1
2131         # close
2132         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2133                 $DIR/$tdir/f0
2134
2135         rm -f $DIR/$tdir/f1
2136         # open f1 with O_LOV_DELAY_CREATE
2137         # unlink f1
2138         # call setstripe ioctl on open file descriptor for f1
2139         # close
2140         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2141
2142         # Allow multiop to fail in imitation of NFS's busted semantics.
2143         true
2144 }
2145 run_test 27B "call setstripe on open unlinked file/rename victim"
2146
2147 test_27C() { #LU-2871
2148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2149
2150         declare -a ost_idx
2151         local index
2152         local found
2153         local i
2154         local j
2155
2156         test_mkdir $DIR/$tdir
2157         cd $DIR/$tdir
2158         for i in $(seq 0 $((OSTCOUNT - 1))); do
2159                 # set stripe across all OSTs starting from OST$i
2160                 $LFS setstripe -i $i -c -1 $tfile$i
2161                 # get striping information
2162                 ost_idx=($($LFS getstripe $tfile$i |
2163                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2164                 echo ${ost_idx[@]}
2165
2166                 # check the layout
2167                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2168                         error "${#ost_idx[@]} != $OSTCOUNT"
2169
2170                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2171                         found=0
2172                         for j in $(echo ${ost_idx[@]}); do
2173                                 if [ $index -eq $j ]; then
2174                                         found=1
2175                                         break
2176                                 fi
2177                         done
2178                         [ $found = 1 ] ||
2179                                 error "Can not find $index in ${ost_idx[@]}"
2180                 done
2181         done
2182 }
2183 run_test 27C "check full striping across all OSTs"
2184
2185 test_27D() {
2186         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2187         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2188         remote_mds_nodsh && skip "remote MDS with nodsh"
2189
2190         local POOL=${POOL:-testpool}
2191         local first_ost=0
2192         local last_ost=$(($OSTCOUNT - 1))
2193         local ost_step=1
2194         local ost_list=$(seq $first_ost $ost_step $last_ost)
2195         local ost_range="$first_ost $last_ost $ost_step"
2196
2197         if ! combined_mgs_mds ; then
2198                 mount_mgs_client
2199         fi
2200
2201         test_mkdir $DIR/$tdir
2202         pool_add $POOL || error "pool_add failed"
2203         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2204
2205         local skip27D
2206         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2207                 skip27D+="-s 29"
2208         [ $MDS1_VERSION -lt $(version_code 2.9.55) -o \
2209           $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2210                 skip27D+=" -s 30,31"
2211         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2212                 error "llapi_layout_test failed"
2213
2214         destroy_test_pools || error "destroy test pools failed"
2215
2216         if ! combined_mgs_mds ; then
2217                 umount_mgs_client
2218         fi
2219 }
2220 run_test 27D "validate llapi_layout API"
2221
2222 # Verify that default_easize is increased from its initial value after
2223 # accessing a widely striped file.
2224 test_27E() {
2225         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2226         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2227                 skip "client does not have LU-3338 fix"
2228
2229         # 72 bytes is the minimum space required to store striping
2230         # information for a file striped across one OST:
2231         # (sizeof(struct lov_user_md_v3) +
2232         #  sizeof(struct lov_user_ost_data_v1))
2233         local min_easize=72
2234         $LCTL set_param -n llite.*.default_easize $min_easize ||
2235                 error "lctl set_param failed"
2236         local easize=$($LCTL get_param -n llite.*.default_easize)
2237
2238         [ $easize -eq $min_easize ] ||
2239                 error "failed to set default_easize"
2240
2241         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2242                 error "setstripe failed"
2243         cat $DIR/$tfile
2244         rm $DIR/$tfile
2245
2246         easize=$($LCTL get_param -n llite.*.default_easize)
2247
2248         [ $easize -gt $min_easize ] ||
2249                 error "default_easize not updated"
2250 }
2251 run_test 27E "check that default extended attribute size properly increases"
2252
2253 test_27F() { # LU-5346/LU-7975
2254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2255         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2256         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2257                 skip "Need MDS version at least 2.8.51"
2258         remote_ost_nodsh && skip "remote OST with nodsh"
2259
2260         test_mkdir $DIR/$tdir
2261         rm -f $DIR/$tdir/f0
2262         $LFS setstripe -c 2 $DIR/$tdir
2263
2264         # stop all OSTs to reproduce situation for LU-7975 ticket
2265         for num in $(seq $OSTCOUNT); do
2266                 stop ost$num
2267         done
2268
2269         # open/create f0 with O_LOV_DELAY_CREATE
2270         # truncate f0 to a non-0 size
2271         # close
2272         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2273
2274         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2275         # open/write it again to force delayed layout creation
2276         cat /etc/hosts > $DIR/$tdir/f0 &
2277         catpid=$!
2278
2279         # restart OSTs
2280         for num in $(seq $OSTCOUNT); do
2281                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2282                         error "ost$num failed to start"
2283         done
2284
2285         wait $catpid || error "cat failed"
2286
2287         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2288         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2289                 error "wrong stripecount"
2290
2291 }
2292 run_test 27F "Client resend delayed layout creation with non-zero size"
2293
2294 test_27G() { #LU-10629
2295         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2296                 skip "Need MDS version at least 2.11.51"
2297         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2298         remote_mds_nodsh && skip "remote MDS with nodsh"
2299         local POOL=${POOL:-testpool}
2300         local ostrange="0 0 1"
2301
2302         test_mkdir $DIR/$tdir
2303         pool_add $POOL || error "pool_add failed"
2304         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2305         $LFS setstripe -p $POOL $DIR/$tdir
2306
2307         local pool=$($LFS getstripe -p $DIR/$tdir)
2308
2309         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2310
2311         $LFS setstripe -d $DIR/$tdir
2312
2313         pool=$($LFS getstripe -p $DIR/$tdir)
2314
2315         rmdir $DIR/$tdir
2316
2317         [ -z "$pool" ] || error "'$pool' is not empty"
2318 }
2319 run_test 27G "Clear OST pool from stripe"
2320
2321 test_27H() {
2322         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2323                 skip "Need MDS version newer than 2.11.54"
2324         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2325         test_mkdir $DIR/$tdir
2326         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2327         touch $DIR/$tdir/$tfile
2328         $LFS getstripe -c $DIR/$tdir/$tfile
2329         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2330                 error "two-stripe file doesn't have two stripes"
2331
2332         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2333         $LFS getstripe -y $DIR/$tdir/$tfile
2334         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2335              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2336                 error "expected l_ost_idx: [02]$ not matched"
2337
2338         # make sure ost list has been cleared
2339         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2340         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2341                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2342         touch $DIR/$tdir/f3
2343         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2344 }
2345 run_test 27H "Set specific OSTs stripe"
2346
2347 # createtest also checks that device nodes are created and
2348 # then visible correctly (#2091)
2349 test_28() { # bug 2091
2350         test_mkdir $DIR/d28
2351         $CREATETEST $DIR/d28/ct || error "createtest failed"
2352 }
2353 run_test 28 "create/mknod/mkdir with bad file types ============"
2354
2355 test_29() {
2356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2357
2358         sync; sleep 1; sync # flush out any dirty pages from previous tests
2359         cancel_lru_locks
2360         test_mkdir $DIR/d29
2361         touch $DIR/d29/foo
2362         log 'first d29'
2363         ls -l $DIR/d29
2364
2365         declare -i LOCKCOUNTORIG=0
2366         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2367                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2368         done
2369         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2370
2371         declare -i LOCKUNUSEDCOUNTORIG=0
2372         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2373                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2374         done
2375
2376         log 'second d29'
2377         ls -l $DIR/d29
2378         log 'done'
2379
2380         declare -i LOCKCOUNTCURRENT=0
2381         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2382                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2383         done
2384
2385         declare -i LOCKUNUSEDCOUNTCURRENT=0
2386         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2387                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2388         done
2389
2390         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2391                 $LCTL set_param -n ldlm.dump_namespaces ""
2392                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2393                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2394                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2395                 return 2
2396         fi
2397         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2398                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2399                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2400                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2401                 return 3
2402         fi
2403 }
2404 run_test 29 "IT_GETATTR regression  ============================"
2405
2406 test_30a() { # was test_30
2407         cp $(which ls) $DIR || cp /bin/ls $DIR
2408         $DIR/ls / || error "Can't execute binary from lustre"
2409         rm $DIR/ls
2410 }
2411 run_test 30a "execute binary from Lustre (execve) =============="
2412
2413 test_30b() {
2414         cp `which ls` $DIR || cp /bin/ls $DIR
2415         chmod go+rx $DIR/ls
2416         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2417         rm $DIR/ls
2418 }
2419 run_test 30b "execute binary from Lustre as non-root ==========="
2420
2421 test_30c() { # b=22376
2422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2423
2424         cp `which ls` $DIR || cp /bin/ls $DIR
2425         chmod a-rw $DIR/ls
2426         cancel_lru_locks mdc
2427         cancel_lru_locks osc
2428         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2429         rm -f $DIR/ls
2430 }
2431 run_test 30c "execute binary from Lustre without read perms ===="
2432
2433 test_31a() {
2434         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2435         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2436 }
2437 run_test 31a "open-unlink file =================================="
2438
2439 test_31b() {
2440         touch $DIR/f31 || error "touch $DIR/f31 failed"
2441         ln $DIR/f31 $DIR/f31b || error "ln failed"
2442         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2443         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2444 }
2445 run_test 31b "unlink file with multiple links while open ======="
2446
2447 test_31c() {
2448         touch $DIR/f31 || error "touch $DIR/f31 failed"
2449         ln $DIR/f31 $DIR/f31c || error "ln failed"
2450         multiop_bg_pause $DIR/f31 O_uc ||
2451                 error "multiop_bg_pause for $DIR/f31 failed"
2452         MULTIPID=$!
2453         $MULTIOP $DIR/f31c Ouc
2454         kill -USR1 $MULTIPID
2455         wait $MULTIPID
2456 }
2457 run_test 31c "open-unlink file with multiple links ============="
2458
2459 test_31d() {
2460         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2461         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2462 }
2463 run_test 31d "remove of open directory ========================="
2464
2465 test_31e() { # bug 2904
2466         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2467 }
2468 run_test 31e "remove of open non-empty directory ==============="
2469
2470 test_31f() { # bug 4554
2471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2472
2473         set -vx
2474         test_mkdir $DIR/d31f
2475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2476         cp /etc/hosts $DIR/d31f
2477         ls -l $DIR/d31f
2478         $LFS getstripe $DIR/d31f/hosts
2479         multiop_bg_pause $DIR/d31f D_c || return 1
2480         MULTIPID=$!
2481
2482         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2483         test_mkdir $DIR/d31f
2484         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2485         cp /etc/hosts $DIR/d31f
2486         ls -l $DIR/d31f
2487         $LFS getstripe $DIR/d31f/hosts
2488         multiop_bg_pause $DIR/d31f D_c || return 1
2489         MULTIPID2=$!
2490
2491         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2492         wait $MULTIPID || error "first opendir $MULTIPID failed"
2493
2494         sleep 6
2495
2496         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2497         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2498         set +vx
2499 }
2500 run_test 31f "remove of open directory with open-unlink file ==="
2501
2502 test_31g() {
2503         echo "-- cross directory link --"
2504         test_mkdir -c1 $DIR/${tdir}ga
2505         test_mkdir -c1 $DIR/${tdir}gb
2506         touch $DIR/${tdir}ga/f
2507         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2508         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2509         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2510         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2511         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2512 }
2513 run_test 31g "cross directory link==============="
2514
2515 test_31h() {
2516         echo "-- cross directory link --"
2517         test_mkdir -c1 $DIR/${tdir}
2518         test_mkdir -c1 $DIR/${tdir}/dir
2519         touch $DIR/${tdir}/f
2520         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2521         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2522         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2523         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2524         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2525 }
2526 run_test 31h "cross directory link under child==============="
2527
2528 test_31i() {
2529         echo "-- cross directory link --"
2530         test_mkdir -c1 $DIR/$tdir
2531         test_mkdir -c1 $DIR/$tdir/dir
2532         touch $DIR/$tdir/dir/f
2533         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2534         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2535         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
2536         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
2537         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
2538 }
2539 run_test 31i "cross directory link under parent==============="
2540
2541 test_31j() {
2542         test_mkdir -c1 -p $DIR/$tdir
2543         test_mkdir -c1 -p $DIR/$tdir/dir1
2544         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
2545         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
2546         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
2547         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
2548         return 0
2549 }
2550 run_test 31j "link for directory==============="
2551
2552 test_31k() {
2553         test_mkdir -c1 -p $DIR/$tdir
2554         touch $DIR/$tdir/s
2555         touch $DIR/$tdir/exist
2556         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
2557         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
2558         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
2559         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
2560         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
2561         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
2562         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
2563         return 0
2564 }
2565 run_test 31k "link to file: the same, non-existing, dir==============="
2566
2567 test_31m() {
2568         mkdir $DIR/d31m
2569         touch $DIR/d31m/s
2570         mkdir $DIR/d31m2
2571         touch $DIR/d31m2/exist
2572         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
2573         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
2574         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
2575         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
2576         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
2577         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
2578         return 0
2579 }
2580 run_test 31m "link to file: the same, non-existing, dir==============="
2581
2582 test_31n() {
2583         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
2584         nlink=$(stat --format=%h $DIR/$tfile)
2585         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2586         local fd=$(free_fd)
2587         local cmd="exec $fd<$DIR/$tfile"
2588         eval $cmd
2589         cmd="exec $fd<&-"
2590         trap "eval $cmd" EXIT
2591         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2592         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
2593         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
2594         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
2595         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
2596         eval $cmd
2597 }
2598 run_test 31n "check link count of unlinked file"
2599
2600 link_one() {
2601         local TEMPNAME=$(mktemp $1_XXXXXX)
2602         mlink $TEMPNAME $1 2> /dev/null &&
2603                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
2604         munlink $TEMPNAME
2605 }
2606
2607 test_31o() { # LU-2901
2608         test_mkdir $DIR/$tdir
2609         for LOOP in $(seq 100); do
2610                 rm -f $DIR/$tdir/$tfile*
2611                 for THREAD in $(seq 8); do
2612                         link_one $DIR/$tdir/$tfile.$LOOP &
2613                 done
2614                 wait
2615                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
2616                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
2617                         error "$LINKS duplicate links to $tfile.$LOOP" &&
2618                         break || true
2619         done
2620 }
2621 run_test 31o "duplicate hard links with same filename"
2622
2623 test_31p() {
2624         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
2625
2626         test_mkdir $DIR/$tdir
2627         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
2628         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
2629
2630         opendirunlink $DIR/$tdir/striped_dir/test1 ||
2631                 error "open unlink test1 failed"
2632         opendirunlink $DIR/$tdir/striped_dir/test2 ||
2633                 error "open unlink test2 failed"
2634
2635         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
2636                 error "test1 still exists"
2637         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
2638                 error "test2 still exists"
2639 }
2640 run_test 31p "remove of open striped directory"
2641
2642 cleanup_test32_mount() {
2643         local rc=0
2644         trap 0
2645         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
2646         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
2647         losetup -d $loopdev || true
2648         rm -rf $DIR/$tdir
2649         return $rc
2650 }
2651
2652 test_32a() {
2653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2654
2655         echo "== more mountpoints and symlinks ================="
2656         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2657         trap cleanup_test32_mount EXIT
2658         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2659         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2660                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2661         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
2662                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
2663         cleanup_test32_mount
2664 }
2665 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
2666
2667 test_32b() {
2668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2669
2670         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2671         trap cleanup_test32_mount EXIT
2672         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2673         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2674                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2675         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
2676                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
2677         cleanup_test32_mount
2678 }
2679 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
2680
2681 test_32c() {
2682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2683
2684         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2685         trap cleanup_test32_mount EXIT
2686         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2687         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2688                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2689         test_mkdir -p $DIR/$tdir/d2/test_dir
2690         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2691                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
2692         cleanup_test32_mount
2693 }
2694 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
2695
2696 test_32d() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698
2699         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2700         trap cleanup_test32_mount EXIT
2701         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2702         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2703                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2704         test_mkdir -p $DIR/$tdir/d2/test_dir
2705         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
2706                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
2707         cleanup_test32_mount
2708 }
2709 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
2710
2711 test_32e() {
2712         rm -fr $DIR/$tdir
2713         test_mkdir -p $DIR/$tdir/tmp
2714         local tmp_dir=$DIR/$tdir/tmp
2715         ln -s $DIR/$tdir $tmp_dir/symlink11
2716         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2717         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
2718         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
2719 }
2720 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
2721
2722 test_32f() {
2723         rm -fr $DIR/$tdir
2724         test_mkdir -p $DIR/$tdir/tmp
2725         local tmp_dir=$DIR/$tdir/tmp
2726         ln -s $DIR/$tdir $tmp_dir/symlink11
2727         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
2728         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
2729         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
2730 }
2731 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
2732
2733 test_32g() {
2734         local tmp_dir=$DIR/$tdir/tmp
2735         test_mkdir -p $tmp_dir
2736         test_mkdir $DIR/${tdir}2
2737         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2738         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2739         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
2740         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
2741         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
2742         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
2743 }
2744 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2745
2746 test_32h() {
2747         rm -fr $DIR/$tdir $DIR/${tdir}2
2748         tmp_dir=$DIR/$tdir/tmp
2749         test_mkdir -p $tmp_dir
2750         test_mkdir $DIR/${tdir}2
2751         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
2752         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
2753         ls $tmp_dir/symlink12 || error "listing symlink12"
2754         ls $DIR/$tdir/symlink02  || error "listing symlink02"
2755 }
2756 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
2757
2758 test_32i() {
2759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2760
2761         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2762         trap cleanup_test32_mount EXIT
2763         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2764         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2765                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2766         touch $DIR/$tdir/test_file
2767         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
2768                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
2769         cleanup_test32_mount
2770 }
2771 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
2772
2773 test_32j() {
2774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2775
2776         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2777         trap cleanup_test32_mount EXIT
2778         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2779         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2780                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2781         touch $DIR/$tdir/test_file
2782         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
2783                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
2784         cleanup_test32_mount
2785 }
2786 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
2787
2788 test_32k() {
2789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2790
2791         rm -fr $DIR/$tdir
2792         trap cleanup_test32_mount EXIT
2793         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2794         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2795                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2796         test_mkdir -p $DIR/$tdir/d2
2797         touch $DIR/$tdir/d2/test_file || error "touch failed"
2798         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2799                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
2800         cleanup_test32_mount
2801 }
2802 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
2803
2804 test_32l() {
2805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2806
2807         rm -fr $DIR/$tdir
2808         trap cleanup_test32_mount EXIT
2809         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2810         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2811                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2812         test_mkdir -p $DIR/$tdir/d2
2813         touch $DIR/$tdir/d2/test_file || error "touch failed"
2814         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
2815                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
2816         cleanup_test32_mount
2817 }
2818 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
2819
2820 test_32m() {
2821         rm -fr $DIR/d32m
2822         test_mkdir -p $DIR/d32m/tmp
2823         TMP_DIR=$DIR/d32m/tmp
2824         ln -s $DIR $TMP_DIR/symlink11
2825         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2826         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
2827                 error "symlink11 not a link"
2828         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
2829                 error "symlink01 not a link"
2830 }
2831 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
2832
2833 test_32n() {
2834         rm -fr $DIR/d32n
2835         test_mkdir -p $DIR/d32n/tmp
2836         TMP_DIR=$DIR/d32n/tmp
2837         ln -s $DIR $TMP_DIR/symlink11
2838         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
2839         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
2840         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
2841 }
2842 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
2843
2844 test_32o() {
2845         touch $DIR/$tfile
2846         test_mkdir -p $DIR/d32o/tmp
2847         TMP_DIR=$DIR/d32o/tmp
2848         ln -s $DIR/$tfile $TMP_DIR/symlink12
2849         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2850         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
2851                 error "symlink12 not a link"
2852         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
2853         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
2854                 error "$DIR/d32o/tmp/symlink12 not file type"
2855         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
2856                 error "$DIR/d32o/symlink02 not file type"
2857 }
2858 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
2859
2860 test_32p() {
2861         log 32p_1
2862         rm -fr $DIR/d32p
2863         log 32p_2
2864         rm -f $DIR/$tfile
2865         log 32p_3
2866         touch $DIR/$tfile
2867         log 32p_4
2868         test_mkdir -p $DIR/d32p/tmp
2869         log 32p_5
2870         TMP_DIR=$DIR/d32p/tmp
2871         log 32p_6
2872         ln -s $DIR/$tfile $TMP_DIR/symlink12
2873         log 32p_7
2874         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
2875         log 32p_8
2876         cat $DIR/d32p/tmp/symlink12 ||
2877                 error "Can't open $DIR/d32p/tmp/symlink12"
2878         log 32p_9
2879         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
2880         log 32p_10
2881 }
2882 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
2883
2884 test_32q() {
2885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2886
2887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2888         trap cleanup_test32_mount EXIT
2889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2890         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2893         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
2894         cleanup_test32_mount
2895 }
2896 run_test 32q "stat follows mountpoints in Lustre (should return error)"
2897
2898 test_32r() {
2899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2900
2901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
2902         trap cleanup_test32_mount EXIT
2903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
2904         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
2905         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
2906                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
2907         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
2908         cleanup_test32_mount
2909 }
2910 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
2911
2912 test_33aa() {
2913         rm -f $DIR/$tfile
2914         touch $DIR/$tfile
2915         chmod 444 $DIR/$tfile
2916         chown $RUNAS_ID $DIR/$tfile
2917         log 33_1
2918         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
2919         log 33_2
2920 }
2921 run_test 33aa "write file with mode 444 (should return error)"
2922
2923 test_33a() {
2924         rm -fr $DIR/$tdir
2925         test_mkdir $DIR/$tdir
2926         chown $RUNAS_ID $DIR/$tdir
2927         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
2928                 error "$RUNAS create $tdir/$tfile failed"
2929         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
2930                 error "open RDWR" || true
2931 }
2932 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
2933
2934 test_33b() {
2935         rm -fr $DIR/$tdir
2936         test_mkdir $DIR/$tdir
2937         chown $RUNAS_ID $DIR/$tdir
2938         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
2939 }
2940 run_test 33b "test open file with malformed flags (No panic)"
2941
2942 test_33c() {
2943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2944         remote_ost_nodsh && skip "remote OST with nodsh"
2945
2946         local ostnum
2947         local ostname
2948         local write_bytes
2949         local all_zeros
2950
2951         all_zeros=:
2952         rm -fr $DIR/$tdir
2953         test_mkdir $DIR/$tdir
2954         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
2955
2956         sync
2957         for ostnum in $(seq $OSTCOUNT); do
2958                 # test-framework's OST numbering is one-based, while Lustre's
2959                 # is zero-based
2960                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2961                 # Parsing llobdstat's output sucks; we could grep the /proc
2962                 # path, but that's likely to not be as portable as using the
2963                 # llobdstat utility.  So we parse lctl output instead.
2964                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2965                         obdfilter/$ostname/stats |
2966                         awk '/^write_bytes/ {print $7}' )
2967                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
2968                 if (( ${write_bytes:-0} > 0 ))
2969                 then
2970                         all_zeros=false
2971                         break;
2972                 fi
2973         done
2974
2975         $all_zeros || return 0
2976
2977         # Write four bytes
2978         echo foo > $DIR/$tdir/bar
2979         # Really write them
2980         sync
2981
2982         # Total up write_bytes after writing.  We'd better find non-zeros.
2983         for ostnum in $(seq $OSTCOUNT); do
2984                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
2985                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
2986                         obdfilter/$ostname/stats |
2987                         awk '/^write_bytes/ {print $7}' )
2988                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
2989                 if (( ${write_bytes:-0} > 0 ))
2990                 then
2991                         all_zeros=false
2992                         break;
2993                 fi
2994         done
2995
2996         if $all_zeros
2997         then
2998                 for ostnum in $(seq $OSTCOUNT); do
2999                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3000                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3001                         do_facet ost$ostnum lctl get_param -n \
3002                                 obdfilter/$ostname/stats
3003                 done
3004                 error "OST not keeping write_bytes stats (b22312)"
3005         fi
3006 }
3007 run_test 33c "test llobdstat and write_bytes"
3008
3009 test_33d() {
3010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3012
3013         local MDTIDX=1
3014         local remote_dir=$DIR/$tdir/remote_dir
3015
3016         test_mkdir $DIR/$tdir
3017         $LFS mkdir -i $MDTIDX $remote_dir ||
3018                 error "create remote directory failed"
3019
3020         touch $remote_dir/$tfile
3021         chmod 444 $remote_dir/$tfile
3022         chown $RUNAS_ID $remote_dir/$tfile
3023
3024         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3025
3026         chown $RUNAS_ID $remote_dir
3027         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3028                                         error "create" || true
3029         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3030                                     error "open RDWR" || true
3031         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3032 }
3033 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3034
3035 test_33e() {
3036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3037
3038         mkdir $DIR/$tdir
3039
3040         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3041         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3042         mkdir $DIR/$tdir/local_dir
3043
3044         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3045         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3046         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3047
3048         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3049                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3050
3051         rmdir $DIR/$tdir/* || error "rmdir failed"
3052
3053         umask 777
3054         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3055         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3056         mkdir $DIR/$tdir/local_dir
3057
3058         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3059         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3060         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3061
3062         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3063                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3064
3065         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3066
3067         umask 000
3068         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3069         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3070         mkdir $DIR/$tdir/local_dir
3071
3072         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3073         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3074         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3075
3076         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3077                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3078 }
3079 run_test 33e "mkdir and striped directory should have same mode"
3080
3081 cleanup_33f() {
3082         trap 0
3083         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3084 }
3085
3086 test_33f() {
3087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3088         remote_mds_nodsh && skip "remote MDS with nodsh"
3089
3090         mkdir $DIR/$tdir
3091         chmod go+rwx $DIR/$tdir
3092         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3093         trap cleanup_33f EXIT
3094
3095         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3096                 error "cannot create striped directory"
3097
3098         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3099                 error "cannot create files in striped directory"
3100
3101         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3102                 error "cannot remove files in striped directory"
3103
3104         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3105                 error "cannot remove striped directory"
3106
3107         cleanup_33f
3108 }
3109 run_test 33f "nonroot user can create, access, and remove a striped directory"
3110
3111 test_33g() {
3112         mkdir -p $DIR/$tdir/dir2
3113
3114         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3115         echo $err
3116         [[ $err =~ "exists" ]] || error "Not exists error"
3117 }
3118 run_test 33g "nonroot user create already existing root created file"
3119
3120 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3121 test_34a() {
3122         rm -f $DIR/f34
3123         $MCREATE $DIR/f34 || error "mcreate failed"
3124         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3125                 error "getstripe failed"
3126         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3127         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3128                 error "getstripe failed"
3129         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3130                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3131 }
3132 run_test 34a "truncate file that has not been opened ==========="
3133
3134 test_34b() {
3135         [ ! -f $DIR/f34 ] && test_34a
3136         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3137                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3138         $OPENFILE -f O_RDONLY $DIR/f34
3139         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3140                 error "getstripe failed"
3141         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3142                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3143 }
3144 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3145
3146 test_34c() {
3147         [ ! -f $DIR/f34 ] && test_34a
3148         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3149                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3150         $OPENFILE -f O_RDWR $DIR/f34
3151         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3152                 error "$LFS getstripe failed"
3153         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3154                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3155 }
3156 run_test 34c "O_RDWR opening file-with-size works =============="
3157
3158 test_34d() {
3159         [ ! -f $DIR/f34 ] && test_34a
3160         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3161                 error "dd failed"
3162         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3163                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3164         rm $DIR/f34
3165 }
3166 run_test 34d "write to sparse file ============================="
3167
3168 test_34e() {
3169         rm -f $DIR/f34e
3170         $MCREATE $DIR/f34e || error "mcreate failed"
3171         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3172         $CHECKSTAT -s 1000 $DIR/f34e ||
3173                 error "Size of $DIR/f34e not equal to 1000 bytes"
3174         $OPENFILE -f O_RDWR $DIR/f34e
3175         $CHECKSTAT -s 1000 $DIR/f34e ||
3176                 error "Size of $DIR/f34e not equal to 1000 bytes"
3177 }
3178 run_test 34e "create objects, some with size and some without =="
3179
3180 test_34f() { # bug 6242, 6243
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         SIZE34F=48000
3184         rm -f $DIR/f34f
3185         $MCREATE $DIR/f34f || error "mcreate failed"
3186         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3187         dd if=$DIR/f34f of=$TMP/f34f
3188         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3189         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3190         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3191         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3192         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3193 }
3194 run_test 34f "read from a file with no objects until EOF ======="
3195
3196 test_34g() {
3197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3198
3199         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3200                 error "dd failed"
3201         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3202         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3203                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3204         cancel_lru_locks osc
3205         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3206                 error "wrong size after lock cancel"
3207
3208         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3209         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3210                 error "expanding truncate failed"
3211         cancel_lru_locks osc
3212         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3213                 error "wrong expanded size after lock cancel"
3214 }
3215 run_test 34g "truncate long file ==============================="
3216
3217 test_34h() {
3218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3219
3220         local gid=10
3221         local sz=1000
3222
3223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3224         sync # Flush the cache so that multiop below does not block on cache
3225              # flush when getting the group lock
3226         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3227         MULTIPID=$!
3228
3229         # Since just timed wait is not good enough, let's do a sync write
3230         # that way we are sure enough time for a roundtrip + processing
3231         # passed + 2 seconds of extra margin.
3232         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3233         rm $DIR/${tfile}-1
3234         sleep 2
3235
3236         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3237                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3238                 kill -9 $MULTIPID
3239         fi
3240         wait $MULTIPID
3241         local nsz=`stat -c %s $DIR/$tfile`
3242         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3243 }
3244 run_test 34h "ftruncate file under grouplock should not block"
3245
3246 test_35a() {
3247         cp /bin/sh $DIR/f35a
3248         chmod 444 $DIR/f35a
3249         chown $RUNAS_ID $DIR/f35a
3250         $RUNAS $DIR/f35a && error || true
3251         rm $DIR/f35a
3252 }
3253 run_test 35a "exec file with mode 444 (should return and not leak)"
3254
3255 test_36a() {
3256         rm -f $DIR/f36
3257         utime $DIR/f36 || error "utime failed for MDS"
3258 }
3259 run_test 36a "MDS utime check (mknod, utime)"
3260
3261 test_36b() {
3262         echo "" > $DIR/f36
3263         utime $DIR/f36 || error "utime failed for OST"
3264 }
3265 run_test 36b "OST utime check (open, utime)"
3266
3267 test_36c() {
3268         rm -f $DIR/d36/f36
3269         test_mkdir $DIR/d36
3270         chown $RUNAS_ID $DIR/d36
3271         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3272 }
3273 run_test 36c "non-root MDS utime check (mknod, utime)"
3274
3275 test_36d() {
3276         [ ! -d $DIR/d36 ] && test_36c
3277         echo "" > $DIR/d36/f36
3278         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3279 }
3280 run_test 36d "non-root OST utime check (open, utime)"
3281
3282 test_36e() {
3283         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3284
3285         test_mkdir $DIR/$tdir
3286         touch $DIR/$tdir/$tfile
3287         $RUNAS utime $DIR/$tdir/$tfile &&
3288                 error "utime worked, expected failure" || true
3289 }
3290 run_test 36e "utime on non-owned file (should return error)"
3291
3292 subr_36fh() {
3293         local fl="$1"
3294         local LANG_SAVE=$LANG
3295         local LC_LANG_SAVE=$LC_LANG
3296         export LANG=C LC_LANG=C # for date language
3297
3298         DATESTR="Dec 20  2000"
3299         test_mkdir $DIR/$tdir
3300         lctl set_param fail_loc=$fl
3301         date; date +%s
3302         cp /etc/hosts $DIR/$tdir/$tfile
3303         sync & # write RPC generated with "current" inode timestamp, but delayed
3304         sleep 1
3305         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3306         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3307         cancel_lru_locks $OSC
3308         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3309         date; date +%s
3310         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3311                 echo "BEFORE: $LS_BEFORE" && \
3312                 echo "AFTER : $LS_AFTER" && \
3313                 echo "WANT  : $DATESTR" && \
3314                 error "$DIR/$tdir/$tfile timestamps changed" || true
3315
3316         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3317 }
3318
3319 test_36f() {
3320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3321
3322         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3323         subr_36fh "0x80000214"
3324 }
3325 run_test 36f "utime on file racing with OST BRW write =========="
3326
3327 test_36g() {
3328         remote_ost_nodsh && skip "remote OST with nodsh"
3329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3330         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3331                 skip "Need MDS version at least 2.12.51"
3332
3333         local fmd_max_age
3334         local fmd
3335         local facet="ost1"
3336         local tgt="obdfilter"
3337
3338         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3339
3340         test_mkdir $DIR/$tdir
3341         fmd_max_age=$(do_facet $facet \
3342                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3343                 head -n 1")
3344
3345         echo "FMD max age: ${fmd_max_age}s"
3346         touch $DIR/$tdir/$tfile
3347         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3348                 gawk '{cnt=cnt+$1}  END{print cnt}')
3349         echo "FMD before: $fmd"
3350         [[ $fmd == 0 ]] &&
3351                 error "FMD wasn't create by touch"
3352         sleep $((fmd_max_age + 12))
3353         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3354                 gawk '{cnt=cnt+$1}  END{print cnt}')
3355         echo "FMD after: $fmd"
3356         [[ $fmd == 0 ]] ||
3357                 error "FMD wasn't expired by ping"
3358 }
3359 run_test 36g "FMD cache expiry ====================="
3360
3361 test_36h() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3365         subr_36fh "0x80000227"
3366 }
3367 run_test 36h "utime on file racing with OST BRW write =========="
3368
3369 test_36i() {
3370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3371
3372         test_mkdir $DIR/$tdir
3373         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3374
3375         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3376         local new_mtime=$((mtime + 200))
3377
3378         #change Modify time of striped dir
3379         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3380                         error "change mtime failed"
3381
3382         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3383
3384         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3385 }
3386 run_test 36i "change mtime on striped directory"
3387
3388 # test_37 - duplicate with tests 32q 32r
3389
3390 test_38() {
3391         local file=$DIR/$tfile
3392         touch $file
3393         openfile -f O_DIRECTORY $file
3394         local RC=$?
3395         local ENOTDIR=20
3396         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3397         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3398 }
3399 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3400
3401 test_39a() { # was test_39
3402         touch $DIR/$tfile
3403         touch $DIR/${tfile}2
3404 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3405 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3406 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3407         sleep 2
3408         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3409         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3410                 echo "mtime"
3411                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3412                 echo "atime"
3413                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3414                 echo "ctime"
3415                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3416                 error "O_TRUNC didn't change timestamps"
3417         fi
3418 }
3419 run_test 39a "mtime changed on create"
3420
3421 test_39b() {
3422         test_mkdir -c1 $DIR/$tdir
3423         cp -p /etc/passwd $DIR/$tdir/fopen
3424         cp -p /etc/passwd $DIR/$tdir/flink
3425         cp -p /etc/passwd $DIR/$tdir/funlink
3426         cp -p /etc/passwd $DIR/$tdir/frename
3427         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3428
3429         sleep 1
3430         echo "aaaaaa" >> $DIR/$tdir/fopen
3431         echo "aaaaaa" >> $DIR/$tdir/flink
3432         echo "aaaaaa" >> $DIR/$tdir/funlink
3433         echo "aaaaaa" >> $DIR/$tdir/frename
3434
3435         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3436         local link_new=`stat -c %Y $DIR/$tdir/flink`
3437         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3438         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3439
3440         cat $DIR/$tdir/fopen > /dev/null
3441         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3442         rm -f $DIR/$tdir/funlink2
3443         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3444
3445         for (( i=0; i < 2; i++ )) ; do
3446                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3447                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3448                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3449                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3450
3451                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3452                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3453                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3454                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3455
3456                 cancel_lru_locks $OSC
3457                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3458         done
3459 }
3460 run_test 39b "mtime change on open, link, unlink, rename  ======"
3461
3462 # this should be set to past
3463 TEST_39_MTIME=`date -d "1 year ago" +%s`
3464
3465 # bug 11063
3466 test_39c() {
3467         touch $DIR1/$tfile
3468         sleep 2
3469         local mtime0=`stat -c %Y $DIR1/$tfile`
3470
3471         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3472         local mtime1=`stat -c %Y $DIR1/$tfile`
3473         [ "$mtime1" = $TEST_39_MTIME ] || \
3474                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3475
3476         local d1=`date +%s`
3477         echo hello >> $DIR1/$tfile
3478         local d2=`date +%s`
3479         local mtime2=`stat -c %Y $DIR1/$tfile`
3480         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3481                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3482
3483         mv $DIR1/$tfile $DIR1/$tfile-1
3484
3485         for (( i=0; i < 2; i++ )) ; do
3486                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3487                 [ "$mtime2" = "$mtime3" ] || \
3488                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3489
3490                 cancel_lru_locks $OSC
3491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3492         done
3493 }
3494 run_test 39c "mtime change on rename ==========================="
3495
3496 # bug 21114
3497 test_39d() {
3498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3499
3500         touch $DIR1/$tfile
3501         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3502
3503         for (( i=0; i < 2; i++ )) ; do
3504                 local mtime=`stat -c %Y $DIR1/$tfile`
3505                 [ $mtime = $TEST_39_MTIME ] || \
3506                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3507
3508                 cancel_lru_locks $OSC
3509                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3510         done
3511 }
3512 run_test 39d "create, utime, stat =============================="
3513
3514 # bug 21114
3515 test_39e() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         touch $DIR1/$tfile
3519         local mtime1=`stat -c %Y $DIR1/$tfile`
3520
3521         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3522
3523         for (( i=0; i < 2; i++ )) ; do
3524                 local mtime2=`stat -c %Y $DIR1/$tfile`
3525                 [ $mtime2 = $TEST_39_MTIME ] || \
3526                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3527
3528                 cancel_lru_locks $OSC
3529                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3530         done
3531 }
3532 run_test 39e "create, stat, utime, stat ========================"
3533
3534 # bug 21114
3535 test_39f() {
3536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3537
3538         touch $DIR1/$tfile
3539         mtime1=`stat -c %Y $DIR1/$tfile`
3540
3541         sleep 2
3542         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3543
3544         for (( i=0; i < 2; i++ )) ; do
3545                 local mtime2=`stat -c %Y $DIR1/$tfile`
3546                 [ $mtime2 = $TEST_39_MTIME ] || \
3547                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
3548
3549                 cancel_lru_locks $OSC
3550                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3551         done
3552 }
3553 run_test 39f "create, stat, sleep, utime, stat ================="
3554
3555 # bug 11063
3556 test_39g() {
3557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3558
3559         echo hello >> $DIR1/$tfile
3560         local mtime1=`stat -c %Y $DIR1/$tfile`
3561
3562         sleep 2
3563         chmod o+r $DIR1/$tfile
3564
3565         for (( i=0; i < 2; i++ )) ; do
3566                 local mtime2=`stat -c %Y $DIR1/$tfile`
3567                 [ "$mtime1" = "$mtime2" ] || \
3568                         error "lost mtime: $mtime2, should be $mtime1"
3569
3570                 cancel_lru_locks $OSC
3571                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3572         done
3573 }
3574 run_test 39g "write, chmod, stat ==============================="
3575
3576 # bug 11063
3577 test_39h() {
3578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3579
3580         touch $DIR1/$tfile
3581         sleep 1
3582
3583         local d1=`date`
3584         echo hello >> $DIR1/$tfile
3585         local mtime1=`stat -c %Y $DIR1/$tfile`
3586
3587         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3588         local d2=`date`
3589         if [ "$d1" != "$d2" ]; then
3590                 echo "write and touch not within one second"
3591         else
3592                 for (( i=0; i < 2; i++ )) ; do
3593                         local mtime2=`stat -c %Y $DIR1/$tfile`
3594                         [ "$mtime2" = $TEST_39_MTIME ] || \
3595                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
3596
3597                         cancel_lru_locks $OSC
3598                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3599                 done
3600         fi
3601 }
3602 run_test 39h "write, utime within one second, stat ============="
3603
3604 test_39i() {
3605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3606
3607         touch $DIR1/$tfile
3608         sleep 1
3609
3610         echo hello >> $DIR1/$tfile
3611         local mtime1=`stat -c %Y $DIR1/$tfile`
3612
3613         mv $DIR1/$tfile $DIR1/$tfile-1
3614
3615         for (( i=0; i < 2; i++ )) ; do
3616                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3617
3618                 [ "$mtime1" = "$mtime2" ] || \
3619                         error "lost mtime: $mtime2, should be $mtime1"
3620
3621                 cancel_lru_locks $OSC
3622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3623         done
3624 }
3625 run_test 39i "write, rename, stat =============================="
3626
3627 test_39j() {
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         start_full_debug_logging
3631         touch $DIR1/$tfile
3632         sleep 1
3633
3634         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
3635         lctl set_param fail_loc=0x80000412
3636         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
3637                 error "multiop failed"
3638         local multipid=$!
3639         local mtime1=`stat -c %Y $DIR1/$tfile`
3640
3641         mv $DIR1/$tfile $DIR1/$tfile-1
3642
3643         kill -USR1 $multipid
3644         wait $multipid || error "multiop close failed"
3645
3646         for (( i=0; i < 2; i++ )) ; do
3647                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
3648                 [ "$mtime1" = "$mtime2" ] ||
3649                         error "mtime is lost on close: $mtime2, " \
3650                               "should be $mtime1"
3651
3652                 cancel_lru_locks $OSC
3653                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3654         done
3655         lctl set_param fail_loc=0
3656         stop_full_debug_logging
3657 }
3658 run_test 39j "write, rename, close, stat ======================="
3659
3660 test_39k() {
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         touch $DIR1/$tfile
3664         sleep 1
3665
3666         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
3667         local multipid=$!
3668         local mtime1=`stat -c %Y $DIR1/$tfile`
3669
3670         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3671
3672         kill -USR1 $multipid
3673         wait $multipid || error "multiop close failed"
3674
3675         for (( i=0; i < 2; i++ )) ; do
3676                 local mtime2=`stat -c %Y $DIR1/$tfile`
3677
3678                 [ "$mtime2" = $TEST_39_MTIME ] || \
3679                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
3680
3681                 cancel_lru_locks osc
3682                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3683         done
3684 }
3685 run_test 39k "write, utime, close, stat ========================"
3686
3687 # this should be set to future
3688 TEST_39_ATIME=`date -d "1 year" +%s`
3689
3690 test_39l() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692         remote_mds_nodsh && skip "remote MDS with nodsh"
3693
3694         local atime_diff=$(do_facet $SINGLEMDS \
3695                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3696         rm -rf $DIR/$tdir
3697         mkdir -p $DIR/$tdir
3698
3699         # test setting directory atime to future
3700         touch -a -d @$TEST_39_ATIME $DIR/$tdir
3701         local atime=$(stat -c %X $DIR/$tdir)
3702         [ "$atime" = $TEST_39_ATIME ] ||
3703                 error "atime is not set to future: $atime, $TEST_39_ATIME"
3704
3705         # test setting directory atime from future to now
3706         local now=$(date +%s)
3707         touch -a -d @$now $DIR/$tdir
3708
3709         atime=$(stat -c %X $DIR/$tdir)
3710         [ "$atime" -eq "$now"  ] ||
3711                 error "atime is not updated from future: $atime, $now"
3712
3713         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
3714         sleep 3
3715
3716         # test setting directory atime when now > dir atime + atime_diff
3717         local d1=$(date +%s)
3718         ls $DIR/$tdir
3719         local d2=$(date +%s)
3720         cancel_lru_locks mdc
3721         atime=$(stat -c %X $DIR/$tdir)
3722         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3723                 error "atime is not updated  : $atime, should be $d2"
3724
3725         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
3726         sleep 3
3727
3728         # test not setting directory atime when now < dir atime + atime_diff
3729         ls $DIR/$tdir
3730         cancel_lru_locks mdc
3731         atime=$(stat -c %X $DIR/$tdir)
3732         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
3733                 error "atime is updated to $atime, should remain $d1<atime<$d2"
3734
3735         do_facet $SINGLEMDS \
3736                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3737 }
3738 run_test 39l "directory atime update ==========================="
3739
3740 test_39m() {
3741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3742
3743         touch $DIR1/$tfile
3744         sleep 2
3745         local far_past_mtime=$(date -d "May 29 1953" +%s)
3746         local far_past_atime=$(date -d "Dec 17 1903" +%s)
3747
3748         touch -m -d @$far_past_mtime $DIR1/$tfile
3749         touch -a -d @$far_past_atime $DIR1/$tfile
3750
3751         for (( i=0; i < 2; i++ )) ; do
3752                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
3753                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
3754                         error "atime or mtime set incorrectly"
3755
3756                 cancel_lru_locks $OSC
3757                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3758         done
3759 }
3760 run_test 39m "test atime and mtime before 1970"
3761
3762 test_39n() { # LU-3832
3763         remote_mds_nodsh && skip "remote MDS with nodsh"
3764
3765         local atime_diff=$(do_facet $SINGLEMDS \
3766                 lctl get_param -n mdd.*MDT0000*.atime_diff)
3767         local atime0
3768         local atime1
3769         local atime2
3770
3771         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
3772
3773         rm -rf $DIR/$tfile
3774         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
3775         atime0=$(stat -c %X $DIR/$tfile)
3776
3777         sleep 5
3778         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3779         atime1=$(stat -c %X $DIR/$tfile)
3780
3781         sleep 5
3782         cancel_lru_locks mdc
3783         cancel_lru_locks osc
3784         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
3785         atime2=$(stat -c %X $DIR/$tfile)
3786
3787         do_facet $SINGLEMDS \
3788                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
3789
3790         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
3791         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
3792 }
3793 run_test 39n "check that O_NOATIME is honored"
3794
3795 test_39o() {
3796         TESTDIR=$DIR/$tdir/$tfile
3797         [ -e $TESTDIR ] && rm -rf $TESTDIR
3798         mkdir -p $TESTDIR
3799         cd $TESTDIR
3800         links1=2
3801         ls
3802         mkdir a b
3803         ls
3804         links2=$(stat -c %h .)
3805         [ $(($links1 + 2)) != $links2 ] &&
3806                 error "wrong links count $(($links1 + 2)) != $links2"
3807         rmdir b
3808         links3=$(stat -c %h .)
3809         [ $(($links1 + 1)) != $links3 ] &&
3810                 error "wrong links count $links1 != $links3"
3811         return 0
3812 }
3813 run_test 39o "directory cached attributes updated after create"
3814
3815 test_39p() {
3816         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3817
3818         local MDTIDX=1
3819         TESTDIR=$DIR/$tdir/$tdir
3820         [ -e $TESTDIR ] && rm -rf $TESTDIR
3821         test_mkdir -p $TESTDIR
3822         cd $TESTDIR
3823         links1=2
3824         ls
3825         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
3826         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
3827         ls
3828         links2=$(stat -c %h .)
3829         [ $(($links1 + 2)) != $links2 ] &&
3830                 error "wrong links count $(($links1 + 2)) != $links2"
3831         rmdir remote_dir2
3832         links3=$(stat -c %h .)
3833         [ $(($links1 + 1)) != $links3 ] &&
3834                 error "wrong links count $links1 != $links3"
3835         return 0
3836 }
3837 run_test 39p "remote directory cached attributes updated after create ========"
3838
3839
3840 test_39q() { # LU-8041
3841         local testdir=$DIR/$tdir
3842         mkdir -p $testdir
3843         multiop_bg_pause $testdir D_c || error "multiop failed"
3844         local multipid=$!
3845         cancel_lru_locks mdc
3846         kill -USR1 $multipid
3847         local atime=$(stat -c %X $testdir)
3848         [ "$atime" -ne 0 ] || error "atime is zero"
3849 }
3850 run_test 39q "close won't zero out atime"
3851
3852 test_40() {
3853         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
3854         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
3855                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
3856         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
3857                 error "$tfile is not 4096 bytes in size"
3858 }
3859 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
3860
3861 test_41() {
3862         # bug 1553
3863         small_write $DIR/f41 18
3864 }
3865 run_test 41 "test small file write + fstat ====================="
3866
3867 count_ost_writes() {
3868         lctl get_param -n ${OSC}.*.stats |
3869                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
3870                         END { printf("%0.0f", writes) }'
3871 }
3872
3873 # decent default
3874 WRITEBACK_SAVE=500
3875 DIRTY_RATIO_SAVE=40
3876 MAX_DIRTY_RATIO=50
3877 BG_DIRTY_RATIO_SAVE=10
3878 MAX_BG_DIRTY_RATIO=25
3879
3880 start_writeback() {
3881         trap 0
3882         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
3883         # dirty_ratio, dirty_background_ratio
3884         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3885                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
3886                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
3887                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
3888         else
3889                 # if file not here, we are a 2.4 kernel
3890                 kill -CONT `pidof kupdated`
3891         fi
3892 }
3893
3894 stop_writeback() {
3895         # setup the trap first, so someone cannot exit the test at the
3896         # exact wrong time and mess up a machine
3897         trap start_writeback EXIT
3898         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
3899         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
3900                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
3901                 sysctl -w vm.dirty_writeback_centisecs=0
3902                 sysctl -w vm.dirty_writeback_centisecs=0
3903                 # save and increase /proc/sys/vm/dirty_ratio
3904                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
3905                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
3906                 # save and increase /proc/sys/vm/dirty_background_ratio
3907                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
3908                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
3909         else
3910                 # if file not here, we are a 2.4 kernel
3911                 kill -STOP `pidof kupdated`
3912         fi
3913 }
3914
3915 # ensure that all stripes have some grant before we test client-side cache
3916 setup_test42() {
3917         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
3918                 dd if=/dev/zero of=$i bs=4k count=1
3919                 rm $i
3920         done
3921 }
3922
3923 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
3924 # file truncation, and file removal.
3925 test_42a() {
3926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3927
3928         setup_test42
3929         cancel_lru_locks $OSC
3930         stop_writeback
3931         sync; sleep 1; sync # just to be safe
3932         BEFOREWRITES=`count_ost_writes`
3933         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
3934         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
3935         AFTERWRITES=`count_ost_writes`
3936         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
3937                 error "$BEFOREWRITES < $AFTERWRITES"
3938         start_writeback
3939 }
3940 run_test 42a "ensure that we don't flush on close"
3941
3942 test_42b() {
3943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3944
3945         setup_test42
3946         cancel_lru_locks $OSC
3947         stop_writeback
3948         sync
3949         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
3950         BEFOREWRITES=$(count_ost_writes)
3951         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
3952         AFTERWRITES=$(count_ost_writes)
3953         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3954                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
3955         fi
3956         BEFOREWRITES=$(count_ost_writes)
3957         sync || error "sync: $?"
3958         AFTERWRITES=$(count_ost_writes)
3959         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
3960                 error "$BEFOREWRITES < $AFTERWRITES on sync"
3961         fi
3962         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
3963         start_writeback
3964         return 0
3965 }
3966 run_test 42b "test destroy of file with cached dirty data ======"
3967
3968 # if these tests just want to test the effect of truncation,
3969 # they have to be very careful.  consider:
3970 # - the first open gets a {0,EOF}PR lock
3971 # - the first write conflicts and gets a {0, count-1}PW
3972 # - the rest of the writes are under {count,EOF}PW
3973 # - the open for truncate tries to match a {0,EOF}PR
3974 #   for the filesize and cancels the PWs.
3975 # any number of fixes (don't get {0,EOF} on open, match
3976 # composite locks, do smarter file size management) fix
3977 # this, but for now we want these tests to verify that
3978 # the cancellation with truncate intent works, so we
3979 # start the file with a full-file pw lock to match against
3980 # until the truncate.
3981 trunc_test() {
3982         test=$1
3983         file=$DIR/$test
3984         offset=$2
3985         cancel_lru_locks $OSC
3986         stop_writeback
3987         # prime the file with 0,EOF PW to match
3988         touch $file
3989         $TRUNCATE $file 0
3990         sync; sync
3991         # now the real test..
3992         dd if=/dev/zero of=$file bs=1024 count=100
3993         BEFOREWRITES=`count_ost_writes`
3994         $TRUNCATE $file $offset
3995         cancel_lru_locks $OSC
3996         AFTERWRITES=`count_ost_writes`
3997         start_writeback
3998 }
3999
4000 test_42c() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         trunc_test 42c 1024
4004         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4005                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4006         rm $file
4007 }
4008 run_test 42c "test partial truncate of file with cached dirty data"
4009
4010 test_42d() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         trunc_test 42d 0
4014         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4015                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4016         rm $file
4017 }
4018 run_test 42d "test complete truncate of file with cached dirty data"
4019
4020 test_42e() { # bug22074
4021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4022
4023         local TDIR=$DIR/${tdir}e
4024         local pages=16 # hardcoded 16 pages, don't change it.
4025         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4026         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4027         local max_dirty_mb
4028         local warmup_files
4029
4030         test_mkdir $DIR/${tdir}e
4031         $LFS setstripe -c 1 $TDIR
4032         createmany -o $TDIR/f $files
4033
4034         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4035
4036         # we assume that with $OSTCOUNT files, at least one of them will
4037         # be allocated on OST0.
4038         warmup_files=$((OSTCOUNT * max_dirty_mb))
4039         createmany -o $TDIR/w $warmup_files
4040
4041         # write a large amount of data into one file and sync, to get good
4042         # avail_grant number from OST.
4043         for ((i=0; i<$warmup_files; i++)); do
4044                 idx=$($LFS getstripe -i $TDIR/w$i)
4045                 [ $idx -ne 0 ] && continue
4046                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4047                 break
4048         done
4049         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4050         sync
4051         $LCTL get_param $proc_osc0/cur_dirty_bytes
4052         $LCTL get_param $proc_osc0/cur_grant_bytes
4053
4054         # create as much dirty pages as we can while not to trigger the actual
4055         # RPCs directly. but depends on the env, VFS may trigger flush during this
4056         # period, hopefully we are good.
4057         for ((i=0; i<$warmup_files; i++)); do
4058                 idx=$($LFS getstripe -i $TDIR/w$i)
4059                 [ $idx -ne 0 ] && continue
4060                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4061         done
4062         $LCTL get_param $proc_osc0/cur_dirty_bytes
4063         $LCTL get_param $proc_osc0/cur_grant_bytes
4064
4065         # perform the real test
4066         $LCTL set_param $proc_osc0/rpc_stats 0
4067         for ((;i<$files; i++)); do
4068                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4069                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4070         done
4071         sync
4072         $LCTL get_param $proc_osc0/rpc_stats
4073
4074         local percent=0
4075         local have_ppr=false
4076         $LCTL get_param $proc_osc0/rpc_stats |
4077                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4078                         # skip lines until we are at the RPC histogram data
4079                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4080                         $have_ppr || continue
4081
4082                         # we only want the percent stat for < 16 pages
4083                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4084
4085                         percent=$((percent + WPCT))
4086                         if [[ $percent -gt 15 ]]; then
4087                                 error "less than 16-pages write RPCs" \
4088                                       "$percent% > 15%"
4089                                 break
4090                         fi
4091                 done
4092         rm -rf $TDIR
4093 }
4094 run_test 42e "verify sub-RPC writes are not done synchronously"
4095
4096 test_43A() { # was test_43
4097         test_mkdir $DIR/$tdir
4098         cp -p /bin/ls $DIR/$tdir/$tfile
4099         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4100         pid=$!
4101         # give multiop a chance to open
4102         sleep 1
4103
4104         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4105         kill -USR1 $pid
4106 }
4107 run_test 43A "execution of file opened for write should return -ETXTBSY"
4108
4109 test_43a() {
4110         test_mkdir $DIR/$tdir
4111         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4112                 cp -p multiop $DIR/$tdir/multiop
4113         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4114                 error "multiop open $TMP/$tfile.junk failed"
4115         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4116         MULTIOP_PID=$!
4117         $MULTIOP $DIR/$tdir/multiop Oc && error "expected error, got success"
4118         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4119         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4120 }
4121 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4122
4123 test_43b() {
4124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4125
4126         test_mkdir $DIR/$tdir
4127         cp -p $(which $MULTIOP) $DIR/$tdir/multiop ||
4128                 cp -p multiop $DIR/$tdir/multiop
4129         MULTIOP_PROG=$DIR/$tdir/multiop multiop_bg_pause $TMP/$tfile.junk O_c ||
4130                 error "multiop open $TMP/$tfile.junk failed"
4131         rm $TMP/$tfile.junk     # delete junk file on close (not part of test)
4132         MULTIOP_PID=$!
4133         $TRUNCATE $DIR/$tdir/multiop 0 && error "expected error, got success"
4134         kill -USR1 $MULTIOP_PID || error "kill -USR1 PID $MULTIOP_PID failed"
4135         wait $MULTIOP_PID || error "wait PID $MULTIOP_PID failed"
4136 }
4137 run_test 43b "truncate of file being executed should return -ETXTBSY"
4138
4139 test_43c() {
4140         local testdir="$DIR/$tdir"
4141         test_mkdir $testdir
4142         cp $SHELL $testdir/
4143         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4144                 ( cd $testdir && md5sum -c )
4145 }
4146 run_test 43c "md5sum of copy into lustre"
4147
4148 test_44A() { # was test_44
4149         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4150
4151         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4152         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4153 }
4154 run_test 44A "zero length read from a sparse stripe"
4155
4156 test_44a() {
4157         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4158                 awk '{ print $2 }')
4159         [ -z "$nstripe" ] && skip "can't get stripe info"
4160         [[ $nstripe -gt $OSTCOUNT ]] &&
4161                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4162
4163         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4164                 awk '{ print $2 }')
4165         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4166                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4167                         awk '{ print $2 }')
4168         fi
4169
4170         OFFSETS="0 $((stride/2)) $((stride-1))"
4171         for offset in $OFFSETS; do
4172                 for i in $(seq 0 $((nstripe-1))); do
4173                         local GLOBALOFFSETS=""
4174                         # size in Bytes
4175                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4176                         local myfn=$DIR/d44a-$size
4177                         echo "--------writing $myfn at $size"
4178                         ll_sparseness_write $myfn $size ||
4179                                 error "ll_sparseness_write"
4180                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4181                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4182                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4183
4184                         for j in $(seq 0 $((nstripe-1))); do
4185                                 # size in Bytes
4186                                 size=$((((j + $nstripe )*$stride + $offset)))
4187                                 ll_sparseness_write $myfn $size ||
4188                                         error "ll_sparseness_write"
4189                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4190                         done
4191                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4192                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4193                         rm -f $myfn
4194                 done
4195         done
4196 }
4197 run_test 44a "test sparse pwrite ==============================="
4198
4199 dirty_osc_total() {
4200         tot=0
4201         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4202                 tot=$(($tot + $d))
4203         done
4204         echo $tot
4205 }
4206 do_dirty_record() {
4207         before=`dirty_osc_total`
4208         echo executing "\"$*\""
4209         eval $*
4210         after=`dirty_osc_total`
4211         echo before $before, after $after
4212 }
4213 test_45() {
4214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4215
4216         f="$DIR/f45"
4217         # Obtain grants from OST if it supports it
4218         echo blah > ${f}_grant
4219         stop_writeback
4220         sync
4221         do_dirty_record "echo blah > $f"
4222         [[ $before -eq $after ]] && error "write wasn't cached"
4223         do_dirty_record "> $f"
4224         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4225         do_dirty_record "echo blah > $f"
4226         [[ $before -eq $after ]] && error "write wasn't cached"
4227         do_dirty_record "sync"
4228         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4229         do_dirty_record "echo blah > $f"
4230         [[ $before -eq $after ]] && error "write wasn't cached"
4231         do_dirty_record "cancel_lru_locks osc"
4232         [[ $before -gt $after ]] ||
4233                 error "lock cancellation didn't lower dirty count"
4234         start_writeback
4235 }
4236 run_test 45 "osc io page accounting ============================"
4237
4238 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4239 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4240 # objects offset and an assert hit when an rpc was built with 1023's mapped
4241 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4242 test_46() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         f="$DIR/f46"
4246         stop_writeback
4247         sync
4248         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4249         sync
4250         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4251         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4252         sync
4253         start_writeback
4254 }
4255 run_test 46 "dirtying a previously written page ================"
4256
4257 # test_47 is removed "Device nodes check" is moved to test_28
4258
4259 test_48a() { # bug 2399
4260         [ "$mds1_FSTYPE" = "zfs" ] &&
4261         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4262                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4263
4264         test_mkdir $DIR/$tdir
4265         cd $DIR/$tdir
4266         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4267         test_mkdir $DIR/$tdir
4268         touch foo || error "'touch foo' failed after recreating cwd"
4269         test_mkdir bar
4270         touch .foo || error "'touch .foo' failed after recreating cwd"
4271         test_mkdir .bar
4272         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4273         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4274         cd . || error "'cd .' failed after recreating cwd"
4275         mkdir . && error "'mkdir .' worked after recreating cwd"
4276         rmdir . && error "'rmdir .' worked after recreating cwd"
4277         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4278         cd .. || error "'cd ..' failed after recreating cwd"
4279 }
4280 run_test 48a "Access renamed working dir (should return errors)="
4281
4282 test_48b() { # bug 2399
4283         rm -rf $DIR/$tdir
4284         test_mkdir $DIR/$tdir
4285         cd $DIR/$tdir
4286         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4287         touch foo && error "'touch foo' worked after removing cwd"
4288         mkdir foo && error "'mkdir foo' worked after removing cwd"
4289         touch .foo && error "'touch .foo' worked after removing cwd"
4290         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4291         ls . > /dev/null && error "'ls .' worked after removing cwd"
4292         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4293         mkdir . && error "'mkdir .' worked after removing cwd"
4294         rmdir . && error "'rmdir .' worked after removing cwd"
4295         ln -s . foo && error "'ln -s .' worked after removing cwd"
4296         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4297 }
4298 run_test 48b "Access removed working dir (should return errors)="
4299
4300 test_48c() { # bug 2350
4301         #lctl set_param debug=-1
4302         #set -vx
4303         rm -rf $DIR/$tdir
4304         test_mkdir -p $DIR/$tdir/dir
4305         cd $DIR/$tdir/dir
4306         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4307         $TRACE touch foo && error "touch foo worked after removing cwd"
4308         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4309         touch .foo && error "touch .foo worked after removing cwd"
4310         mkdir .foo && error "mkdir .foo worked after removing cwd"
4311         $TRACE ls . && error "'ls .' worked after removing cwd"
4312         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4313         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4314         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4315         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4316         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4317 }
4318 run_test 48c "Access removed working subdir (should return errors)"
4319
4320 test_48d() { # bug 2350
4321         #lctl set_param debug=-1
4322         #set -vx
4323         rm -rf $DIR/$tdir
4324         test_mkdir -p $DIR/$tdir/dir
4325         cd $DIR/$tdir/dir
4326         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4327         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4328         $TRACE touch foo && error "'touch foo' worked after removing parent"
4329         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4330         touch .foo && error "'touch .foo' worked after removing parent"
4331         mkdir .foo && error "mkdir .foo worked after removing parent"
4332         $TRACE ls . && error "'ls .' worked after removing parent"
4333         $TRACE ls .. && error "'ls ..' worked after removing parent"
4334         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4335         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4336         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4337         true
4338 }
4339 run_test 48d "Access removed parent subdir (should return errors)"
4340
4341 test_48e() { # bug 4134
4342         #lctl set_param debug=-1
4343         #set -vx
4344         rm -rf $DIR/$tdir
4345         test_mkdir -p $DIR/$tdir/dir
4346         cd $DIR/$tdir/dir
4347         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4348         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4349         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4350         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4351         # On a buggy kernel addition of "touch foo" after cd .. will
4352         # produce kernel oops in lookup_hash_it
4353         touch ../foo && error "'cd ..' worked after recreate parent"
4354         cd $DIR
4355         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4356 }
4357 run_test 48e "Access to recreated parent subdir (should return errors)"
4358
4359 test_49() { # LU-1030
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361         remote_ost_nodsh && skip "remote OST with nodsh"
4362
4363         # get ost1 size - lustre-OST0000
4364         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4365                 awk '{ print $4 }')
4366         # write 800M at maximum
4367         [[ $ost1_size -lt 2 ]] && ost1_size=2
4368         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4369
4370         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4371         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4372         local dd_pid=$!
4373
4374         # change max_pages_per_rpc while writing the file
4375         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4376         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4377         # loop until dd process exits
4378         while ps ax -opid | grep -wq $dd_pid; do
4379                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4380                 sleep $((RANDOM % 5 + 1))
4381         done
4382         # restore original max_pages_per_rpc
4383         $LCTL set_param $osc1_mppc=$orig_mppc
4384         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4385 }
4386 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4387
4388 test_50() {
4389         # bug 1485
4390         test_mkdir $DIR/$tdir
4391         cd $DIR/$tdir
4392         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4393 }
4394 run_test 50 "special situations: /proc symlinks  ==============="
4395
4396 test_51a() {    # was test_51
4397         # bug 1516 - create an empty entry right after ".." then split dir
4398         test_mkdir -c1 $DIR/$tdir
4399         touch $DIR/$tdir/foo
4400         $MCREATE $DIR/$tdir/bar
4401         rm $DIR/$tdir/foo
4402         createmany -m $DIR/$tdir/longfile 201
4403         FNUM=202
4404         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4405                 $MCREATE $DIR/$tdir/longfile$FNUM
4406                 FNUM=$(($FNUM + 1))
4407                 echo -n "+"
4408         done
4409         echo
4410         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4411 }
4412 run_test 51a "special situations: split htree with empty entry =="
4413
4414 cleanup_print_lfs_df () {
4415         trap 0
4416         $LFS df
4417         $LFS df -i
4418 }
4419
4420 test_51b() {
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422
4423         local dir=$DIR/$tdir
4424         local nrdirs=$((65536 + 100))
4425
4426         # cleanup the directory
4427         rm -fr $dir
4428
4429         test_mkdir -c1 $dir
4430
4431         $LFS df
4432         $LFS df -i
4433         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4434         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4435         [[ $numfree -lt $nrdirs ]] &&
4436                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4437
4438         # need to check free space for the directories as well
4439         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4440         numfree=$(( blkfree / $(fs_inode_ksize) ))
4441         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4442
4443         trap cleanup_print_lfs_df EXIT
4444
4445         # create files
4446         createmany -d $dir/d $nrdirs || {
4447                 unlinkmany $dir/d $nrdirs
4448                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4449         }
4450
4451         # really created :
4452         nrdirs=$(ls -U $dir | wc -l)
4453
4454         # unlink all but 100 subdirectories, then check it still works
4455         local left=100
4456         local delete=$((nrdirs - left))
4457
4458         $LFS df
4459         $LFS df -i
4460
4461         # for ldiskfs the nlink count should be 1, but this is OSD specific
4462         # and so this is listed for informational purposes only
4463         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4464         unlinkmany -d $dir/d $delete ||
4465                 error "unlink of first $delete subdirs failed"
4466
4467         echo "nlink between: $(stat -c %h $dir)"
4468         local found=$(ls -U $dir | wc -l)
4469         [ $found -ne $left ] &&
4470                 error "can't find subdirs: found only $found, expected $left"
4471
4472         unlinkmany -d $dir/d $delete $left ||
4473                 error "unlink of second $left subdirs failed"
4474         # regardless of whether the backing filesystem tracks nlink accurately
4475         # or not, the nlink count shouldn't be more than "." and ".." here
4476         local after=$(stat -c %h $dir)
4477         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4478                 echo "nlink after: $after"
4479
4480         cleanup_print_lfs_df
4481 }
4482 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4483
4484 test_51d() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4487
4488         test_mkdir $DIR/$tdir
4489         createmany -o $DIR/$tdir/t- 1000
4490         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4491         for N in $(seq 0 $((OSTCOUNT - 1))); do
4492                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4493                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4494                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4495                         '($1 == '$N') { objs += 1 } \
4496                         END { printf("%0.0f", objs) }')
4497                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4498         done
4499         unlinkmany $DIR/$tdir/t- 1000
4500
4501         NLAST=0
4502         for N in $(seq 1 $((OSTCOUNT - 1))); do
4503                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4504                         error "OST $N has less objects vs OST $NLAST" \
4505                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4506                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4507                         error "OST $N has less objects vs OST $NLAST" \
4508                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4509
4510                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4511                         error "OST $N has less #0 objects vs OST $NLAST" \
4512                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4513                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4514                         error "OST $N has less #0 objects vs OST $NLAST" \
4515                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4516                 NLAST=$N
4517         done
4518         rm -f $TMP/$tfile
4519 }
4520 run_test 51d "check object distribution"
4521
4522 test_51e() {
4523         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4524                 skip_env "ldiskfs only test"
4525         fi
4526
4527         test_mkdir -c1 $DIR/$tdir
4528         test_mkdir -c1 $DIR/$tdir/d0
4529
4530         touch $DIR/$tdir/d0/foo
4531         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4532                 error "file exceed 65000 nlink limit!"
4533         unlinkmany $DIR/$tdir/d0/f- 65001
4534         return 0
4535 }
4536 run_test 51e "check file nlink limit"
4537
4538 test_51f() {
4539         test_mkdir $DIR/$tdir
4540
4541         local max=100000
4542         local ulimit_old=$(ulimit -n)
4543         local spare=20 # number of spare fd's for scripts/libraries, etc.
4544         local mdt=$($LFS getstripe -m $DIR/$tdir)
4545         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
4546
4547         echo "MDT$mdt numfree=$numfree, max=$max"
4548         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
4549         if [ $((numfree + spare)) -gt $ulimit_old ]; then
4550                 while ! ulimit -n $((numfree + spare)); do
4551                         numfree=$((numfree * 3 / 4))
4552                 done
4553                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
4554         else
4555                 echo "left ulimit at $ulimit_old"
4556         fi
4557
4558         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
4559                 unlinkmany $DIR/$tdir/f $numfree
4560                 error "create+open $numfree files in $DIR/$tdir failed"
4561         }
4562         ulimit -n $ulimit_old
4563
4564         # if createmany exits at 120s there will be fewer than $numfree files
4565         unlinkmany $DIR/$tdir/f $numfree || true
4566 }
4567 run_test 51f "check many open files limit"
4568
4569 test_52a() {
4570         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
4571         test_mkdir $DIR/$tdir
4572         touch $DIR/$tdir/foo
4573         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
4574         echo bar >> $DIR/$tdir/foo || error "append bar failed"
4575         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4576         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4577         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4578                                         error "link worked"
4579         echo foo >> $DIR/$tdir/foo || error "append foo failed"
4580         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4581         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
4582                                                      error "lsattr"
4583         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
4584         cp -r $DIR/$tdir $TMP/
4585         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
4586 }
4587 run_test 52a "append-only flag test (should return errors)"
4588
4589 test_52b() {
4590         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
4591         test_mkdir $DIR/$tdir
4592         touch $DIR/$tdir/foo
4593         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
4594         cat test > $DIR/$tdir/foo && error "cat test worked"
4595         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
4596         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
4597         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
4598                                         error "link worked"
4599         echo foo >> $DIR/$tdir/foo && error "echo worked"
4600         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
4601         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
4602         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
4603         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
4604                                                         error "lsattr"
4605         chattr -i $DIR/$tdir/foo || error "chattr failed"
4606
4607         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
4608 }
4609 run_test 52b "immutable flag test (should return errors) ======="
4610
4611 test_53() {
4612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4613         remote_mds_nodsh && skip "remote MDS with nodsh"
4614         remote_ost_nodsh && skip "remote OST with nodsh"
4615
4616         local param
4617         local param_seq
4618         local ostname
4619         local mds_last
4620         local mds_last_seq
4621         local ost_last
4622         local ost_last_seq
4623         local ost_last_id
4624         local ostnum
4625         local node
4626         local found=false
4627         local support_last_seq=true
4628
4629         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
4630                 support_last_seq=false
4631
4632         # only test MDT0000
4633         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
4634         local value
4635         for value in $(do_facet $SINGLEMDS \
4636                        $LCTL get_param osc.$mdtosc.prealloc_last_id) ; do
4637                 param=$(echo ${value[0]} | cut -d "=" -f1)
4638                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
4639
4640                 if $support_last_seq; then
4641                         param_seq=$(echo $param |
4642                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
4643                         mds_last_seq=$(do_facet $SINGLEMDS \
4644                                        $LCTL get_param -n $param_seq)
4645                 fi
4646                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
4647
4648                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
4649                 node=$(facet_active_host ost$((ostnum+1)))
4650                 param="obdfilter.$ostname.last_id"
4651                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
4652                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
4653                         ost_last_id=$ost_last
4654
4655                         if $support_last_seq; then
4656                                 ost_last_id=$(echo $ost_last |
4657                                               awk -F':' '{print $2}' |
4658                                               sed -e "s/^0x//g")
4659                                 ost_last_seq=$(echo $ost_last |
4660                                                awk -F':' '{print $1}')
4661                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
4662                         fi
4663
4664                         if [[ $ost_last_id != $mds_last ]]; then
4665                                 error "$ost_last_id != $mds_last"
4666                         else
4667                                 found=true
4668                                 break
4669                         fi
4670                 done
4671         done
4672         $found || error "can not match last_seq/last_id for $mdtosc"
4673         return 0
4674 }
4675 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
4676
4677 test_54a() {
4678         perl -MSocket -e ';' || skip "no Socket perl module installed"
4679
4680         $SOCKETSERVER $DIR/socket ||
4681                 error "$SOCKETSERVER $DIR/socket failed: $?"
4682         $SOCKETCLIENT $DIR/socket ||
4683                 error "$SOCKETCLIENT $DIR/socket failed: $?"
4684         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
4685 }
4686 run_test 54a "unix domain socket test =========================="
4687
4688 test_54b() {
4689         f="$DIR/f54b"
4690         mknod $f c 1 3
4691         chmod 0666 $f
4692         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
4693 }
4694 run_test 54b "char device works in lustre ======================"
4695
4696 find_loop_dev() {
4697         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
4698         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
4699         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
4700
4701         for i in $(seq 3 7); do
4702                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
4703                 LOOPDEV=$LOOPBASE$i
4704                 LOOPNUM=$i
4705                 break
4706         done
4707 }
4708
4709 cleanup_54c() {
4710         local rc=0
4711         loopdev="$DIR/loop54c"
4712
4713         trap 0
4714         $UMOUNT $DIR/$tdir || rc=$?
4715         losetup -d $loopdev || true
4716         losetup -d $LOOPDEV || true
4717         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
4718         return $rc
4719 }
4720
4721 test_54c() {
4722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4723
4724         loopdev="$DIR/loop54c"
4725
4726         find_loop_dev
4727         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
4728         trap cleanup_54c EXIT
4729         mknod $loopdev b 7 $LOOPNUM
4730         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
4731         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
4732         losetup $loopdev $DIR/$tfile ||
4733                 error "can't set up $loopdev for $DIR/$tfile"
4734         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
4735         test_mkdir $DIR/$tdir
4736         mount -t ext2 $loopdev $DIR/$tdir ||
4737                 error "error mounting $loopdev on $DIR/$tdir"
4738         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
4739                 error "dd write"
4740         df $DIR/$tdir
4741         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
4742                 error "dd read"
4743         cleanup_54c
4744 }
4745 run_test 54c "block device works in lustre ====================="
4746
4747 test_54d() {
4748         f="$DIR/f54d"
4749         string="aaaaaa"
4750         mknod $f p
4751         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
4752 }
4753 run_test 54d "fifo device works in lustre ======================"
4754
4755 test_54e() {
4756         f="$DIR/f54e"
4757         string="aaaaaa"
4758         cp -aL /dev/console $f
4759         echo $string > $f || error "echo $string to $f failed"
4760 }
4761 run_test 54e "console/tty device works in lustre ======================"
4762
4763 test_56a() {
4764         local numfiles=3
4765         local dir=$DIR/$tdir
4766
4767         rm -rf $dir
4768         test_mkdir -p $dir/dir
4769         for i in $(seq $numfiles); do
4770                 touch $dir/file$i
4771                 touch $dir/dir/file$i
4772         done
4773
4774         local numcomp=$($LFS getstripe --component-count $dir)
4775
4776         [[ $numcomp == 0 ]] && numcomp=1
4777
4778         # test lfs getstripe with --recursive
4779         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
4780
4781         [[ $filenum -eq $((numfiles * 2)) ]] ||
4782                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
4783         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
4784         [[ $filenum -eq $numfiles ]] ||
4785                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
4786         echo "$LFS getstripe showed obdidx or l_ost_idx"
4787
4788         # test lfs getstripe with file instead of dir
4789         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
4790         [[ $filenum -eq 1 ]] ||
4791                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
4792         echo "$LFS getstripe file1 passed"
4793
4794         #test lfs getstripe with --verbose
4795         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
4796         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4797                 error "$LFS getstripe --verbose $dir: "\
4798                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
4799         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
4800                 error "$LFS getstripe $dir: showed lmm_magic"
4801
4802         #test lfs getstripe with -v prints lmm_fid
4803         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
4804         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
4805                 error "$LFS getstripe -v $dir: "\
4806                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
4807         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
4808                 error "$LFS getstripe $dir: showed lmm_fid by default"
4809         echo "$LFS getstripe --verbose passed"
4810
4811         #check for FID information
4812         local fid1=$($LFS getstripe --fid $dir/file1)
4813         local fid2=$($LFS getstripe --verbose $dir/file1 |
4814                      awk '/lmm_fid: / { print $2; exit; }')
4815         local fid3=$($LFS path2fid $dir/file1)
4816
4817         [ "$fid1" != "$fid2" ] &&
4818                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
4819         [ "$fid1" != "$fid3" ] &&
4820                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
4821         echo "$LFS getstripe --fid passed"
4822
4823         #test lfs getstripe with --obd
4824         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
4825                 error "$LFS getstripe --obd wrong_uuid: should return error"
4826
4827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4828
4829         local ostidx=1
4830         local obduuid=$(ostuuid_from_index $ostidx)
4831         local found=$($LFS getstripe -r --obd $obduuid $dir |
4832                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
4833
4834         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
4835         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
4836                 ((filenum--))
4837         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
4838                 ((filenum--))
4839
4840         [[ $found -eq $filenum ]] ||
4841                 error "$LFS getstripe --obd: found $found expect $filenum"
4842         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
4843                 sed '/^[         ]*'${ostidx}'[  ]/d' |
4844                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
4845                 error "$LFS getstripe --obd: should not show file on other obd"
4846         echo "$LFS getstripe --obd passed"
4847 }
4848 run_test 56a "check $LFS getstripe"
4849
4850 test_56b() {
4851         local dir=$DIR/$tdir
4852         local numdirs=3
4853
4854         test_mkdir $dir
4855         for i in $(seq $numdirs); do
4856                 test_mkdir $dir/dir$i
4857         done
4858
4859         # test lfs getdirstripe default mode is non-recursion, which is
4860         # different from lfs getstripe
4861         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
4862
4863         [[ $dircnt -eq 1 ]] ||
4864                 error "$LFS getdirstripe: found $dircnt, not 1"
4865         dircnt=$($LFS getdirstripe --recursive $dir |
4866                 grep -c lmv_stripe_count)
4867         [[ $dircnt -eq $((numdirs + 1)) ]] ||
4868                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
4869 }
4870 run_test 56b "check $LFS getdirstripe"
4871
4872 test_56c() {
4873         remote_ost_nodsh && skip "remote OST with nodsh"
4874
4875         local ost_idx=0
4876         local ost_name=$(ostname_from_index $ost_idx)
4877         local old_status=$(ost_dev_status $ost_idx)
4878
4879         [[ -z "$old_status" ]] ||
4880                 skip_env "OST $ost_name is in $old_status status"
4881
4882         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
4883         sleep_maxage
4884
4885         local new_status=$(ost_dev_status $ost_idx)
4886
4887         [[ "$new_status" = "D" ]] ||
4888                 error "OST $ost_name is in status of '$new_status', not 'D'"
4889
4890         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
4891         sleep_maxage
4892
4893         new_status=$(ost_dev_status $ost_idx)
4894         [[ -z "$new_status" ]] ||
4895                 error "OST $ost_name is in status of '$new_status', not ''"
4896 }
4897 run_test 56c "check 'lfs df' showing device status"
4898
4899 NUMFILES=3
4900 NUMDIRS=3
4901 setup_56() {
4902         local local_tdir="$1"
4903         local local_numfiles="$2"
4904         local local_numdirs="$3"
4905         local dir_params="$4"
4906         local dir_stripe_params="$5"
4907
4908         if [ ! -d "$local_tdir" ] ; then
4909                 test_mkdir -p $dir_stripe_params $local_tdir
4910                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
4911                 for i in $(seq $local_numfiles) ; do
4912                         touch $local_tdir/file$i
4913                 done
4914                 for i in $(seq $local_numdirs) ; do
4915                         test_mkdir $dir_stripe_params $local_tdir/dir$i
4916                         for j in $(seq $local_numfiles) ; do
4917                                 touch $local_tdir/dir$i/file$j
4918                         done
4919                 done
4920         fi
4921 }
4922
4923 setup_56_special() {
4924         local local_tdir=$1
4925         local local_numfiles=$2
4926         local local_numdirs=$3
4927
4928         setup_56 $local_tdir $local_numfiles $local_numdirs
4929
4930         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
4931                 for i in $(seq $local_numfiles) ; do
4932                         mknod $local_tdir/loop${i}b b 7 $i
4933                         mknod $local_tdir/null${i}c c 1 3
4934                         ln -s $local_tdir/file1 $local_tdir/link${i}
4935                 done
4936                 for i in $(seq $local_numdirs) ; do
4937                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
4938                         mknod $local_tdir/dir$i/null${i}c c 1 3
4939                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
4940                 done
4941         fi
4942 }
4943
4944 test_56g() {
4945         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4946         local expected=$(($NUMDIRS + 2))
4947
4948         setup_56 $dir $NUMFILES $NUMDIRS
4949
4950         # test lfs find with -name
4951         for i in $(seq $NUMFILES) ; do
4952                 local nums=$($LFS find -name "*$i" $dir | wc -l)
4953
4954                 [ $nums -eq $expected ] ||
4955                         error "lfs find -name '*$i' $dir wrong: "\
4956                               "found $nums, expected $expected"
4957         done
4958 }
4959 run_test 56g "check lfs find -name"
4960
4961 test_56h() {
4962         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4963         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
4964
4965         setup_56 $dir $NUMFILES $NUMDIRS
4966
4967         # test lfs find with ! -name
4968         for i in $(seq $NUMFILES) ; do
4969                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
4970
4971                 [ $nums -eq $expected ] ||
4972                         error "lfs find ! -name '*$i' $dir wrong: "\
4973                               "found $nums, expected $expected"
4974         done
4975 }
4976 run_test 56h "check lfs find ! -name"
4977
4978 test_56i() {
4979         local dir=$DIR/$tdir
4980
4981         test_mkdir $dir
4982
4983         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
4984         local out=$($cmd)
4985
4986         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
4987 }
4988 run_test 56i "check 'lfs find -ost UUID' skips directories"
4989
4990 test_56j() {
4991         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
4992
4993         setup_56_special $dir $NUMFILES $NUMDIRS
4994
4995         local expected=$((NUMDIRS + 1))
4996         local cmd="$LFS find -type d $dir"
4997         local nums=$($cmd | wc -l)
4998
4999         [ $nums -eq $expected ] ||
5000                 error "'$cmd' wrong: found $nums, expected $expected"
5001 }
5002 run_test 56j "check lfs find -type d"
5003
5004 test_56k() {
5005         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5006
5007         setup_56_special $dir $NUMFILES $NUMDIRS
5008
5009         local expected=$(((NUMDIRS + 1) * NUMFILES))
5010         local cmd="$LFS find -type f $dir"
5011         local nums=$($cmd | wc -l)
5012
5013         [ $nums -eq $expected ] ||
5014                 error "'$cmd' wrong: found $nums, expected $expected"
5015 }
5016 run_test 56k "check lfs find -type f"
5017
5018 test_56l() {
5019         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5020
5021         setup_56_special $dir $NUMFILES $NUMDIRS
5022
5023         local expected=$((NUMDIRS + NUMFILES))
5024         local cmd="$LFS find -type b $dir"
5025         local nums=$($cmd | wc -l)
5026
5027         [ $nums -eq $expected ] ||
5028                 error "'$cmd' wrong: found $nums, expected $expected"
5029 }
5030 run_test 56l "check lfs find -type b"
5031
5032 test_56m() {
5033         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5034
5035         setup_56_special $dir $NUMFILES $NUMDIRS
5036
5037         local expected=$((NUMDIRS + NUMFILES))
5038         local cmd="$LFS find -type c $dir"
5039         local nums=$($cmd | wc -l)
5040         [ $nums -eq $expected ] ||
5041                 error "'$cmd' wrong: found $nums, expected $expected"
5042 }
5043 run_test 56m "check lfs find -type c"
5044
5045 test_56n() {
5046         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5047         setup_56_special $dir $NUMFILES $NUMDIRS
5048
5049         local expected=$((NUMDIRS + NUMFILES))
5050         local cmd="$LFS find -type l $dir"
5051         local nums=$($cmd | wc -l)
5052
5053         [ $nums -eq $expected ] ||
5054                 error "'$cmd' wrong: found $nums, expected $expected"
5055 }
5056 run_test 56n "check lfs find -type l"
5057
5058 test_56o() {
5059         local dir=$DIR/$tdir
5060
5061         setup_56 $dir $NUMFILES $NUMDIRS
5062         utime $dir/file1 > /dev/null || error "utime (1)"
5063         utime $dir/file2 > /dev/null || error "utime (2)"
5064         utime $dir/dir1 > /dev/null || error "utime (3)"
5065         utime $dir/dir2 > /dev/null || error "utime (4)"
5066         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5067         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5068
5069         local expected=4
5070         local nums=$($LFS find -mtime +0 $dir | wc -l)
5071
5072         [ $nums -eq $expected ] ||
5073                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5074
5075         expected=12
5076         cmd="$LFS find -mtime 0 $dir"
5077         nums=$($cmd | wc -l)
5078         [ $nums -eq $expected ] ||
5079                 error "'$cmd' wrong: found $nums, expected $expected"
5080 }
5081 run_test 56o "check lfs find -mtime for old files"
5082
5083 test_56ob() {
5084         local dir=$DIR/$tdir
5085         local expected=1
5086         local count=0
5087
5088         # just to make sure there is something that won't be found
5089         test_mkdir $dir
5090         touch $dir/$tfile.now
5091
5092         for age in year week day hour min; do
5093                 count=$((count + 1))
5094
5095                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5096                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5097                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5098
5099                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5100                 local nums=$($cmd | wc -l)
5101                 [ $nums -eq $expected ] ||
5102                         error "'$cmd' wrong: found $nums, expected $expected"
5103
5104                 cmd="$LFS find $dir -atime $count${age:0:1}"
5105                 nums=$($cmd | wc -l)
5106                 [ $nums -eq $expected ] ||
5107                         error "'$cmd' wrong: found $nums, expected $expected"
5108         done
5109
5110         sleep 2
5111         cmd="$LFS find $dir -ctime +1s -type f"
5112         nums=$($cmd | wc -l)
5113         (( $nums == $count * 2 + 1)) ||
5114                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5115 }
5116 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5117
5118 test_56p() {
5119         [ $RUNAS_ID -eq $UID ] &&
5120                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5121
5122         local dir=$DIR/$tdir
5123
5124         setup_56 $dir $NUMFILES $NUMDIRS
5125         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5126
5127         local expected=$NUMFILES
5128         local cmd="$LFS find -uid $RUNAS_ID $dir"
5129         local nums=$($cmd | wc -l)
5130
5131         [ $nums -eq $expected ] ||
5132                 error "'$cmd' wrong: found $nums, expected $expected"
5133
5134         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5135         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5136         nums=$($cmd | wc -l)
5137         [ $nums -eq $expected ] ||
5138                 error "'$cmd' wrong: found $nums, expected $expected"
5139 }
5140 run_test 56p "check lfs find -uid and ! -uid"
5141
5142 test_56q() {
5143         [ $RUNAS_ID -eq $UID ] &&
5144                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5145
5146         local dir=$DIR/$tdir
5147
5148         setup_56 $dir $NUMFILES $NUMDIRS
5149         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5150
5151         local expected=$NUMFILES
5152         local cmd="$LFS find -gid $RUNAS_GID $dir"
5153         local nums=$($cmd | wc -l)
5154
5155         [ $nums -eq $expected ] ||
5156                 error "'$cmd' wrong: found $nums, expected $expected"
5157
5158         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5159         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5160         nums=$($cmd | wc -l)
5161         [ $nums -eq $expected ] ||
5162                 error "'$cmd' wrong: found $nums, expected $expected"
5163 }
5164 run_test 56q "check lfs find -gid and ! -gid"
5165
5166 test_56r() {
5167         local dir=$DIR/$tdir
5168
5169         setup_56 $dir $NUMFILES $NUMDIRS
5170
5171         local expected=12
5172         local cmd="$LFS find -size 0 -type f $dir"
5173         local nums=$($cmd | wc -l)
5174
5175         [ $nums -eq $expected ] ||
5176                 error "'$cmd' wrong: found $nums, expected $expected"
5177         expected=0
5178         cmd="$LFS find ! -size 0 -type f $dir"
5179         nums=$($cmd | wc -l)
5180         [ $nums -eq $expected ] ||
5181                 error "'$cmd' wrong: found $nums, expected $expected"
5182         echo "test" > $dir/$tfile
5183         echo "test2" > $dir/$tfile.2 && sync
5184         expected=1
5185         cmd="$LFS find -size 5 -type f $dir"
5186         nums=$($cmd | wc -l)
5187         [ $nums -eq $expected ] ||
5188                 error "'$cmd' wrong: found $nums, expected $expected"
5189         expected=1
5190         cmd="$LFS find -size +5 -type f $dir"
5191         nums=$($cmd | wc -l)
5192         [ $nums -eq $expected ] ||
5193                 error "'$cmd' wrong: found $nums, expected $expected"
5194         expected=2
5195         cmd="$LFS find -size +0 -type f $dir"
5196         nums=$($cmd | wc -l)
5197         [ $nums -eq $expected ] ||
5198                 error "'$cmd' wrong: found $nums, expected $expected"
5199         expected=2
5200         cmd="$LFS find ! -size -5 -type f $dir"
5201         nums=$($cmd | wc -l)
5202         [ $nums -eq $expected ] ||
5203                 error "'$cmd' wrong: found $nums, expected $expected"
5204         expected=12
5205         cmd="$LFS find -size -5 -type f $dir"
5206         nums=$($cmd | wc -l)
5207         [ $nums -eq $expected ] ||
5208                 error "'$cmd' wrong: found $nums, expected $expected"
5209 }
5210 run_test 56r "check lfs find -size works"
5211
5212 test_56s() { # LU-611 #LU-9369
5213         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5214
5215         local dir=$DIR/$tdir
5216         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5217
5218         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5219         for i in $(seq $NUMDIRS); do
5220                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5221         done
5222
5223         local expected=$NUMDIRS
5224         local cmd="$LFS find -c $OSTCOUNT $dir"
5225         local nums=$($cmd | wc -l)
5226
5227         [ $nums -eq $expected ] || {
5228                 $LFS getstripe -R $dir
5229                 error "'$cmd' wrong: found $nums, expected $expected"
5230         }
5231
5232         expected=$((NUMDIRS + onestripe))
5233         cmd="$LFS find -stripe-count +0 -type f $dir"
5234         nums=$($cmd | wc -l)
5235         [ $nums -eq $expected ] || {
5236                 $LFS getstripe -R $dir
5237                 error "'$cmd' wrong: found $nums, expected $expected"
5238         }
5239
5240         expected=$onestripe
5241         cmd="$LFS find -stripe-count 1 -type f $dir"
5242         nums=$($cmd | wc -l)
5243         [ $nums -eq $expected ] || {
5244                 $LFS getstripe -R $dir
5245                 error "'$cmd' wrong: found $nums, expected $expected"
5246         }
5247
5248         cmd="$LFS find -stripe-count -2 -type f $dir"
5249         nums=$($cmd | wc -l)
5250         [ $nums -eq $expected ] || {
5251                 $LFS getstripe -R $dir
5252                 error "'$cmd' wrong: found $nums, expected $expected"
5253         }
5254
5255         expected=0
5256         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5257         nums=$($cmd | wc -l)
5258         [ $nums -eq $expected ] || {
5259                 $LFS getstripe -R $dir
5260                 error "'$cmd' wrong: found $nums, expected $expected"
5261         }
5262 }
5263 run_test 56s "check lfs find -stripe-count works"
5264
5265 test_56t() { # LU-611 #LU-9369
5266         local dir=$DIR/$tdir
5267
5268         setup_56 $dir 0 $NUMDIRS
5269         for i in $(seq $NUMDIRS); do
5270                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5271         done
5272
5273         local expected=$NUMDIRS
5274         local cmd="$LFS find -S 8M $dir"
5275         local nums=$($cmd | wc -l)
5276
5277         [ $nums -eq $expected ] || {
5278                 $LFS getstripe -R $dir
5279                 error "'$cmd' wrong: found $nums, expected $expected"
5280         }
5281         rm -rf $dir
5282
5283         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5284
5285         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5286
5287         expected=$(((NUMDIRS + 1) * NUMFILES))
5288         cmd="$LFS find -stripe-size 512k -type f $dir"
5289         nums=$($cmd | wc -l)
5290         [ $nums -eq $expected ] ||
5291                 error "'$cmd' wrong: found $nums, expected $expected"
5292
5293         cmd="$LFS find -stripe-size +320k -type f $dir"
5294         nums=$($cmd | wc -l)
5295         [ $nums -eq $expected ] ||
5296                 error "'$cmd' wrong: found $nums, expected $expected"
5297
5298         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5299         cmd="$LFS find -stripe-size +200k -type f $dir"
5300         nums=$($cmd | wc -l)
5301         [ $nums -eq $expected ] ||
5302                 error "'$cmd' wrong: found $nums, expected $expected"
5303
5304         cmd="$LFS find -stripe-size -640k -type f $dir"
5305         nums=$($cmd | wc -l)
5306         [ $nums -eq $expected ] ||
5307                 error "'$cmd' wrong: found $nums, expected $expected"
5308
5309         expected=4
5310         cmd="$LFS find -stripe-size 256k -type f $dir"
5311         nums=$($cmd | wc -l)
5312         [ $nums -eq $expected ] ||
5313                 error "'$cmd' wrong: found $nums, expected $expected"
5314
5315         cmd="$LFS find -stripe-size -320k -type f $dir"
5316         nums=$($cmd | wc -l)
5317         [ $nums -eq $expected ] ||
5318                 error "'$cmd' wrong: found $nums, expected $expected"
5319
5320         expected=0
5321         cmd="$LFS find -stripe-size 1024k -type f $dir"
5322         nums=$($cmd | wc -l)
5323         [ $nums -eq $expected ] ||
5324                 error "'$cmd' wrong: found $nums, expected $expected"
5325 }
5326 run_test 56t "check lfs find -stripe-size works"
5327
5328 test_56u() { # LU-611
5329         local dir=$DIR/$tdir
5330
5331         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5332
5333         if [[ $OSTCOUNT -gt 1 ]]; then
5334                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5335                 onestripe=4
5336         else
5337                 onestripe=0
5338         fi
5339
5340         local expected=$(((NUMDIRS + 1) * NUMFILES))
5341         local cmd="$LFS find -stripe-index 0 -type f $dir"
5342         local nums=$($cmd | wc -l)
5343
5344         [ $nums -eq $expected ] ||
5345                 error "'$cmd' wrong: found $nums, expected $expected"
5346
5347         expected=$onestripe
5348         cmd="$LFS find -stripe-index 1 -type f $dir"
5349         nums=$($cmd | wc -l)
5350         [ $nums -eq $expected ] ||
5351                 error "'$cmd' wrong: found $nums, expected $expected"
5352
5353         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5354         nums=$($cmd | wc -l)
5355         [ $nums -eq $expected ] ||
5356                 error "'$cmd' wrong: found $nums, expected $expected"
5357
5358         expected=0
5359         # This should produce an error and not return any files
5360         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5361         nums=$($cmd 2>/dev/null | wc -l)
5362         [ $nums -eq $expected ] ||
5363                 error "'$cmd' wrong: found $nums, expected $expected"
5364
5365         if [[ $OSTCOUNT -gt 1 ]]; then
5366                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5367                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5368                 nums=$($cmd | wc -l)
5369                 [ $nums -eq $expected ] ||
5370                         error "'$cmd' wrong: found $nums, expected $expected"
5371         fi
5372 }
5373 run_test 56u "check lfs find -stripe-index works"
5374
5375 test_56v() {
5376         local mdt_idx=0
5377         local dir=$DIR/$tdir
5378
5379         setup_56 $dir $NUMFILES $NUMDIRS
5380
5381         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5382         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5383
5384         for file in $($LFS find -m $UUID $dir); do
5385                 file_midx=$($LFS getstripe -m $file)
5386                 [ $file_midx -eq $mdt_idx ] ||
5387                         error "lfs find -m $UUID != getstripe -m $file_midx"
5388         done
5389 }
5390 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5391
5392 test_56w() {
5393         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5395
5396         local dir=$DIR/$tdir
5397
5398         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5399
5400         local stripe_size=$($LFS getstripe -S -d $dir) ||
5401                 error "$LFS getstripe -S -d $dir failed"
5402         stripe_size=${stripe_size%% *}
5403
5404         local file_size=$((stripe_size * OSTCOUNT))
5405         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5406         local required_space=$((file_num * file_size))
5407         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5408                            head -n1)
5409         [[ $free_space -le $((required_space / 1024)) ]] &&
5410                 skip_env "need $required_space, have $free_space kbytes"
5411
5412         local dd_bs=65536
5413         local dd_count=$((file_size / dd_bs))
5414
5415         # write data into the files
5416         local i
5417         local j
5418         local file
5419
5420         for i in $(seq $NUMFILES); do
5421                 file=$dir/file$i
5422                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5423                         error "write data into $file failed"
5424         done
5425         for i in $(seq $NUMDIRS); do
5426                 for j in $(seq $NUMFILES); do
5427                         file=$dir/dir$i/file$j
5428                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5429                                 error "write data into $file failed"
5430                 done
5431         done
5432
5433         # $LFS_MIGRATE will fail if hard link migration is unsupported
5434         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5435                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5436                         error "creating links to $dir/dir1/file1 failed"
5437         fi
5438
5439         local expected=-1
5440
5441         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5442
5443         # lfs_migrate file
5444         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5445
5446         echo "$cmd"
5447         eval $cmd || error "$cmd failed"
5448
5449         check_stripe_count $dir/file1 $expected
5450
5451         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5452         then
5453                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5454                 # OST 1 if it is on OST 0. This file is small enough to
5455                 # be on only one stripe.
5456                 file=$dir/migr_1_ost
5457                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5458                         error "write data into $file failed"
5459                 local obdidx=$($LFS getstripe -i $file)
5460                 local oldmd5=$(md5sum $file)
5461                 local newobdidx=0
5462
5463                 [[ $obdidx -eq 0 ]] && newobdidx=1
5464                 cmd="$LFS migrate -i $newobdidx $file"
5465                 echo $cmd
5466                 eval $cmd || error "$cmd failed"
5467
5468                 local realobdix=$($LFS getstripe -i $file)
5469                 local newmd5=$(md5sum $file)
5470
5471                 [[ $newobdidx -ne $realobdix ]] &&
5472                         error "new OST is different (was=$obdidx, "\
5473                               "wanted=$newobdidx, got=$realobdix)"
5474                 [[ "$oldmd5" != "$newmd5" ]] &&
5475                         error "md5sum differ: $oldmd5, $newmd5"
5476         fi
5477
5478         # lfs_migrate dir
5479         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5480         echo "$cmd"
5481         eval $cmd || error "$cmd failed"
5482
5483         for j in $(seq $NUMFILES); do
5484                 check_stripe_count $dir/dir1/file$j $expected
5485         done
5486
5487         # lfs_migrate works with lfs find
5488         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5489              $LFS_MIGRATE -y -c $expected"
5490         echo "$cmd"
5491         eval $cmd || error "$cmd failed"
5492
5493         for i in $(seq 2 $NUMFILES); do
5494                 check_stripe_count $dir/file$i $expected
5495         done
5496         for i in $(seq 2 $NUMDIRS); do
5497                 for j in $(seq $NUMFILES); do
5498                 check_stripe_count $dir/dir$i/file$j $expected
5499                 done
5500         done
5501 }
5502 run_test 56w "check lfs_migrate -c stripe_count works"
5503
5504 test_56wb() {
5505         local file1=$DIR/$tdir/file1
5506         local create_pool=false
5507         local initial_pool=$($LFS getstripe -p $DIR)
5508         local pool_list=()
5509         local pool=""
5510
5511         echo -n "Creating test dir..."
5512         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5513         echo "done."
5514
5515         echo -n "Creating test file..."
5516         touch $file1 || error "cannot create file"
5517         echo "done."
5518
5519         echo -n "Detecting existing pools..."
5520         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5521
5522         if [ ${#pool_list[@]} -gt 0 ]; then
5523                 echo "${pool_list[@]}"
5524                 for thispool in "${pool_list[@]}"; do
5525                         if [[ -z "$initial_pool" ||
5526                               "$initial_pool" != "$thispool" ]]; then
5527                                 pool="$thispool"
5528                                 echo "Using existing pool '$pool'"
5529                                 break
5530                         fi
5531                 done
5532         else
5533                 echo "none detected."
5534         fi
5535         if [ -z "$pool" ]; then
5536                 pool=${POOL:-testpool}
5537                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5538                 echo -n "Creating pool '$pool'..."
5539                 create_pool=true
5540                 pool_add $pool &> /dev/null ||
5541                         error "pool_add failed"
5542                 echo "done."
5543
5544                 echo -n "Adding target to pool..."
5545                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5546                         error "pool_add_targets failed"
5547                 echo "done."
5548         fi
5549
5550         echo -n "Setting pool using -p option..."
5551         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5552                 error "migrate failed rc = $?"
5553         echo "done."
5554
5555         echo -n "Verifying test file is in pool after migrating..."
5556         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5557                 error "file was not migrated to pool $pool"
5558         echo "done."
5559
5560         echo -n "Removing test file from pool '$pool'..."
5561         $LFS migrate $file1 &> /dev/null ||
5562                 error "cannot remove from pool"
5563         [ "$($LFS getstripe -p $file1)" ] &&
5564                 error "pool still set"
5565         echo "done."
5566
5567         echo -n "Setting pool using --pool option..."
5568         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5569                 error "migrate failed rc = $?"
5570         echo "done."
5571
5572         # Clean up
5573         rm -f $file1
5574         if $create_pool; then
5575                 destroy_test_pools 2> /dev/null ||
5576                         error "destroy test pools failed"
5577         fi
5578 }
5579 run_test 56wb "check lfs_migrate pool support"
5580
5581 test_56wc() {
5582         local file1="$DIR/$tdir/file1"
5583
5584         echo -n "Creating test dir..."
5585         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5586         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5587         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5588                 error "cannot set stripe"
5589         echo "done"
5590
5591         echo -n "Setting initial stripe for test file..."
5592         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5593                 error "cannot set stripe"
5594         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5595                 error "stripe size not set"
5596         echo "done."
5597
5598         # File currently set to -S 512K -c 1
5599
5600         # Ensure -c and -S options are rejected when -R is set
5601         echo -n "Verifying incompatible options are detected..."
5602         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5603                 error "incompatible -c and -R options not detected"
5604         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5605                 error "incompatible -S and -R options not detected"
5606         echo "done."
5607
5608         # Ensure unrecognized options are passed through to 'lfs migrate'
5609         echo -n "Verifying -S option is passed through to lfs migrate..."
5610         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5611                 error "migration failed"
5612         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5613                 error "file was not restriped"
5614         echo "done."
5615
5616         # File currently set to -S 1M -c 1
5617
5618         # Ensure long options are supported
5619         echo -n "Verifying long options supported..."
5620         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5621                 error "long option without argument not supported"
5622         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5623                 error "long option with argument not supported"
5624         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5625                 error "file not restriped with --stripe-size option"
5626         echo "done."
5627
5628         # File currently set to -S 512K -c 1
5629
5630         if [ "$OSTCOUNT" -gt 1 ]; then
5631                 echo -n "Verifying explicit stripe count can be set..."
5632                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5633                         error "migrate failed"
5634                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5635                         error "file not restriped to explicit count"
5636                 echo "done."
5637         fi
5638
5639         # File currently set to -S 512K -c 1 or -S 512K -c 2
5640
5641         # Ensure parent striping is used if -R is set, and no stripe
5642         # count or size is specified
5643         echo -n "Setting stripe for parent directory..."
5644         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5645                 error "cannot set stripe"
5646         echo "done."
5647
5648         echo -n "Verifying restripe option uses parent stripe settings..."
5649         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5650                 error "migrate failed"
5651         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5652                 error "file not restriped to parent settings"
5653         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5654                 error "file not restriped to parent settings"
5655         echo "done."
5656
5657         # File currently set to -S 1M -c 1
5658
5659         # Ensure striping is preserved if -R is not set, and no stripe
5660         # count or size is specified
5661         echo -n "Verifying striping size preserved when not specified..."
5662         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5663         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5664                 error "cannot set stripe on parent directory"
5665         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5666                 error "migrate failed"
5667         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5668                 error "file was restriped"
5669         echo "done."
5670
5671         # Ensure file name properly detected when final option has no argument
5672         echo -n "Verifying file name properly detected..."
5673         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5674                 error "file name interpreted as option argument"
5675         echo "done."
5676
5677         # Clean up
5678         rm -f "$file1"
5679 }
5680 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5681
5682 test_56wd() {
5683         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5684
5685         local file1=$DIR/$tdir/file1
5686
5687         echo -n "Creating test dir..."
5688         test_mkdir $DIR/$tdir || error "cannot create dir"
5689         echo "done."
5690
5691         echo -n "Creating test file..."
5692         touch $file1
5693         echo "done."
5694
5695         # Ensure 'lfs migrate' will fail by using a non-existent option,
5696         # and make sure rsync is not called to recover
5697         echo -n "Make sure --no-rsync option works..."
5698         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5699                 grep -q 'refusing to fall back to rsync' ||
5700                 error "rsync was called with --no-rsync set"
5701         echo "done."
5702
5703         # Ensure rsync is called without trying 'lfs migrate' first
5704         echo -n "Make sure --rsync option works..."
5705         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5706                 grep -q 'falling back to rsync' &&
5707                 error "lfs migrate was called with --rsync set"
5708         echo "done."
5709
5710         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5711         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5712                 grep -q 'at the same time' ||
5713                 error "--rsync and --no-rsync accepted concurrently"
5714         echo "done."
5715
5716         # Clean up
5717         rm -f $file1
5718 }
5719 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5720
5721 test_56x() {
5722         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5723         check_swap_layouts_support
5724
5725         local dir=$DIR/$tdir
5726         local ref1=/etc/passwd
5727         local file1=$dir/file1
5728
5729         test_mkdir $dir || error "creating dir $dir"
5730         $LFS setstripe -c 2 $file1
5731         cp $ref1 $file1
5732         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5733         stripe=$($LFS getstripe -c $file1)
5734         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5735         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5736
5737         # clean up
5738         rm -f $file1
5739 }
5740 run_test 56x "lfs migration support"
5741
5742 test_56xa() {
5743         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5744         check_swap_layouts_support
5745
5746         local dir=$DIR/$tdir/$testnum
5747
5748         test_mkdir -p $dir
5749
5750         local ref1=/etc/passwd
5751         local file1=$dir/file1
5752
5753         $LFS setstripe -c 2 $file1
5754         cp $ref1 $file1
5755         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5756
5757         local stripe=$($LFS getstripe -c $file1)
5758
5759         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5760         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5761
5762         # clean up
5763         rm -f $file1
5764 }
5765 run_test 56xa "lfs migration --block support"
5766
5767 check_migrate_links() {
5768         local dir="$1"
5769         local file1="$dir/file1"
5770         local begin="$2"
5771         local count="$3"
5772         local total_count=$(($begin + $count - 1))
5773         local symlink_count=10
5774         local uniq_count=10
5775
5776         if [ ! -f "$file1" ]; then
5777                 echo -n "creating initial file..."
5778                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5779                         error "cannot setstripe initial file"
5780                 echo "done"
5781
5782                 echo -n "creating symlinks..."
5783                 for s in $(seq 1 $symlink_count); do
5784                         ln -s "$file1" "$dir/slink$s" ||
5785                                 error "cannot create symlinks"
5786                 done
5787                 echo "done"
5788
5789                 echo -n "creating nonlinked files..."
5790                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5791                         error "cannot create nonlinked files"
5792                 echo "done"
5793         fi
5794
5795         # create hard links
5796         if [ ! -f "$dir/file$total_count" ]; then
5797                 echo -n "creating hard links $begin:$total_count..."
5798                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5799                         /dev/null || error "cannot create hard links"
5800                 echo "done"
5801         fi
5802
5803         echo -n "checking number of hard links listed in xattrs..."
5804         local fid=$($LFS getstripe -F "$file1")
5805         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5806
5807         echo "${#paths[*]}"
5808         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5809                         skip "hard link list has unexpected size, skipping test"
5810         fi
5811         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5812                         error "link names should exceed xattrs size"
5813         fi
5814
5815         echo -n "migrating files..."
5816         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5817         local rc=$?
5818         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5819         echo "done"
5820
5821         # make sure all links have been properly migrated
5822         echo -n "verifying files..."
5823         fid=$($LFS getstripe -F "$file1") ||
5824                 error "cannot get fid for file $file1"
5825         for i in $(seq 2 $total_count); do
5826                 local fid2=$($LFS getstripe -F $dir/file$i)
5827
5828                 [ "$fid2" == "$fid" ] ||
5829                         error "migrated hard link has mismatched FID"
5830         done
5831
5832         # make sure hard links were properly detected, and migration was
5833         # performed only once for the entire link set; nonlinked files should
5834         # also be migrated
5835         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5836         local expected=$(($uniq_count + 1))
5837
5838         [ "$actual" -eq  "$expected" ] ||
5839                 error "hard links individually migrated ($actual != $expected)"
5840
5841         # make sure the correct number of hard links are present
5842         local hardlinks=$(stat -c '%h' "$file1")
5843
5844         [ $hardlinks -eq $total_count ] ||
5845                 error "num hard links $hardlinks != $total_count"
5846         echo "done"
5847
5848         return 0
5849 }
5850
5851 test_56xb() {
5852         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5853                 skip "Need MDS version at least 2.10.55"
5854
5855         local dir="$DIR/$tdir"
5856
5857         test_mkdir "$dir" || error "cannot create dir $dir"
5858
5859         echo "testing lfs migrate mode when all links fit within xattrs"
5860         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5861
5862         echo "testing rsync mode when all links fit within xattrs"
5863         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5864
5865         echo "testing lfs migrate mode when all links do not fit within xattrs"
5866         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5867
5868         echo "testing rsync mode when all links do not fit within xattrs"
5869         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5870
5871
5872         # clean up
5873         rm -rf $dir
5874 }
5875 run_test 56xb "lfs migration hard link support"
5876
5877 test_56xc() {
5878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5879
5880         local dir="$DIR/$tdir"
5881
5882         test_mkdir "$dir" || error "cannot create dir $dir"
5883
5884         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5885         echo -n "Setting initial stripe for 20MB test file..."
5886         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5887         echo "done"
5888         echo -n "Sizing 20MB test file..."
5889         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5890         echo "done"
5891         echo -n "Verifying small file autostripe count is 1..."
5892         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5893                 error "cannot migrate 20MB file"
5894         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5895                 error "cannot get stripe for $dir/20mb"
5896         [ $stripe_count -eq 1 ] ||
5897                 error "unexpected stripe count $stripe_count for 20MB file"
5898         rm -f "$dir/20mb"
5899         echo "done"
5900
5901         # Test 2: File is small enough to fit within the available space on
5902         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5903         # have at least an additional 1KB for each desired stripe for test 3
5904         echo -n "Setting stripe for 1GB test file..."
5905         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5906         echo "done"
5907         echo -n "Sizing 1GB test file..."
5908         # File size is 1GB + 3KB
5909         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5910                 error "cannot create 1GB test file"
5911         echo "done"
5912         echo -n "Migrating 1GB file..."
5913         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5914                 error "cannot migrate file"
5915         echo "done"
5916         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5917         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5918                 error "cannot get stripe for $dir/1gb"
5919         [ $stripe_count -eq 2 ] ||
5920                 error "unexpected stripe count $stripe_count (expected 2)"
5921         echo "done"
5922
5923         # Test 3: File is too large to fit within the available space on
5924         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5925         if [ $OSTCOUNT -ge 3 ]; then
5926                 # The required available space is calculated as
5927                 # file size (1GB + 3KB) / OST count (3).
5928                 local kb_per_ost=349526
5929
5930                 echo -n "Migrating 1GB file..."
5931                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5932                         /dev/null || error "cannot migrate file"
5933                 echo "done"
5934
5935                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5936                 echo -n "Verifying autostripe count with limited space..."
5937                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5938                         error "unexpected stripe count $stripe_count (wanted 3)"
5939                 echo "done"
5940         fi
5941
5942         # clean up
5943         rm -rf $dir
5944 }
5945 run_test 56xc "lfs migration autostripe"
5946
5947 test_56y() {
5948         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5949                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5950
5951         local res=""
5952         local dir=$DIR/$tdir
5953         local f1=$dir/file1
5954         local f2=$dir/file2
5955
5956         test_mkdir -p $dir || error "creating dir $dir"
5957         touch $f1 || error "creating std file $f1"
5958         $MULTIOP $f2 H2c || error "creating released file $f2"
5959
5960         # a directory can be raid0, so ask only for files
5961         res=$($LFS find $dir -L raid0 -type f | wc -l)
5962         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5963
5964         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5965         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5966
5967         # only files can be released, so no need to force file search
5968         res=$($LFS find $dir -L released)
5969         [[ $res == $f2 ]] || error "search released: found $res != $f2"
5970
5971         res=$($LFS find $dir -type f \! -L released)
5972         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
5973 }
5974 run_test 56y "lfs find -L raid0|released"
5975
5976 test_56z() { # LU-4824
5977         # This checks to make sure 'lfs find' continues after errors
5978         # There are two classes of errors that should be caught:
5979         # - If multiple paths are provided, all should be searched even if one
5980         #   errors out
5981         # - If errors are encountered during the search, it should not terminate
5982         #   early
5983         local dir=$DIR/$tdir
5984         local i
5985
5986         test_mkdir $dir
5987         for i in d{0..9}; do
5988                 test_mkdir $dir/$i
5989         done
5990         touch $dir/d{0..9}/$tfile
5991         $LFS find $DIR/non_existent_dir $dir &&
5992                 error "$LFS find did not return an error"
5993         # Make a directory unsearchable. This should NOT be the last entry in
5994         # directory order.  Arbitrarily pick the 6th entry
5995         chmod 700 $($LFS find $dir -type d | sed '6!d')
5996
5997         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
5998
5999         # The user should be able to see 10 directories and 9 files
6000         [ $count == 19 ] || error "$LFS find did not continue after error"
6001 }
6002 run_test 56z "lfs find should continue after an error"
6003
6004 test_56aa() { # LU-5937
6005         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6006
6007         local dir=$DIR/$tdir
6008
6009         mkdir $dir
6010         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6011
6012         createmany -o $dir/striped_dir/${tfile}- 1024
6013         local dirs=$($LFS find --size +8k $dir/)
6014
6015         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6016 }
6017 run_test 56aa "lfs find --size under striped dir"
6018
6019 test_56ab() { # LU-10705
6020         test_mkdir $DIR/$tdir
6021         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6022         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6023         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6024         # Flush writes to ensure valid blocks.  Need to be more thorough for
6025         # ZFS, since blocks are not allocated/returned to client immediately.
6026         sync_all_data
6027         wait_zfs_commit ost1 2
6028         cancel_lru_locks osc
6029         ls -ls $DIR/$tdir
6030
6031         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6032
6033         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6034
6035         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6036         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6037
6038         rm -f $DIR/$tdir/$tfile.[123]
6039 }
6040 run_test 56ab "lfs find --blocks"
6041
6042 test_56ba() {
6043         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6044                 skip "Need MDS version at least 2.10.50"
6045
6046         # Create composite files with one component
6047         local dir=$DIR/$tdir
6048
6049         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6050         # Create composite files with three components
6051         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6052         # Create non-composite files
6053         createmany -o $dir/${tfile}- 10
6054
6055         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6056
6057         [[ $nfiles == 10 ]] ||
6058                 error "lfs find -E 1M found $nfiles != 10 files"
6059
6060         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6061         [[ $nfiles == 25 ]] ||
6062                 error "lfs find ! -E 1M found $nfiles != 25 files"
6063
6064         # All files have a component that starts at 0
6065         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6066         [[ $nfiles == 35 ]] ||
6067                 error "lfs find --component-start 0 - $nfiles != 35 files"
6068
6069         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6070         [[ $nfiles == 15 ]] ||
6071                 error "lfs find --component-start 2M - $nfiles != 15 files"
6072
6073         # All files created here have a componenet that does not starts at 2M
6074         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6075         [[ $nfiles == 35 ]] ||
6076                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6077
6078         # Find files with a specified number of components
6079         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6080         [[ $nfiles == 15 ]] ||
6081                 error "lfs find --component-count 3 - $nfiles != 15 files"
6082
6083         # Remember non-composite files have a component count of zero
6084         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6085         [[ $nfiles == 10 ]] ||
6086                 error "lfs find --component-count 0 - $nfiles != 10 files"
6087
6088         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6089         [[ $nfiles == 20 ]] ||
6090                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6091
6092         # All files have a flag called "init"
6093         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6094         [[ $nfiles == 35 ]] ||
6095                 error "lfs find --component-flags init - $nfiles != 35 files"
6096
6097         # Multi-component files will have a component not initialized
6098         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6099         [[ $nfiles == 15 ]] ||
6100                 error "lfs find !--component-flags init - $nfiles != 15 files"
6101
6102         rm -rf $dir
6103
6104 }
6105 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6106
6107 test_56ca() {
6108         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6109                 skip "Need MDS version at least 2.10.57"
6110
6111         local td=$DIR/$tdir
6112         local tf=$td/$tfile
6113         local dir
6114         local nfiles
6115         local cmd
6116         local i
6117         local j
6118
6119         # create mirrored directories and mirrored files
6120         mkdir $td || error "mkdir $td failed"
6121         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6122         createmany -o $tf- 10 || error "create $tf- failed"
6123
6124         for i in $(seq 2); do
6125                 dir=$td/dir$i
6126                 mkdir $dir || error "mkdir $dir failed"
6127                 $LFS mirror create -N$((3 + i)) $dir ||
6128                         error "create mirrored dir $dir failed"
6129                 createmany -o $dir/$tfile- 10 ||
6130                         error "create $dir/$tfile- failed"
6131         done
6132
6133         # change the states of some mirrored files
6134         echo foo > $tf-6
6135         for i in $(seq 2); do
6136                 dir=$td/dir$i
6137                 for j in $(seq 4 9); do
6138                         echo foo > $dir/$tfile-$j
6139                 done
6140         done
6141
6142         # find mirrored files with specific mirror count
6143         cmd="$LFS find --mirror-count 3 --type f $td"
6144         nfiles=$($cmd | wc -l)
6145         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6146
6147         cmd="$LFS find ! --mirror-count 3 --type f $td"
6148         nfiles=$($cmd | wc -l)
6149         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6150
6151         cmd="$LFS find --mirror-count +2 --type f $td"
6152         nfiles=$($cmd | wc -l)
6153         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6154
6155         cmd="$LFS find --mirror-count -6 --type f $td"
6156         nfiles=$($cmd | wc -l)
6157         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6158
6159         # find mirrored files with specific file state
6160         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6161         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6162
6163         cmd="$LFS find --mirror-state=ro --type f $td"
6164         nfiles=$($cmd | wc -l)
6165         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6166
6167         cmd="$LFS find ! --mirror-state=ro --type f $td"
6168         nfiles=$($cmd | wc -l)
6169         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6170
6171         cmd="$LFS find --mirror-state=wp --type f $td"
6172         nfiles=$($cmd | wc -l)
6173         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6174
6175         cmd="$LFS find ! --mirror-state=sp --type f $td"
6176         nfiles=$($cmd | wc -l)
6177         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6178 }
6179 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6180
6181 test_57a() {
6182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6183         # note test will not do anything if MDS is not local
6184         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6185                 skip_env "ldiskfs only test"
6186         fi
6187         remote_mds_nodsh && skip "remote MDS with nodsh"
6188
6189         local MNTDEV="osd*.*MDT*.mntdev"
6190         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6191         [ -z "$DEV" ] && error "can't access $MNTDEV"
6192         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6193                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6194                         error "can't access $DEV"
6195                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6196                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6197                 rm $TMP/t57a.dump
6198         done
6199 }
6200 run_test 57a "verify MDS filesystem created with large inodes =="
6201
6202 test_57b() {
6203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6204         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6205                 skip_env "ldiskfs only test"
6206         fi
6207         remote_mds_nodsh && skip "remote MDS with nodsh"
6208
6209         local dir=$DIR/$tdir
6210         local filecount=100
6211         local file1=$dir/f1
6212         local fileN=$dir/f$filecount
6213
6214         rm -rf $dir || error "removing $dir"
6215         test_mkdir -c1 $dir
6216         local mdtidx=$($LFS getstripe -m $dir)
6217         local mdtname=MDT$(printf %04x $mdtidx)
6218         local facet=mds$((mdtidx + 1))
6219
6220         echo "mcreating $filecount files"
6221         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6222
6223         # verify that files do not have EAs yet
6224         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6225                 error "$file1 has an EA"
6226         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6227                 error "$fileN has an EA"
6228
6229         sync
6230         sleep 1
6231         df $dir  #make sure we get new statfs data
6232         local mdsfree=$(do_facet $facet \
6233                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6234         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6235         local file
6236
6237         echo "opening files to create objects/EAs"
6238         for file in $(seq -f $dir/f%g 1 $filecount); do
6239                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6240                         error "opening $file"
6241         done
6242
6243         # verify that files have EAs now
6244         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6245         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6246
6247         sleep 1  #make sure we get new statfs data
6248         df $dir
6249         local mdsfree2=$(do_facet $facet \
6250                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6251         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6252
6253         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6254                 if [ "$mdsfree" != "$mdsfree2" ]; then
6255                         error "MDC before $mdcfree != after $mdcfree2"
6256                 else
6257                         echo "MDC before $mdcfree != after $mdcfree2"
6258                         echo "unable to confirm if MDS has large inodes"
6259                 fi
6260         fi
6261         rm -rf $dir
6262 }
6263 run_test 57b "default LOV EAs are stored inside large inodes ==="
6264
6265 test_58() {
6266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6267         [ -z "$(which wiretest 2>/dev/null)" ] &&
6268                         skip_env "could not find wiretest"
6269
6270         wiretest
6271 }
6272 run_test 58 "verify cross-platform wire constants =============="
6273
6274 test_59() {
6275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6276
6277         echo "touch 130 files"
6278         createmany -o $DIR/f59- 130
6279         echo "rm 130 files"
6280         unlinkmany $DIR/f59- 130
6281         sync
6282         # wait for commitment of removal
6283         wait_delete_completed
6284 }
6285 run_test 59 "verify cancellation of llog records async ========="
6286
6287 TEST60_HEAD="test_60 run $RANDOM"
6288 test_60a() {
6289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6290         remote_mgs_nodsh && skip "remote MGS with nodsh"
6291         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6292                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6293                         skip_env "missing subtest run-llog.sh"
6294
6295         log "$TEST60_HEAD - from kernel mode"
6296         do_facet mgs "$LCTL dk > /dev/null"
6297         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6298         do_facet mgs $LCTL dk > $TMP/$tfile
6299
6300         # LU-6388: test llog_reader
6301         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6302         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6303         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6304                         skip_env "missing llog_reader"
6305         local fstype=$(facet_fstype mgs)
6306         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6307                 skip_env "Only for ldiskfs or zfs type mgs"
6308
6309         local mntpt=$(facet_mntpt mgs)
6310         local mgsdev=$(mgsdevname 1)
6311         local fid_list
6312         local fid
6313         local rec_list
6314         local rec
6315         local rec_type
6316         local obj_file
6317         local path
6318         local seq
6319         local oid
6320         local pass=true
6321
6322         #get fid and record list
6323         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6324                 tail -n 4))
6325         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6326                 tail -n 4))
6327         #remount mgs as ldiskfs or zfs type
6328         stop mgs || error "stop mgs failed"
6329         mount_fstype mgs || error "remount mgs failed"
6330         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6331                 fid=${fid_list[i]}
6332                 rec=${rec_list[i]}
6333                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6334                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6335                 oid=$((16#$oid))
6336
6337                 case $fstype in
6338                         ldiskfs )
6339                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6340                         zfs )
6341                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6342                 esac
6343                 echo "obj_file is $obj_file"
6344                 do_facet mgs $llog_reader $obj_file
6345
6346                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6347                         awk '{ print $3 }' | sed -e "s/^type=//g")
6348                 if [ $rec_type != $rec ]; then
6349                         echo "FAILED test_60a wrong record type $rec_type," \
6350                               "should be $rec"
6351                         pass=false
6352                         break
6353                 fi
6354
6355                 #check obj path if record type is LLOG_LOGID_MAGIC
6356                 if [ "$rec" == "1064553b" ]; then
6357                         path=$(do_facet mgs $llog_reader $obj_file |
6358                                 grep "path=" | awk '{ print $NF }' |
6359                                 sed -e "s/^path=//g")
6360                         if [ $obj_file != $mntpt/$path ]; then
6361                                 echo "FAILED test_60a wrong obj path" \
6362                                       "$montpt/$path, should be $obj_file"
6363                                 pass=false
6364                                 break
6365                         fi
6366                 fi
6367         done
6368         rm -f $TMP/$tfile
6369         #restart mgs before "error", otherwise it will block the next test
6370         stop mgs || error "stop mgs failed"
6371         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6372         $pass || error "test failed, see FAILED test_60a messages for specifics"
6373 }
6374 run_test 60a "llog_test run from kernel module and test llog_reader"
6375
6376 test_60b() { # bug 6411
6377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6378
6379         dmesg > $DIR/$tfile
6380         LLOG_COUNT=$(do_facet mgs dmesg |
6381                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6382                           /llog_[a-z]*.c:[0-9]/ {
6383                                 if (marker)
6384                                         from_marker++
6385                                 from_begin++
6386                           }
6387                           END {
6388                                 if (marker)
6389                                         print from_marker
6390                                 else
6391                                         print from_begin
6392                           }")
6393
6394         [[ $LLOG_COUNT -gt 120 ]] &&
6395                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6396 }
6397 run_test 60b "limit repeated messages from CERROR/CWARN"
6398
6399 test_60c() {
6400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6401
6402         echo "create 5000 files"
6403         createmany -o $DIR/f60c- 5000
6404 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6405         lctl set_param fail_loc=0x80000137
6406         unlinkmany $DIR/f60c- 5000
6407         lctl set_param fail_loc=0
6408 }
6409 run_test 60c "unlink file when mds full"
6410
6411 test_60d() {
6412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6413
6414         SAVEPRINTK=$(lctl get_param -n printk)
6415         # verify "lctl mark" is even working"
6416         MESSAGE="test message ID $RANDOM $$"
6417         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6418         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6419
6420         lctl set_param printk=0 || error "set lnet.printk failed"
6421         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6422         MESSAGE="new test message ID $RANDOM $$"
6423         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6424         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6425         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6426
6427         lctl set_param -n printk="$SAVEPRINTK"
6428 }
6429 run_test 60d "test printk console message masking"
6430
6431 test_60e() {
6432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6433         remote_mds_nodsh && skip "remote MDS with nodsh"
6434
6435         touch $DIR/$tfile
6436 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6437         do_facet mds1 lctl set_param fail_loc=0x15b
6438         rm $DIR/$tfile
6439 }
6440 run_test 60e "no space while new llog is being created"
6441
6442 test_60g() {
6443         local pid
6444
6445         test_mkdir -c $MDSCOUNT $DIR/$tdir
6446         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6447
6448         (
6449                 local index=0
6450                 while true; do
6451                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6452                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6453                         index=$((index + 1))
6454                 done
6455         ) &
6456
6457         pid=$!
6458
6459         for i in $(seq 100); do 
6460                 # define OBD_FAIL_OSD_TXN_START    0x19a
6461                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6462                 usleep 100
6463         done
6464
6465         kill -9 $pid
6466
6467         mkdir $DIR/$tdir/new || error "mkdir failed"
6468         rmdir $DIR/$tdir/new || error "rmdir failed"
6469 }
6470 run_test 60g "transaction abort won't cause MDT hung"
6471
6472 test_61a() {
6473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6474
6475         f="$DIR/f61"
6476         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6477         cancel_lru_locks osc
6478         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6479         sync
6480 }
6481 run_test 61a "mmap() writes don't make sync hang ================"
6482
6483 test_61b() {
6484         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6485 }
6486 run_test 61b "mmap() of unstriped file is successful"
6487
6488 # bug 2330 - insufficient obd_match error checking causes LBUG
6489 test_62() {
6490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6491
6492         f="$DIR/f62"
6493         echo foo > $f
6494         cancel_lru_locks osc
6495         lctl set_param fail_loc=0x405
6496         cat $f && error "cat succeeded, expect -EIO"
6497         lctl set_param fail_loc=0
6498 }
6499 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6500 # match every page all of the time.
6501 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6502
6503 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6504 # Though this test is irrelevant anymore, it helped to reveal some
6505 # other grant bugs (LU-4482), let's keep it.
6506 test_63a() {   # was test_63
6507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6508
6509         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6510
6511         for i in `seq 10` ; do
6512                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6513                 sleep 5
6514                 kill $!
6515                 sleep 1
6516         done
6517
6518         rm -f $DIR/f63 || true
6519 }
6520 run_test 63a "Verify oig_wait interruption does not crash ======="
6521
6522 # bug 2248 - async write errors didn't return to application on sync
6523 # bug 3677 - async write errors left page locked
6524 test_63b() {
6525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6526
6527         debugsave
6528         lctl set_param debug=-1
6529
6530         # ensure we have a grant to do async writes
6531         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6532         rm $DIR/$tfile
6533
6534         sync    # sync lest earlier test intercept the fail_loc
6535
6536         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6537         lctl set_param fail_loc=0x80000406
6538         $MULTIOP $DIR/$tfile Owy && \
6539                 error "sync didn't return ENOMEM"
6540         sync; sleep 2; sync     # do a real sync this time to flush page
6541         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6542                 error "locked page left in cache after async error" || true
6543         debugrestore
6544 }
6545 run_test 63b "async write errors should be returned to fsync ==="
6546
6547 test_64a () {
6548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6549
6550         df $DIR
6551         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6552 }
6553 run_test 64a "verify filter grant calculations (in kernel) ====="
6554
6555 test_64b () {
6556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6557
6558         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6559 }
6560 run_test 64b "check out-of-space detection on client"
6561
6562 test_64c() {
6563         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6564 }
6565 run_test 64c "verify grant shrink"
6566
6567 # this does exactly what osc_request.c:osc_announce_cached() does in
6568 # order to calculate max amount of grants to ask from server
6569 want_grant() {
6570         local tgt=$1
6571
6572         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6573         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6574
6575         ((rpc_in_flight ++));
6576         nrpages=$((nrpages * rpc_in_flight))
6577
6578         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6579
6580         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6581
6582         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6583         local undirty=$((nrpages * PAGE_SIZE))
6584
6585         local max_extent_pages
6586         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6587             grep grant_max_extent_size | awk '{print $2}')
6588         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6589         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6590         local grant_extent_tax
6591         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6592             grep grant_extent_tax | awk '{print $2}')
6593
6594         undirty=$((undirty + nrextents * grant_extent_tax))
6595
6596         echo $undirty
6597 }
6598
6599 # this is size of unit for grant allocation. It should be equal to
6600 # what tgt_grant.c:tgt_grant_chunk() calculates
6601 grant_chunk() {
6602         local tgt=$1
6603         local max_brw_size
6604         local grant_extent_tax
6605
6606         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6607             grep max_brw_size | awk '{print $2}')
6608
6609         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6610             grep grant_extent_tax | awk '{print $2}')
6611
6612         echo $(((max_brw_size + grant_extent_tax) * 2))
6613 }
6614
6615 test_64d() {
6616         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6617                 skip "OST < 2.10.55 doesn't limit grants enough"
6618
6619         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6620         local file=$DIR/$tfile
6621
6622         [[ $($LCTL get_param osc.${tgt}.import |
6623              grep "connect_flags:.*grant_param") ]] ||
6624                 skip "no grant_param connect flag"
6625
6626         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6627
6628         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6629
6630         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6631         stack_trap "rm -f $file" EXIT
6632
6633         $LFS setstripe $file -i 0 -c 1
6634         dd if=/dev/zero of=$file bs=1M count=1000 &
6635         ddpid=$!
6636
6637         while true
6638         do
6639                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6640                 if [[ $cur_grant -gt $max_cur_granted ]]
6641                 then
6642                         kill $ddpid
6643                         error "cur_grant $cur_grant > $max_cur_granted"
6644                 fi
6645                 kill -0 $ddpid
6646                 [[ $? -ne 0 ]] && break;
6647                 sleep 2
6648         done
6649
6650         rm -f $DIR/$tfile
6651         wait_delete_completed
6652         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6653 }
6654 run_test 64d "check grant limit exceed"
6655
6656 # bug 1414 - set/get directories' stripe info
6657 test_65a() {
6658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6659
6660         test_mkdir $DIR/$tdir
6661         touch $DIR/$tdir/f1
6662         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6663 }
6664 run_test 65a "directory with no stripe info"
6665
6666 test_65b() {
6667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6668
6669         test_mkdir $DIR/$tdir
6670         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6671
6672         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6673                                                 error "setstripe"
6674         touch $DIR/$tdir/f2
6675         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6676 }
6677 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6678
6679 test_65c() {
6680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6681         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6682
6683         test_mkdir $DIR/$tdir
6684         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6685
6686         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6687                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6688         touch $DIR/$tdir/f3
6689         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6690 }
6691 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6692
6693 test_65d() {
6694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6695
6696         test_mkdir $DIR/$tdir
6697         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6698         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6699
6700         if [[ $STRIPECOUNT -le 0 ]]; then
6701                 sc=1
6702         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6703 #LOV_MAX_STRIPE_COUNT is 2000
6704                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6705         else
6706                 sc=$(($STRIPECOUNT - 1))
6707         fi
6708         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6709         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6710         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6711                 error "lverify failed"
6712 }
6713 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6714
6715 test_65e() {
6716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6717
6718         test_mkdir $DIR/$tdir
6719
6720         $LFS setstripe $DIR/$tdir || error "setstripe"
6721         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6722                                         error "no stripe info failed"
6723         touch $DIR/$tdir/f6
6724         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6725 }
6726 run_test 65e "directory setstripe defaults"
6727
6728 test_65f() {
6729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6730
6731         test_mkdir $DIR/${tdir}f
6732         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6733                 error "setstripe succeeded" || true
6734 }
6735 run_test 65f "dir setstripe permission (should return error) ==="
6736
6737 test_65g() {
6738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6739
6740         test_mkdir $DIR/$tdir
6741         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6742
6743         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6744                 error "setstripe -S failed"
6745         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6746         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6747                 error "delete default stripe failed"
6748 }
6749 run_test 65g "directory setstripe -d"
6750
6751 test_65h() {
6752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6753
6754         test_mkdir $DIR/$tdir
6755         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6756
6757         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6758                 error "setstripe -S failed"
6759         test_mkdir $DIR/$tdir/dd1
6760         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6761                 error "stripe info inherit failed"
6762 }
6763 run_test 65h "directory stripe info inherit ===================="
6764
6765 test_65i() {
6766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6767
6768         save_layout_restore_at_exit $MOUNT
6769
6770         # bug6367: set non-default striping on root directory
6771         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6772
6773         # bug12836: getstripe on -1 default directory striping
6774         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6775
6776         # bug12836: getstripe -v on -1 default directory striping
6777         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6778
6779         # bug12836: new find on -1 default directory striping
6780         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6781 }
6782 run_test 65i "various tests to set root directory striping"
6783
6784 test_65j() { # bug6367
6785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6786
6787         sync; sleep 1
6788
6789         # if we aren't already remounting for each test, do so for this test
6790         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6791                 cleanup || error "failed to unmount"
6792                 setup
6793         fi
6794
6795         save_layout_restore_at_exit $MOUNT
6796
6797         $LFS setstripe -d $MOUNT || error "setstripe failed"
6798 }
6799 run_test 65j "set default striping on root directory (bug 6367)="
6800
6801 cleanup_65k() {
6802         rm -rf $DIR/$tdir
6803         wait_delete_completed
6804         do_facet $SINGLEMDS "lctl set_param -n \
6805                 osp.$ost*MDT0000.max_create_count=$max_count"
6806         do_facet $SINGLEMDS "lctl set_param -n \
6807                 osp.$ost*MDT0000.create_count=$count"
6808         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6809         echo $INACTIVE_OSC "is Activate"
6810
6811         wait_osc_import_state mds ost$ostnum FULL
6812 }
6813
6814 test_65k() { # bug11679
6815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6817         remote_mds_nodsh && skip "remote MDS with nodsh"
6818
6819         local disable_precreate=true
6820         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6821                 disable_precreate=false
6822
6823         echo "Check OST status: "
6824         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6825                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6826
6827         for OSC in $MDS_OSCS; do
6828                 echo $OSC "is active"
6829                 do_facet $SINGLEMDS lctl --device %$OSC activate
6830         done
6831
6832         for INACTIVE_OSC in $MDS_OSCS; do
6833                 local ost=$(osc_to_ost $INACTIVE_OSC)
6834                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6835                                lov.*md*.target_obd |
6836                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6837
6838                 mkdir -p $DIR/$tdir
6839                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6840                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6841
6842                 echo "Deactivate: " $INACTIVE_OSC
6843                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6844
6845                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6846                               osp.$ost*MDT0000.create_count")
6847                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6848                                   osp.$ost*MDT0000.max_create_count")
6849                 $disable_precreate &&
6850                         do_facet $SINGLEMDS "lctl set_param -n \
6851                                 osp.$ost*MDT0000.max_create_count=0"
6852
6853                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6854                         [ -f $DIR/$tdir/$idx ] && continue
6855                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6856                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6857                                 { cleanup_65k;
6858                                   error "setstripe $idx should succeed"; }
6859                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6860                 done
6861                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6862                 rmdir $DIR/$tdir
6863
6864                 do_facet $SINGLEMDS "lctl set_param -n \
6865                         osp.$ost*MDT0000.max_create_count=$max_count"
6866                 do_facet $SINGLEMDS "lctl set_param -n \
6867                         osp.$ost*MDT0000.create_count=$count"
6868                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6869                 echo $INACTIVE_OSC "is Activate"
6870
6871                 wait_osc_import_state mds ost$ostnum FULL
6872         done
6873 }
6874 run_test 65k "validate manual striping works properly with deactivated OSCs"
6875
6876 test_65l() { # bug 12836
6877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6878
6879         test_mkdir -p $DIR/$tdir/test_dir
6880         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6881         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6882 }
6883 run_test 65l "lfs find on -1 stripe dir ========================"
6884
6885 test_65m() {
6886         local layout=$(save_layout $MOUNT)
6887         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6888                 restore_layout $MOUNT $layout
6889                 error "setstripe should fail by non-root users"
6890         }
6891         true
6892 }
6893 run_test 65m "normal user can't set filesystem default stripe"
6894
6895 test_65n() {
6896         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6897         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6898                 skip "Need MDS version at least 2.12.50"
6899         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6900
6901         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6902         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6903         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6904
6905         local root_layout=$(save_layout $MOUNT)
6906         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6907
6908         # new subdirectory under root directory should not inherit
6909         # the default layout from root
6910         local dir1=$MOUNT/$tdir-1
6911         mkdir $dir1 || error "mkdir $dir1 failed"
6912         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6913                 error "$dir1 shouldn't have LOV EA"
6914
6915         # delete the default layout on root directory
6916         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6917
6918         local dir2=$MOUNT/$tdir-2
6919         mkdir $dir2 || error "mkdir $dir2 failed"
6920         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6921                 error "$dir2 shouldn't have LOV EA"
6922
6923         # set a new striping pattern on root directory
6924         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6925         local new_def_stripe_size=$((def_stripe_size * 2))
6926         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6927                 error "set stripe size on $MOUNT failed"
6928
6929         # new file created in $dir2 should inherit the new stripe size from
6930         # the filesystem default
6931         local file2=$dir2/$tfile-2
6932         touch $file2 || error "touch $file2 failed"
6933
6934         local file2_stripe_size=$($LFS getstripe -S $file2)
6935         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6936                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6937
6938         local dir3=$MOUNT/$tdir-3
6939         mkdir $dir3 || error "mkdir $dir3 failed"
6940         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6941                 error "$dir3 shouldn't have LOV EA"
6942
6943         # set OST pool on root directory
6944         local pool=$TESTNAME
6945         pool_add $pool || error "add $pool failed"
6946         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6947                 error "add targets to $pool failed"
6948
6949         $LFS setstripe -p $pool $MOUNT ||
6950                 error "set OST pool on $MOUNT failed"
6951
6952         # new file created in $dir3 should inherit the pool from
6953         # the filesystem default
6954         local file3=$dir3/$tfile-3
6955         touch $file3 || error "touch $file3 failed"
6956
6957         local file3_pool=$($LFS getstripe -p $file3)
6958         [[ "$file3_pool" = "$pool" ]] ||
6959                 error "$file3 didn't inherit OST pool $pool"
6960
6961         local dir4=$MOUNT/$tdir-4
6962         mkdir $dir4 || error "mkdir $dir4 failed"
6963         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6964                 error "$dir4 shouldn't have LOV EA"
6965
6966         # new file created in $dir4 should inherit the pool from
6967         # the filesystem default
6968         local file4=$dir4/$tfile-4
6969         touch $file4 || error "touch $file4 failed"
6970
6971         local file4_pool=$($LFS getstripe -p $file4)
6972         [[ "$file4_pool" = "$pool" ]] ||
6973                 error "$file4 didn't inherit OST pool $pool"
6974
6975         # new subdirectory under non-root directory should inherit
6976         # the default layout from its parent directory
6977         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
6978                 error "set directory layout on $dir4 failed"
6979
6980         local dir5=$dir4/$tdir-5
6981         mkdir $dir5 || error "mkdir $dir5 failed"
6982
6983         local dir4_layout=$(get_layout_param $dir4)
6984         local dir5_layout=$(get_layout_param $dir5)
6985         [[ "$dir4_layout" = "$dir5_layout" ]] ||
6986                 error "$dir5 should inherit the default layout from $dir4"
6987 }
6988 run_test 65n "don't inherit default layout from root for new subdirectories"
6989
6990 # bug 2543 - update blocks count on client
6991 test_66() {
6992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6993
6994         COUNT=${COUNT:-8}
6995         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
6996         sync; sync_all_data; sync; sync_all_data
6997         cancel_lru_locks osc
6998         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
6999         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7000 }
7001 run_test 66 "update inode blocks count on client ==============="
7002
7003 meminfo() {
7004         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7005 }
7006
7007 swap_used() {
7008         swapon -s | awk '($1 == "'$1'") { print $4 }'
7009 }
7010
7011 # bug5265, obdfilter oa2dentry return -ENOENT
7012 # #define OBD_FAIL_SRV_ENOENT 0x217
7013 test_69() {
7014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7015         remote_ost_nodsh && skip "remote OST with nodsh"
7016
7017         f="$DIR/$tfile"
7018         $LFS setstripe -c 1 -i 0 $f
7019
7020         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7021
7022         do_facet ost1 lctl set_param fail_loc=0x217
7023         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7024         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7025
7026         do_facet ost1 lctl set_param fail_loc=0
7027         $DIRECTIO write $f 0 2 || error "write error"
7028
7029         cancel_lru_locks osc
7030         $DIRECTIO read $f 0 1 || error "read error"
7031
7032         do_facet ost1 lctl set_param fail_loc=0x217
7033         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7034
7035         do_facet ost1 lctl set_param fail_loc=0
7036         rm -f $f
7037 }
7038 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7039
7040 test_71() {
7041         test_mkdir $DIR/$tdir
7042         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7043         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7044 }
7045 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7046
7047 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7049         [ "$RUNAS_ID" = "$UID" ] &&
7050                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7051         # Check that testing environment is properly set up. Skip if not
7052         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7053                 skip_env "User $RUNAS_ID does not exist - skipping"
7054
7055         touch $DIR/$tfile
7056         chmod 777 $DIR/$tfile
7057         chmod ug+s $DIR/$tfile
7058         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7059                 error "$RUNAS dd $DIR/$tfile failed"
7060         # See if we are still setuid/sgid
7061         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7062                 error "S/gid is not dropped on write"
7063         # Now test that MDS is updated too
7064         cancel_lru_locks mdc
7065         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7066                 error "S/gid is not dropped on MDS"
7067         rm -f $DIR/$tfile
7068 }
7069 run_test 72a "Test that remove suid works properly (bug5695) ===="
7070
7071 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7072         local perm
7073
7074         [ "$RUNAS_ID" = "$UID" ] &&
7075                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7076         [ "$RUNAS_ID" -eq 0 ] &&
7077                 skip_env "RUNAS_ID = 0 -- skipping"
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079         # Check that testing environment is properly set up. Skip if not
7080         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7081                 skip_env "User $RUNAS_ID does not exist - skipping"
7082
7083         touch $DIR/${tfile}-f{g,u}
7084         test_mkdir $DIR/${tfile}-dg
7085         test_mkdir $DIR/${tfile}-du
7086         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7087         chmod g+s $DIR/${tfile}-{f,d}g
7088         chmod u+s $DIR/${tfile}-{f,d}u
7089         for perm in 777 2777 4777; do
7090                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7091                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7092                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7093                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7094         done
7095         true
7096 }
7097 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7098
7099 # bug 3462 - multiple simultaneous MDC requests
7100 test_73() {
7101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7102
7103         test_mkdir $DIR/d73-1
7104         test_mkdir $DIR/d73-2
7105         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7106         pid1=$!
7107
7108         lctl set_param fail_loc=0x80000129
7109         $MULTIOP $DIR/d73-1/f73-2 Oc &
7110         sleep 1
7111         lctl set_param fail_loc=0
7112
7113         $MULTIOP $DIR/d73-2/f73-3 Oc &
7114         pid3=$!
7115
7116         kill -USR1 $pid1
7117         wait $pid1 || return 1
7118
7119         sleep 25
7120
7121         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7122         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7123         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7124
7125         rm -rf $DIR/d73-*
7126 }
7127 run_test 73 "multiple MDC requests (should not deadlock)"
7128
7129 test_74a() { # bug 6149, 6184
7130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7131
7132         touch $DIR/f74a
7133         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7134         #
7135         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7136         # will spin in a tight reconnection loop
7137         $LCTL set_param fail_loc=0x8000030e
7138         # get any lock that won't be difficult - lookup works.
7139         ls $DIR/f74a
7140         $LCTL set_param fail_loc=0
7141         rm -f $DIR/f74a
7142         true
7143 }
7144 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7145
7146 test_74b() { # bug 13310
7147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7148
7149         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7150         #
7151         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7152         # will spin in a tight reconnection loop
7153         $LCTL set_param fail_loc=0x8000030e
7154         # get a "difficult" lock
7155         touch $DIR/f74b
7156         $LCTL set_param fail_loc=0
7157         rm -f $DIR/f74b
7158         true
7159 }
7160 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7161
7162 test_74c() {
7163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7164
7165         #define OBD_FAIL_LDLM_NEW_LOCK
7166         $LCTL set_param fail_loc=0x319
7167         touch $DIR/$tfile && error "touch successful"
7168         $LCTL set_param fail_loc=0
7169         true
7170 }
7171 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7172
7173 num_inodes() {
7174         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7175 }
7176
7177 test_76() { # Now for bug 20433, added originally in bug 1443
7178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7179
7180         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7181
7182         cancel_lru_locks osc
7183         BEFORE_INODES=$(num_inodes)
7184         echo "before inodes: $BEFORE_INODES"
7185         local COUNT=1000
7186         [ "$SLOW" = "no" ] && COUNT=100
7187         for i in $(seq $COUNT); do
7188                 touch $DIR/$tfile
7189                 rm -f $DIR/$tfile
7190         done
7191         cancel_lru_locks osc
7192         AFTER_INODES=$(num_inodes)
7193         echo "after inodes: $AFTER_INODES"
7194         local wait=0
7195         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7196                 sleep 2
7197                 AFTER_INODES=$(num_inodes)
7198                 wait=$((wait+2))
7199                 echo "wait $wait seconds inodes: $AFTER_INODES"
7200                 if [ $wait -gt 30 ]; then
7201                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7202                 fi
7203         done
7204 }
7205 run_test 76 "confirm clients recycle inodes properly ===="
7206
7207
7208 export ORIG_CSUM=""
7209 set_checksums()
7210 {
7211         # Note: in sptlrpc modes which enable its own bulk checksum, the
7212         # original crc32_le bulk checksum will be automatically disabled,
7213         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7214         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7215         # In this case set_checksums() will not be no-op, because sptlrpc
7216         # bulk checksum will be enabled all through the test.
7217
7218         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7219         lctl set_param -n osc.*.checksums $1
7220         return 0
7221 }
7222
7223 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7224                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7225 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7226                              tr -d [] | head -n1)}
7227 set_checksum_type()
7228 {
7229         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7230         log "set checksum type to $1"
7231         return 0
7232 }
7233 F77_TMP=$TMP/f77-temp
7234 F77SZ=8
7235 setup_f77() {
7236         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7237                 error "error writing to $F77_TMP"
7238 }
7239
7240 test_77a() { # bug 10889
7241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7242         $GSS && skip_env "could not run with gss"
7243
7244         [ ! -f $F77_TMP ] && setup_f77
7245         set_checksums 1
7246         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7247         set_checksums 0
7248         rm -f $DIR/$tfile
7249 }
7250 run_test 77a "normal checksum read/write operation"
7251
7252 test_77b() { # bug 10889
7253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7254         $GSS && skip_env "could not run with gss"
7255
7256         [ ! -f $F77_TMP ] && setup_f77
7257         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7258         $LCTL set_param fail_loc=0x80000409
7259         set_checksums 1
7260
7261         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7262                 error "dd error: $?"
7263         $LCTL set_param fail_loc=0
7264
7265         for algo in $CKSUM_TYPES; do
7266                 cancel_lru_locks osc
7267                 set_checksum_type $algo
7268                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7269                 $LCTL set_param fail_loc=0x80000408
7270                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7271                 $LCTL set_param fail_loc=0
7272         done
7273         set_checksums 0
7274         set_checksum_type $ORIG_CSUM_TYPE
7275         rm -f $DIR/$tfile
7276 }
7277 run_test 77b "checksum error on client write, read"
7278
7279 cleanup_77c() {
7280         trap 0
7281         set_checksums 0
7282         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7283         $check_ost &&
7284                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7285         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7286         $check_ost && [ -n "$ost_file_prefix" ] &&
7287                 do_facet ost1 rm -f ${ost_file_prefix}\*
7288 }
7289
7290 test_77c() {
7291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7292         $GSS && skip_env "could not run with gss"
7293         remote_ost_nodsh && skip "remote OST with nodsh"
7294
7295         local bad1
7296         local osc_file_prefix
7297         local osc_file
7298         local check_ost=false
7299         local ost_file_prefix
7300         local ost_file
7301         local orig_cksum
7302         local dump_cksum
7303         local fid
7304
7305         # ensure corruption will occur on first OSS/OST
7306         $LFS setstripe -i 0 $DIR/$tfile
7307
7308         [ ! -f $F77_TMP ] && setup_f77
7309         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7310                 error "dd write error: $?"
7311         fid=$($LFS path2fid $DIR/$tfile)
7312
7313         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7314         then
7315                 check_ost=true
7316                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7317                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7318         else
7319                 echo "OSS do not support bulk pages dump upon error"
7320         fi
7321
7322         osc_file_prefix=$($LCTL get_param -n debug_path)
7323         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7324
7325         trap cleanup_77c EXIT
7326
7327         set_checksums 1
7328         # enable bulk pages dump upon error on Client
7329         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7330         # enable bulk pages dump upon error on OSS
7331         $check_ost &&
7332                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7333
7334         # flush Client cache to allow next read to reach OSS
7335         cancel_lru_locks osc
7336
7337         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7338         $LCTL set_param fail_loc=0x80000408
7339         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7340         $LCTL set_param fail_loc=0
7341
7342         rm -f $DIR/$tfile
7343
7344         # check cksum dump on Client
7345         osc_file=$(ls ${osc_file_prefix}*)
7346         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7347         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7348         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7349         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7350         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7351                      cksum)
7352         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7353         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7354                 error "dump content does not match on Client"
7355
7356         $check_ost || skip "No need to check cksum dump on OSS"
7357
7358         # check cksum dump on OSS
7359         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7360         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7361         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7362         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7363         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7364                 error "dump content does not match on OSS"
7365
7366         cleanup_77c
7367 }
7368 run_test 77c "checksum error on client read with debug"
7369
7370 test_77d() { # bug 10889
7371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7372         $GSS && skip_env "could not run with gss"
7373
7374         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7375         $LCTL set_param fail_loc=0x80000409
7376         set_checksums 1
7377         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7378                 error "direct write: rc=$?"
7379         $LCTL set_param fail_loc=0
7380         set_checksums 0
7381
7382         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7383         $LCTL set_param fail_loc=0x80000408
7384         set_checksums 1
7385         cancel_lru_locks osc
7386         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7387                 error "direct read: rc=$?"
7388         $LCTL set_param fail_loc=0
7389         set_checksums 0
7390 }
7391 run_test 77d "checksum error on OST direct write, read"
7392
7393 test_77f() { # bug 10889
7394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7395         $GSS && skip_env "could not run with gss"
7396
7397         set_checksums 1
7398         for algo in $CKSUM_TYPES; do
7399                 cancel_lru_locks osc
7400                 set_checksum_type $algo
7401                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7402                 $LCTL set_param fail_loc=0x409
7403                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7404                         error "direct write succeeded"
7405                 $LCTL set_param fail_loc=0
7406         done
7407         set_checksum_type $ORIG_CSUM_TYPE
7408         set_checksums 0
7409 }
7410 run_test 77f "repeat checksum error on write (expect error)"
7411
7412 test_77g() { # bug 10889
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414         $GSS && skip_env "could not run with gss"
7415         remote_ost_nodsh && skip "remote OST with nodsh"
7416
7417         [ ! -f $F77_TMP ] && setup_f77
7418
7419         local file=$DIR/$tfile
7420         stack_trap "rm -f $file" EXIT
7421
7422         $LFS setstripe -c 1 -i 0 $file
7423         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7424         do_facet ost1 lctl set_param fail_loc=0x8000021a
7425         set_checksums 1
7426         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7427                 error "write error: rc=$?"
7428         do_facet ost1 lctl set_param fail_loc=0
7429         set_checksums 0
7430
7431         cancel_lru_locks osc
7432         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7433         do_facet ost1 lctl set_param fail_loc=0x8000021b
7434         set_checksums 1
7435         cmp $F77_TMP $file || error "file compare failed"
7436         do_facet ost1 lctl set_param fail_loc=0
7437         set_checksums 0
7438 }
7439 run_test 77g "checksum error on OST write, read"
7440
7441 test_77k() { # LU-10906
7442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7443         $GSS && skip_env "could not run with gss"
7444
7445         local cksum_param="osc.$FSNAME*.checksums"
7446         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7447         local checksum
7448         local i
7449
7450         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7451         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7452         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7453                 EXIT
7454
7455         for i in 0 1; do
7456                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7457                         error "failed to set checksum=$i on MGS"
7458                 wait_update $HOSTNAME "$get_checksum" $i
7459                 #remount
7460                 echo "remount client, checksum should be $i"
7461                 remount_client $MOUNT || "failed to remount client"
7462                 checksum=$(eval $get_checksum)
7463                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7464         done
7465         # remove persistent param to avoid races with checksum mountopt below
7466         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7467                 error "failed to delete checksum on MGS"
7468
7469         for opt in "checksum" "nochecksum"; do
7470                 #remount with mount option
7471                 echo "remount client with option $opt, checksum should be $i"
7472                 umount_client $MOUNT || "failed to umount client"
7473                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7474                         "failed to mount client with option '$opt'"
7475                 checksum=$(eval $get_checksum)
7476                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7477                 i=$((i - 1))
7478         done
7479
7480         remount_client $MOUNT || "failed to remount client"
7481 }
7482 run_test 77k "enable/disable checksum correctly"
7483
7484 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7485 rm -f $F77_TMP
7486 unset F77_TMP
7487
7488 cleanup_test_78() {
7489         trap 0
7490         rm -f $DIR/$tfile
7491 }
7492
7493 test_78() { # bug 10901
7494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7495         remote_ost || skip_env "local OST"
7496
7497         NSEQ=5
7498         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7499         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7500         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7501         echo "MemTotal: $MEMTOTAL"
7502
7503         # reserve 256MB of memory for the kernel and other running processes,
7504         # and then take 1/2 of the remaining memory for the read/write buffers.
7505         if [ $MEMTOTAL -gt 512 ] ;then
7506                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7507         else
7508                 # for those poor memory-starved high-end clusters...
7509                 MEMTOTAL=$((MEMTOTAL / 2))
7510         fi
7511         echo "Mem to use for directio: $MEMTOTAL"
7512
7513         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7514         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7515         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7516         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7517                 head -n1)
7518         echo "Smallest OST: $SMALLESTOST"
7519         [[ $SMALLESTOST -lt 10240 ]] &&
7520                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7521
7522         trap cleanup_test_78 EXIT
7523
7524         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7525                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7526
7527         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7528         echo "File size: $F78SIZE"
7529         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7530         for i in $(seq 1 $NSEQ); do
7531                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7532                 echo directIO rdwr round $i of $NSEQ
7533                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7534         done
7535
7536         cleanup_test_78
7537 }
7538 run_test 78 "handle large O_DIRECT writes correctly ============"
7539
7540 test_79() { # bug 12743
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542
7543         wait_delete_completed
7544
7545         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7546         BKFREE=$(calc_osc_kbytes kbytesfree)
7547         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7548
7549         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7550         DFTOTAL=`echo $STRING | cut -d, -f1`
7551         DFUSED=`echo $STRING  | cut -d, -f2`
7552         DFAVAIL=`echo $STRING | cut -d, -f3`
7553         DFFREE=$(($DFTOTAL - $DFUSED))
7554
7555         ALLOWANCE=$((64 * $OSTCOUNT))
7556
7557         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7558            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7559                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7560         fi
7561         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7562            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7563                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7564         fi
7565         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7566            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7567                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7568         fi
7569 }
7570 run_test 79 "df report consistency check ======================="
7571
7572 test_80() { # bug 10718
7573         remote_ost_nodsh && skip "remote OST with nodsh"
7574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7575
7576         # relax strong synchronous semantics for slow backends like ZFS
7577         local soc="obdfilter.*.sync_on_lock_cancel"
7578         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7579         local hosts=
7580         if [ "$soc_old" != "never" ] &&
7581                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7582                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7583                                 facet_active_host $host; done | sort -u)
7584                         do_nodes $hosts lctl set_param $soc=never
7585         fi
7586
7587         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7588         sync; sleep 1; sync
7589         local BEFORE=`date +%s`
7590         cancel_lru_locks osc
7591         local AFTER=`date +%s`
7592         local DIFF=$((AFTER-BEFORE))
7593         if [ $DIFF -gt 1 ] ; then
7594                 error "elapsed for 1M@1T = $DIFF"
7595         fi
7596
7597         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7598
7599         rm -f $DIR/$tfile
7600 }
7601 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7602
7603 test_81a() { # LU-456
7604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7605         remote_ost_nodsh && skip "remote OST with nodsh"
7606
7607         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7608         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7609         do_facet ost1 lctl set_param fail_loc=0x80000228
7610
7611         # write should trigger a retry and success
7612         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7613         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7614         RC=$?
7615         if [ $RC -ne 0 ] ; then
7616                 error "write should success, but failed for $RC"
7617         fi
7618 }
7619 run_test 81a "OST should retry write when get -ENOSPC ==============="
7620
7621 test_81b() { # LU-456
7622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7623         remote_ost_nodsh && skip "remote OST with nodsh"
7624
7625         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7626         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7627         do_facet ost1 lctl set_param fail_loc=0x228
7628
7629         # write should retry several times and return -ENOSPC finally
7630         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7631         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7632         RC=$?
7633         ENOSPC=28
7634         if [ $RC -ne $ENOSPC ] ; then
7635                 error "dd should fail for -ENOSPC, but succeed."
7636         fi
7637 }
7638 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7639
7640 test_82() { # LU-1031
7641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7642         local gid1=14091995
7643         local gid2=16022000
7644
7645         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7646         local MULTIPID1=$!
7647         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7648         local MULTIPID2=$!
7649         kill -USR1 $MULTIPID2
7650         sleep 2
7651         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7652                 error "First grouplock does not block second one"
7653         else
7654                 echo "Second grouplock blocks first one"
7655         fi
7656         kill -USR1 $MULTIPID1
7657         wait $MULTIPID1
7658         wait $MULTIPID2
7659 }
7660 run_test 82 "Basic grouplock test"
7661
7662 test_99() {
7663         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7664
7665         test_mkdir $DIR/$tdir.cvsroot
7666         chown $RUNAS_ID $DIR/$tdir.cvsroot
7667
7668         cd $TMP
7669         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7670
7671         cd /etc/init.d
7672         # some versions of cvs import exit(1) when asked to import links or
7673         # files they can't read.  ignore those files.
7674         local toignore=$(find . -type l -printf '-I %f\n' -o \
7675                          ! -perm /4 -printf '-I %f\n')
7676         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7677                 $tdir.reposname vtag rtag
7678
7679         cd $DIR
7680         test_mkdir $DIR/$tdir.reposname
7681         chown $RUNAS_ID $DIR/$tdir.reposname
7682         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7683
7684         cd $DIR/$tdir.reposname
7685         $RUNAS touch foo99
7686         $RUNAS cvs add -m 'addmsg' foo99
7687         $RUNAS cvs update
7688         $RUNAS cvs commit -m 'nomsg' foo99
7689         rm -fr $DIR/$tdir.cvsroot
7690 }
7691 run_test 99 "cvs strange file/directory operations"
7692
7693 test_100() {
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695         [[ "$NETTYPE" =~ tcp ]] ||
7696                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7697         remote_ost_nodsh && skip "remote OST with nodsh"
7698         remote_mds_nodsh && skip "remote MDS with nodsh"
7699         remote_servers ||
7700                 skip "useless for local single node setup"
7701
7702         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7703                 [ "$PROT" != "tcp" ] && continue
7704                 RPORT=$(echo $REMOTE | cut -d: -f2)
7705                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7706
7707                 rc=0
7708                 LPORT=`echo $LOCAL | cut -d: -f2`
7709                 if [ $LPORT -ge 1024 ]; then
7710                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7711                         netstat -tna
7712                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7713                 fi
7714         done
7715         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7716 }
7717 run_test 100 "check local port using privileged port ==========="
7718
7719 function get_named_value()
7720 {
7721     local tag
7722
7723     tag=$1
7724     while read ;do
7725         line=$REPLY
7726         case $line in
7727         $tag*)
7728             echo $line | sed "s/^$tag[ ]*//"
7729             break
7730             ;;
7731         esac
7732     done
7733 }
7734
7735 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7736                    awk '/^max_cached_mb/ { print $2 }')
7737
7738 cleanup_101a() {
7739         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7740         trap 0
7741 }
7742
7743 test_101a() {
7744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7745         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7746
7747         local s
7748         local discard
7749         local nreads=10000
7750         local cache_limit=32
7751
7752         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7753         trap cleanup_101a EXIT
7754         $LCTL set_param -n llite.*.read_ahead_stats 0
7755         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7756
7757         #
7758         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7759         #
7760         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7761         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7762
7763         discard=0
7764         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7765                 get_named_value 'read but discarded' | cut -d" " -f1); do
7766                         discard=$(($discard + $s))
7767         done
7768         cleanup_101a
7769
7770         if [[ $(($discard * 10)) -gt $nreads ]]; then
7771                 $LCTL get_param osc.*-osc*.rpc_stats
7772                 $LCTL get_param llite.*.read_ahead_stats
7773                 error "too many ($discard) discarded pages"
7774         fi
7775         rm -f $DIR/$tfile || true
7776 }
7777 run_test 101a "check read-ahead for random reads"
7778
7779 setup_test101bc() {
7780         test_mkdir $DIR/$tdir
7781         local ssize=$1
7782         local FILE_LENGTH=$2
7783         STRIPE_OFFSET=0
7784
7785         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7786
7787         local list=$(comma_list $(osts_nodes))
7788         set_osd_param $list '' read_cache_enable 0
7789         set_osd_param $list '' writethrough_cache_enable 0
7790
7791         trap cleanup_test101bc EXIT
7792         # prepare the read-ahead file
7793         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7794
7795         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7796                                 count=$FILE_SIZE_MB 2> /dev/null
7797
7798 }
7799
7800 cleanup_test101bc() {
7801         trap 0
7802         rm -rf $DIR/$tdir
7803         rm -f $DIR/$tfile
7804
7805         local list=$(comma_list $(osts_nodes))
7806         set_osd_param $list '' read_cache_enable 1
7807         set_osd_param $list '' writethrough_cache_enable 1
7808 }
7809
7810 calc_total() {
7811         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7812 }
7813
7814 ra_check_101() {
7815         local READ_SIZE=$1
7816         local STRIPE_SIZE=$2
7817         local FILE_LENGTH=$3
7818         local RA_INC=1048576
7819         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7820         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7821                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7822         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7823                         get_named_value 'read but discarded' |
7824                         cut -d" " -f1 | calc_total)
7825         if [[ $DISCARD -gt $discard_limit ]]; then
7826                 $LCTL get_param llite.*.read_ahead_stats
7827                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7828         else
7829                 echo "Read-ahead success for size ${READ_SIZE}"
7830         fi
7831 }
7832
7833 test_101b() {
7834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7836
7837         local STRIPE_SIZE=1048576
7838         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7839
7840         if [ $SLOW == "yes" ]; then
7841                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7842         else
7843                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7844         fi
7845
7846         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7847
7848         # prepare the read-ahead file
7849         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7850         cancel_lru_locks osc
7851         for BIDX in 2 4 8 16 32 64 128 256
7852         do
7853                 local BSIZE=$((BIDX*4096))
7854                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7855                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7856                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7857                 $LCTL set_param -n llite.*.read_ahead_stats 0
7858                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7859                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7860                 cancel_lru_locks osc
7861                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7862         done
7863         cleanup_test101bc
7864         true
7865 }
7866 run_test 101b "check stride-io mode read-ahead ================="
7867
7868 test_101c() {
7869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7870
7871         local STRIPE_SIZE=1048576
7872         local FILE_LENGTH=$((STRIPE_SIZE*100))
7873         local nreads=10000
7874         local rsize=65536
7875         local osc_rpc_stats
7876
7877         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7878
7879         cancel_lru_locks osc
7880         $LCTL set_param osc.*.rpc_stats 0
7881         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7882         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7883                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7884                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7885                 local size
7886
7887                 if [ $lines -le 20 ]; then
7888                         continue
7889                 fi
7890                 for size in 1 2 4 8; do
7891                         local rpc=$(echo "$stats" |
7892                                     awk '($1 == "'$size':") {print $2; exit; }')
7893                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7894                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7895                 done
7896                 echo "$osc_rpc_stats check passed!"
7897         done
7898         cleanup_test101bc
7899         true
7900 }
7901 run_test 101c "check stripe_size aligned read-ahead ================="
7902
7903 set_read_ahead() {
7904         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7905         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7906 }
7907
7908 test_101d() {
7909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7910
7911         local file=$DIR/$tfile
7912         local sz_MB=${FILESIZE_101d:-500}
7913         local ra_MB=${READAHEAD_MB:-40}
7914
7915         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7916         [ $free_MB -lt $sz_MB ] &&
7917                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7918
7919         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7920         $LFS setstripe -c -1 $file || error "setstripe failed"
7921
7922         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7923         echo Cancel LRU locks on lustre client to flush the client cache
7924         cancel_lru_locks osc
7925
7926         echo Disable read-ahead
7927         local old_READAHEAD=$(set_read_ahead 0)
7928
7929         echo Reading the test file $file with read-ahead disabled
7930         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7931
7932         echo Cancel LRU locks on lustre client to flush the client cache
7933         cancel_lru_locks osc
7934         echo Enable read-ahead with ${ra_MB}MB
7935         set_read_ahead $ra_MB
7936
7937         echo Reading the test file $file with read-ahead enabled
7938         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7939
7940         echo "read-ahead disabled time read $raOFF"
7941         echo "read-ahead enabled  time read $raON"
7942
7943         set_read_ahead $old_READAHEAD
7944         rm -f $file
7945         wait_delete_completed
7946
7947         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7948                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7949 }
7950 run_test 101d "file read with and without read-ahead enabled"
7951
7952 test_101e() {
7953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7954
7955         local file=$DIR/$tfile
7956         local size_KB=500  #KB
7957         local count=100
7958         local bsize=1024
7959
7960         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7961         local need_KB=$((count * size_KB))
7962         [[ $free_KB -le $need_KB ]] &&
7963                 skip_env "Need free space $need_KB, have $free_KB"
7964
7965         echo "Creating $count ${size_KB}K test files"
7966         for ((i = 0; i < $count; i++)); do
7967                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7968         done
7969
7970         echo "Cancel LRU locks on lustre client to flush the client cache"
7971         cancel_lru_locks $OSC
7972
7973         echo "Reset readahead stats"
7974         $LCTL set_param -n llite.*.read_ahead_stats 0
7975
7976         for ((i = 0; i < $count; i++)); do
7977                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
7978         done
7979
7980         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7981                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
7982
7983         for ((i = 0; i < $count; i++)); do
7984                 rm -rf $file.$i 2>/dev/null
7985         done
7986
7987         #10000 means 20% reads are missing in readahead
7988         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
7989 }
7990 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
7991
7992 test_101f() {
7993         which iozone || skip_env "no iozone installed"
7994
7995         local old_debug=$($LCTL get_param debug)
7996         old_debug=${old_debug#*=}
7997         $LCTL set_param debug="reada mmap"
7998
7999         # create a test file
8000         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8001
8002         echo Cancel LRU locks on lustre client to flush the client cache
8003         cancel_lru_locks osc
8004
8005         echo Reset readahead stats
8006         $LCTL set_param -n llite.*.read_ahead_stats 0
8007
8008         echo mmap read the file with small block size
8009         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8010                 > /dev/null 2>&1
8011
8012         echo checking missing pages
8013         $LCTL get_param llite.*.read_ahead_stats
8014         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8015                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8016
8017         $LCTL set_param debug="$old_debug"
8018         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8019         rm -f $DIR/$tfile
8020 }
8021 run_test 101f "check mmap read performance"
8022
8023 test_101g_brw_size_test() {
8024         local mb=$1
8025         local pages=$((mb * 1048576 / PAGE_SIZE))
8026         local file=$DIR/$tfile
8027
8028         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8029                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8030         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8031                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8032                         return 2
8033         done
8034
8035         stack_trap "rm -f $file" EXIT
8036         $LCTL set_param -n osc.*.rpc_stats=0
8037
8038         # 10 RPCs should be enough for the test
8039         local count=10
8040         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8041                 { error "dd write ${mb} MB blocks failed"; return 3; }
8042         cancel_lru_locks osc
8043         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8044                 { error "dd write ${mb} MB blocks failed"; return 4; }
8045
8046         # calculate number of full-sized read and write RPCs
8047         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8048                 sed -n '/pages per rpc/,/^$/p' |
8049                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8050                 END { print reads,writes }'))
8051         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8052                 return 5
8053         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8054                 return 6
8055
8056         return 0
8057 }
8058
8059 test_101g() {
8060         remote_ost_nodsh && skip "remote OST with nodsh"
8061
8062         local rpcs
8063         local osts=$(get_facets OST)
8064         local list=$(comma_list $(osts_nodes))
8065         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8066         local brw_size="obdfilter.*.brw_size"
8067
8068         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8069
8070         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8071         if [ $OST1_VERSION -ge $(version_code 2.8.52) -o \
8072              \( $OST1_VERSION -ge $(version_code 2.7.17) -a \
8073                 $OST1_VERSION -lt $(version_code 2.7.50) \) ] &&
8074            [ $CLIENT_VERSION -ge $(version_code 2.8.52) -o \
8075              \( $CLIENT_VERSION -ge $(version_code 2.7.17) -a \
8076                 $CLIENT_VERSION -lt $(version_code 2.7.50) \) ]; then
8077                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] && suffix="M"
8078                 if [[ $orig_mb -lt 16 ]]; then
8079                         save_lustre_params $osts "$brw_size" > $p
8080                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8081                                 error "set 16MB RPC size failed"
8082
8083                         echo "remount client to enable new RPC size"
8084                         remount_client $MOUNT || error "remount_client failed"
8085                 fi
8086
8087                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8088                 # should be able to set brw_size=12, but no rpc_stats for that
8089                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8090         fi
8091
8092         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8093
8094         if [[ $orig_mb -lt 16 ]]; then
8095                 restore_lustre_params < $p
8096                 remount_client $MOUNT || error "remount_client restore failed"
8097         fi
8098
8099         rm -f $p $DIR/$tfile
8100 }
8101 run_test 101g "Big bulk(4/16 MiB) readahead"
8102
8103 setup_test102() {
8104         test_mkdir $DIR/$tdir
8105         chown $RUNAS_ID $DIR/$tdir
8106         STRIPE_SIZE=65536
8107         STRIPE_OFFSET=1
8108         STRIPE_COUNT=$OSTCOUNT
8109         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8110
8111         trap cleanup_test102 EXIT
8112         cd $DIR
8113         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8114         cd $DIR/$tdir
8115         for num in 1 2 3 4; do
8116                 for count in $(seq 1 $STRIPE_COUNT); do
8117                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8118                                 local size=`expr $STRIPE_SIZE \* $num`
8119                                 local file=file"$num-$idx-$count"
8120                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8121                         done
8122                 done
8123         done
8124
8125         cd $DIR
8126         $1 tar cf $TMP/f102.tar $tdir --xattrs
8127 }
8128
8129 cleanup_test102() {
8130         trap 0
8131         rm -f $TMP/f102.tar
8132         rm -rf $DIR/d0.sanity/d102
8133 }
8134
8135 test_102a() {
8136         [ "$UID" != 0 ] && skip "must run as root"
8137         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8138                 skip_env "must have user_xattr"
8139
8140         [ -z "$(which setfattr 2>/dev/null)" ] &&
8141                 skip_env "could not find setfattr"
8142
8143         local testfile=$DIR/$tfile
8144
8145         touch $testfile
8146         echo "set/get xattr..."
8147         setfattr -n trusted.name1 -v value1 $testfile ||
8148                 error "setfattr -n trusted.name1=value1 $testfile failed"
8149         getfattr -n trusted.name1 $testfile 2> /dev/null |
8150           grep "trusted.name1=.value1" ||
8151                 error "$testfile missing trusted.name1=value1"
8152
8153         setfattr -n user.author1 -v author1 $testfile ||
8154                 error "setfattr -n user.author1=author1 $testfile failed"
8155         getfattr -n user.author1 $testfile 2> /dev/null |
8156           grep "user.author1=.author1" ||
8157                 error "$testfile missing trusted.author1=author1"
8158
8159         echo "listxattr..."
8160         setfattr -n trusted.name2 -v value2 $testfile ||
8161                 error "$testfile unable to set trusted.name2"
8162         setfattr -n trusted.name3 -v value3 $testfile ||
8163                 error "$testfile unable to set trusted.name3"
8164         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8165             grep "trusted.name" | wc -l) -eq 3 ] ||
8166                 error "$testfile missing 3 trusted.name xattrs"
8167
8168         setfattr -n user.author2 -v author2 $testfile ||
8169                 error "$testfile unable to set user.author2"
8170         setfattr -n user.author3 -v author3 $testfile ||
8171                 error "$testfile unable to set user.author3"
8172         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8173             grep "user.author" | wc -l) -eq 3 ] ||
8174                 error "$testfile missing 3 user.author xattrs"
8175
8176         echo "remove xattr..."
8177         setfattr -x trusted.name1 $testfile ||
8178                 error "$testfile error deleting trusted.name1"
8179         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8180                 error "$testfile did not delete trusted.name1 xattr"
8181
8182         setfattr -x user.author1 $testfile ||
8183                 error "$testfile error deleting user.author1"
8184         echo "set lustre special xattr ..."
8185         $LFS setstripe -c1 $testfile
8186         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8187                 awk -F "=" '/trusted.lov/ { print $2 }' )
8188         setfattr -n "trusted.lov" -v $lovea $testfile ||
8189                 error "$testfile doesn't ignore setting trusted.lov again"
8190         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8191                 error "$testfile allow setting invalid trusted.lov"
8192         rm -f $testfile
8193 }
8194 run_test 102a "user xattr test =================================="
8195
8196 test_102b() {
8197         [ -z "$(which setfattr 2>/dev/null)" ] &&
8198                 skip_env "could not find setfattr"
8199         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8200
8201         # b10930: get/set/list trusted.lov xattr
8202         echo "get/set/list trusted.lov xattr ..."
8203         local testfile=$DIR/$tfile
8204         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8205                 error "setstripe failed"
8206         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8207                 error "getstripe failed"
8208         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8209                 error "can't get trusted.lov from $testfile"
8210
8211         local testfile2=${testfile}2
8212         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8213                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8214
8215         $MCREATE $testfile2
8216         setfattr -n trusted.lov -v $value $testfile2
8217         local stripe_size=$($LFS getstripe -S $testfile2)
8218         local stripe_count=$($LFS getstripe -c $testfile2)
8219         [[ $stripe_size -eq 65536 ]] ||
8220                 error "stripe size $stripe_size != 65536"
8221         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8222                 error "stripe count $stripe_count != $STRIPECOUNT"
8223         rm -f $DIR/$tfile
8224 }
8225 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8226
8227 test_102c() {
8228         [ -z "$(which setfattr 2>/dev/null)" ] &&
8229                 skip_env "could not find setfattr"
8230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8231
8232         # b10930: get/set/list lustre.lov xattr
8233         echo "get/set/list lustre.lov xattr ..."
8234         test_mkdir $DIR/$tdir
8235         chown $RUNAS_ID $DIR/$tdir
8236         local testfile=$DIR/$tdir/$tfile
8237         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8238                 error "setstripe failed"
8239         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8240                 error "getstripe failed"
8241         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8242         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8243
8244         local testfile2=${testfile}2
8245         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8246                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8247
8248         $RUNAS $MCREATE $testfile2
8249         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8250         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8251         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8252         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8253         [ $stripe_count -eq $STRIPECOUNT ] ||
8254                 error "stripe count $stripe_count != $STRIPECOUNT"
8255 }
8256 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8257
8258 compare_stripe_info1() {
8259         local stripe_index_all_zero=true
8260
8261         for num in 1 2 3 4; do
8262                 for count in $(seq 1 $STRIPE_COUNT); do
8263                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8264                                 local size=$((STRIPE_SIZE * num))
8265                                 local file=file"$num-$offset-$count"
8266                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8267                                 [[ $stripe_size -ne $size ]] &&
8268                                     error "$file: size $stripe_size != $size"
8269                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8270                                 # allow fewer stripes to be created, ORI-601
8271                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8272                                     error "$file: count $stripe_count != $count"
8273                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8274                                 [[ $stripe_index -ne 0 ]] &&
8275                                         stripe_index_all_zero=false
8276                         done
8277                 done
8278         done
8279         $stripe_index_all_zero &&
8280                 error "all files are being extracted starting from OST index 0"
8281         return 0
8282 }
8283
8284 have_xattrs_include() {
8285         tar --help | grep -q xattrs-include &&
8286                 echo --xattrs-include="lustre.*"
8287 }
8288
8289 test_102d() {
8290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8292
8293         XINC=$(have_xattrs_include)
8294         setup_test102
8295         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8296         cd $DIR/$tdir/$tdir
8297         compare_stripe_info1
8298 }
8299 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8300
8301 test_102f() {
8302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8303         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8304
8305         XINC=$(have_xattrs_include)
8306         setup_test102
8307         test_mkdir $DIR/$tdir.restore
8308         cd $DIR
8309         tar cf - --xattrs $tdir | tar xf - \
8310                 -C $DIR/$tdir.restore --xattrs $XINC
8311         cd $DIR/$tdir.restore/$tdir
8312         compare_stripe_info1
8313 }
8314 run_test 102f "tar copy files, not keep osts"
8315
8316 grow_xattr() {
8317         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8318                 skip "must have user_xattr"
8319         [ -z "$(which setfattr 2>/dev/null)" ] &&
8320                 skip_env "could not find setfattr"
8321         [ -z "$(which getfattr 2>/dev/null)" ] &&
8322                 skip_env "could not find getfattr"
8323
8324         local xsize=${1:-1024}  # in bytes
8325         local file=$DIR/$tfile
8326         local value="$(generate_string $xsize)"
8327         local xbig=trusted.big
8328
8329         touch $file
8330         log "save $xbig on $file"
8331         setfattr -n $xbig -v $value $file ||
8332                 error "saving $xbig on $file failed"
8333
8334         local orig=$(get_xattr_value $xbig $file)
8335         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8336
8337         local xsml=trusted.sml
8338         log "save $xsml on $file"
8339         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8340
8341         local new=$(get_xattr_value $xbig $file)
8342         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8343
8344         log "grow $xsml on $file"
8345         setfattr -n $xsml -v "$value" $file ||
8346                 error "growing $xsml on $file failed"
8347
8348         new=$(get_xattr_value $xbig $file)
8349         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8350         log "$xbig still valid after growing $xsml"
8351
8352         rm -f $file
8353 }
8354
8355 test_102h() { # bug 15777
8356         grow_xattr 1024
8357 }
8358 run_test 102h "grow xattr from inside inode to external block"
8359
8360 test_102ha() {
8361         large_xattr_enabled || skip_env "ea_inode feature disabled"
8362
8363         grow_xattr $(max_xattr_size)
8364 }
8365 run_test 102ha "grow xattr from inside inode to external inode"
8366
8367 test_102i() { # bug 17038
8368         [ -z "$(which getfattr 2>/dev/null)" ] &&
8369                 skip "could not find getfattr"
8370
8371         touch $DIR/$tfile
8372         ln -s $DIR/$tfile $DIR/${tfile}link
8373         getfattr -n trusted.lov $DIR/$tfile ||
8374                 error "lgetxattr on $DIR/$tfile failed"
8375         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8376                 grep -i "no such attr" ||
8377                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8378         rm -f $DIR/$tfile $DIR/${tfile}link
8379 }
8380 run_test 102i "lgetxattr test on symbolic link ============"
8381
8382 test_102j() {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8385
8386         XINC=$(have_xattrs_include)
8387         setup_test102 "$RUNAS"
8388         chown $RUNAS_ID $DIR/$tdir
8389         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8390         cd $DIR/$tdir/$tdir
8391         compare_stripe_info1 "$RUNAS"
8392 }
8393 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8394
8395 test_102k() {
8396         [ -z "$(which setfattr 2>/dev/null)" ] &&
8397                 skip "could not find setfattr"
8398
8399         touch $DIR/$tfile
8400         # b22187 just check that does not crash for regular file.
8401         setfattr -n trusted.lov $DIR/$tfile
8402         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8403         local test_kdir=$DIR/$tdir
8404         test_mkdir $test_kdir
8405         local default_size=$($LFS getstripe -S $test_kdir)
8406         local default_count=$($LFS getstripe -c $test_kdir)
8407         local default_offset=$($LFS getstripe -i $test_kdir)
8408         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8409                 error 'dir setstripe failed'
8410         setfattr -n trusted.lov $test_kdir
8411         local stripe_size=$($LFS getstripe -S $test_kdir)
8412         local stripe_count=$($LFS getstripe -c $test_kdir)
8413         local stripe_offset=$($LFS getstripe -i $test_kdir)
8414         [ $stripe_size -eq $default_size ] ||
8415                 error "stripe size $stripe_size != $default_size"
8416         [ $stripe_count -eq $default_count ] ||
8417                 error "stripe count $stripe_count != $default_count"
8418         [ $stripe_offset -eq $default_offset ] ||
8419                 error "stripe offset $stripe_offset != $default_offset"
8420         rm -rf $DIR/$tfile $test_kdir
8421 }
8422 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8423
8424 test_102l() {
8425         [ -z "$(which getfattr 2>/dev/null)" ] &&
8426                 skip "could not find getfattr"
8427
8428         # LU-532 trusted. xattr is invisible to non-root
8429         local testfile=$DIR/$tfile
8430
8431         touch $testfile
8432
8433         echo "listxattr as user..."
8434         chown $RUNAS_ID $testfile
8435         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8436             grep -q "trusted" &&
8437                 error "$testfile trusted xattrs are user visible"
8438
8439         return 0;
8440 }
8441 run_test 102l "listxattr size test =================================="
8442
8443 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8444         local path=$DIR/$tfile
8445         touch $path
8446
8447         listxattr_size_check $path || error "listattr_size_check $path failed"
8448 }
8449 run_test 102m "Ensure listxattr fails on small bufffer ========"
8450
8451 cleanup_test102
8452
8453 getxattr() { # getxattr path name
8454         # Return the base64 encoding of the value of xattr name on path.
8455         local path=$1
8456         local name=$2
8457
8458         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8459         # file: $path
8460         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8461         #
8462         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8463
8464         getfattr --absolute-names --encoding=base64 --name=$name $path |
8465                 awk -F= -v name=$name '$1 == name {
8466                         print substr($0, index($0, "=") + 1);
8467         }'
8468 }
8469
8470 test_102n() { # LU-4101 mdt: protect internal xattrs
8471         [ -z "$(which setfattr 2>/dev/null)" ] &&
8472                 skip "could not find setfattr"
8473         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8474         then
8475                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8476         fi
8477
8478         local file0=$DIR/$tfile.0
8479         local file1=$DIR/$tfile.1
8480         local xattr0=$TMP/$tfile.0
8481         local xattr1=$TMP/$tfile.1
8482         local namelist="lov lma lmv link fid version som hsm"
8483         local name
8484         local value
8485
8486         rm -rf $file0 $file1 $xattr0 $xattr1
8487         touch $file0 $file1
8488
8489         # Get 'before' xattrs of $file1.
8490         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8491
8492         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8493                 namelist+=" lfsck_namespace"
8494         for name in $namelist; do
8495                 # Try to copy xattr from $file0 to $file1.
8496                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8497
8498                 setfattr --name=trusted.$name --value="$value" $file1 ||
8499                         error "setxattr 'trusted.$name' failed"
8500
8501                 # Try to set a garbage xattr.
8502                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8503
8504                 if [[ x$name == "xlov" ]]; then
8505                         setfattr --name=trusted.lov --value="$value" $file1 &&
8506                         error "setxattr invalid 'trusted.lov' success"
8507                 else
8508                         setfattr --name=trusted.$name --value="$value" $file1 ||
8509                                 error "setxattr invalid 'trusted.$name' failed"
8510                 fi
8511
8512                 # Try to remove the xattr from $file1. We don't care if this
8513                 # appears to succeed or fail, we just don't want there to be
8514                 # any changes or crashes.
8515                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8516         done
8517
8518         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8519         then
8520                 name="lfsck_ns"
8521                 # Try to copy xattr from $file0 to $file1.
8522                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8523
8524                 setfattr --name=trusted.$name --value="$value" $file1 ||
8525                         error "setxattr 'trusted.$name' failed"
8526
8527                 # Try to set a garbage xattr.
8528                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8529
8530                 setfattr --name=trusted.$name --value="$value" $file1 ||
8531                         error "setxattr 'trusted.$name' failed"
8532
8533                 # Try to remove the xattr from $file1. We don't care if this
8534                 # appears to succeed or fail, we just don't want there to be
8535                 # any changes or crashes.
8536                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8537         fi
8538
8539         # Get 'after' xattrs of file1.
8540         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8541
8542         if ! diff $xattr0 $xattr1; then
8543                 error "before and after xattrs of '$file1' differ"
8544         fi
8545
8546         rm -rf $file0 $file1 $xattr0 $xattr1
8547
8548         return 0
8549 }
8550 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8551
8552 test_102p() { # LU-4703 setxattr did not check ownership
8553         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8554                 skip "MDS needs to be at least 2.5.56"
8555
8556         local testfile=$DIR/$tfile
8557
8558         touch $testfile
8559
8560         echo "setfacl as user..."
8561         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8562         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8563
8564         echo "setfattr as user..."
8565         setfacl -m "u:$RUNAS_ID:---" $testfile
8566         $RUNAS setfattr -x system.posix_acl_access $testfile
8567         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8568 }
8569 run_test 102p "check setxattr(2) correctly fails without permission"
8570
8571 test_102q() {
8572         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8573                 skip "MDS needs to be at least 2.6.92"
8574
8575         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8576 }
8577 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8578
8579 test_102r() {
8580         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8581                 skip "MDS needs to be at least 2.6.93"
8582
8583         touch $DIR/$tfile || error "touch"
8584         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8585         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8586         rm $DIR/$tfile || error "rm"
8587
8588         #normal directory
8589         mkdir -p $DIR/$tdir || error "mkdir"
8590         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8591         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8592         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8593                 error "$testfile error deleting user.author1"
8594         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8595                 grep "user.$(basename $tdir)" &&
8596                 error "$tdir did not delete user.$(basename $tdir)"
8597         rmdir $DIR/$tdir || error "rmdir"
8598
8599         #striped directory
8600         test_mkdir $DIR/$tdir
8601         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8602         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8603         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8604                 error "$testfile error deleting user.author1"
8605         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8606                 grep "user.$(basename $tdir)" &&
8607                 error "$tdir did not delete user.$(basename $tdir)"
8608         rmdir $DIR/$tdir || error "rm striped dir"
8609 }
8610 run_test 102r "set EAs with empty values"
8611
8612 test_102s() {
8613         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8614                 skip "MDS needs to be at least 2.11.52"
8615
8616         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8617
8618         save_lustre_params client "llite.*.xattr_cache" > $save
8619
8620         for cache in 0 1; do
8621                 lctl set_param llite.*.xattr_cache=$cache
8622
8623                 rm -f $DIR/$tfile
8624                 touch $DIR/$tfile || error "touch"
8625                 for prefix in lustre security system trusted user; do
8626                         # Note getxattr() may fail with 'Operation not
8627                         # supported' or 'No such attribute' depending
8628                         # on prefix and cache.
8629                         getfattr -n $prefix.n102s $DIR/$tfile &&
8630                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8631                 done
8632         done
8633
8634         restore_lustre_params < $save
8635 }
8636 run_test 102s "getting nonexistent xattrs should fail"
8637
8638 test_102t() {
8639         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8640                 skip "MDS needs to be at least 2.11.52"
8641
8642         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8643
8644         save_lustre_params client "llite.*.xattr_cache" > $save
8645
8646         for cache in 0 1; do
8647                 lctl set_param llite.*.xattr_cache=$cache
8648
8649                 for buf_size in 0 256; do
8650                         rm -f $DIR/$tfile
8651                         touch $DIR/$tfile || error "touch"
8652                         setfattr -n user.multiop $DIR/$tfile
8653                         $MULTIOP $DIR/$tfile oa$buf_size ||
8654                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8655                 done
8656         done
8657
8658         restore_lustre_params < $save
8659 }
8660 run_test 102t "zero length xattr values handled correctly"
8661
8662 run_acl_subtest()
8663 {
8664     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8665     return $?
8666 }
8667
8668 test_103a() {
8669         [ "$UID" != 0 ] && skip "must run as root"
8670         $GSS && skip_env "could not run under gss"
8671         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8672                 skip_env "must have acl enabled"
8673         [ -z "$(which setfacl 2>/dev/null)" ] &&
8674                 skip_env "could not find setfacl"
8675         remote_mds_nodsh && skip "remote MDS with nodsh"
8676
8677         gpasswd -a daemon bin                           # LU-5641
8678         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8679
8680         declare -a identity_old
8681
8682         for num in $(seq $MDSCOUNT); do
8683                 switch_identity $num true || identity_old[$num]=$?
8684         done
8685
8686         SAVE_UMASK=$(umask)
8687         umask 0022
8688         mkdir -p $DIR/$tdir
8689         cd $DIR/$tdir
8690
8691         echo "performing cp ..."
8692         run_acl_subtest cp || error "run_acl_subtest cp failed"
8693         echo "performing getfacl-noacl..."
8694         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8695         echo "performing misc..."
8696         run_acl_subtest misc || error  "misc test failed"
8697         echo "performing permissions..."
8698         run_acl_subtest permissions || error "permissions failed"
8699         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8700         if [ $MDS1_VERSION -gt $(version_code 2.8.55) -o \
8701              \( $MDS1_VERSION -lt $(version_code 2.6) -a \
8702              $MDS1_VERSION -ge $(version_code 2.5.29) \) ]
8703         then
8704                 echo "performing permissions xattr..."
8705                 run_acl_subtest permissions_xattr ||
8706                         error "permissions_xattr failed"
8707         fi
8708         echo "performing setfacl..."
8709         run_acl_subtest setfacl || error  "setfacl test failed"
8710
8711         # inheritance test got from HP
8712         echo "performing inheritance..."
8713         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8714         chmod +x make-tree || error "chmod +x failed"
8715         run_acl_subtest inheritance || error "inheritance test failed"
8716         rm -f make-tree
8717
8718         echo "LU-974 ignore umask when acl is enabled..."
8719         run_acl_subtest 974 || error "LU-974 umask test failed"
8720         if [ $MDSCOUNT -ge 2 ]; then
8721                 run_acl_subtest 974_remote ||
8722                         error "LU-974 umask test failed under remote dir"
8723         fi
8724
8725         echo "LU-2561 newly created file is same size as directory..."
8726         if [ "$mds1_FSTYPE" != "zfs" ]; then
8727                 run_acl_subtest 2561 || error "LU-2561 test failed"
8728         else
8729                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8730         fi
8731
8732         run_acl_subtest 4924 || error "LU-4924 test failed"
8733
8734         cd $SAVE_PWD
8735         umask $SAVE_UMASK
8736
8737         for num in $(seq $MDSCOUNT); do
8738                 if [ "${identity_old[$num]}" = 1 ]; then
8739                         switch_identity $num false || identity_old[$num]=$?
8740                 fi
8741         done
8742 }
8743 run_test 103a "acl test"
8744
8745 test_103b() {
8746         declare -a pids
8747         local U
8748
8749         for U in {0..511}; do
8750                 {
8751                 local O=$(printf "%04o" $U)
8752
8753                 umask $(printf "%04o" $((511 ^ $O)))
8754                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8755                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8756
8757                 (( $S == ($O & 0666) )) ||
8758                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8759
8760                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8761                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8762                 (( $S == ($O & 0666) )) ||
8763                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8764
8765                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8766                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8767                 (( $S == ($O & 0666) )) ||
8768                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8769                 rm -f $DIR/$tfile.[smp]$0
8770                 } &
8771                 local pid=$!
8772
8773                 # limit the concurrently running threads to 64. LU-11878
8774                 local idx=$((U % 64))
8775                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8776                 pids[idx]=$pid
8777         done
8778         wait
8779 }
8780 run_test 103b "umask lfs setstripe"
8781
8782 test_103c() {
8783         mkdir -p $DIR/$tdir
8784         cp -rp $DIR/$tdir $DIR/$tdir.bak
8785
8786         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8787                 error "$DIR/$tdir shouldn't contain default ACL"
8788         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8789                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8790         true
8791 }
8792 run_test 103c "'cp -rp' won't set empty acl"
8793
8794 test_104a() {
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796
8797         touch $DIR/$tfile
8798         lfs df || error "lfs df failed"
8799         lfs df -ih || error "lfs df -ih failed"
8800         lfs df -h $DIR || error "lfs df -h $DIR failed"
8801         lfs df -i $DIR || error "lfs df -i $DIR failed"
8802         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8803         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8804
8805         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8806         lctl --device %$OSC deactivate
8807         lfs df || error "lfs df with deactivated OSC failed"
8808         lctl --device %$OSC activate
8809         # wait the osc back to normal
8810         wait_osc_import_ready client ost
8811
8812         lfs df || error "lfs df with reactivated OSC failed"
8813         rm -f $DIR/$tfile
8814 }
8815 run_test 104a "lfs df [-ih] [path] test ========================="
8816
8817 test_104b() {
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819         [ $RUNAS_ID -eq $UID ] &&
8820                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8821
8822         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8823                         grep "Permission denied" | wc -l)))
8824         if [ $denied_cnt -ne 0 ]; then
8825                 error "lfs check servers test failed"
8826         fi
8827 }
8828 run_test 104b "$RUNAS lfs check servers test ===================="
8829
8830 test_105a() {
8831         # doesn't work on 2.4 kernels
8832         touch $DIR/$tfile
8833         if $(flock_is_enabled); then
8834                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8835         else
8836                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8837         fi
8838         rm -f $DIR/$tfile
8839 }
8840 run_test 105a "flock when mounted without -o flock test ========"
8841
8842 test_105b() {
8843         touch $DIR/$tfile
8844         if $(flock_is_enabled); then
8845                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8846         else
8847                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8848         fi
8849         rm -f $DIR/$tfile
8850 }
8851 run_test 105b "fcntl when mounted without -o flock test ========"
8852
8853 test_105c() {
8854         touch $DIR/$tfile
8855         if $(flock_is_enabled); then
8856                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8857         else
8858                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8859         fi
8860         rm -f $DIR/$tfile
8861 }
8862 run_test 105c "lockf when mounted without -o flock test"
8863
8864 test_105d() { # bug 15924
8865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8866
8867         test_mkdir $DIR/$tdir
8868         flock_is_enabled || skip_env "mount w/o flock enabled"
8869         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8870         $LCTL set_param fail_loc=0x80000315
8871         flocks_test 2 $DIR/$tdir
8872 }
8873 run_test 105d "flock race (should not freeze) ========"
8874
8875 test_105e() { # bug 22660 && 22040
8876         flock_is_enabled || skip_env "mount w/o flock enabled"
8877
8878         touch $DIR/$tfile
8879         flocks_test 3 $DIR/$tfile
8880 }
8881 run_test 105e "Two conflicting flocks from same process"
8882
8883 test_106() { #bug 10921
8884         test_mkdir $DIR/$tdir
8885         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8886         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8887 }
8888 run_test 106 "attempt exec of dir followed by chown of that dir"
8889
8890 test_107() {
8891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8892
8893         CDIR=`pwd`
8894         local file=core
8895
8896         cd $DIR
8897         rm -f $file
8898
8899         local save_pattern=$(sysctl -n kernel.core_pattern)
8900         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8901         sysctl -w kernel.core_pattern=$file
8902         sysctl -w kernel.core_uses_pid=0
8903
8904         ulimit -c unlimited
8905         sleep 60 &
8906         SLEEPPID=$!
8907
8908         sleep 1
8909
8910         kill -s 11 $SLEEPPID
8911         wait $SLEEPPID
8912         if [ -e $file ]; then
8913                 size=`stat -c%s $file`
8914                 [ $size -eq 0 ] && error "Fail to create core file $file"
8915         else
8916                 error "Fail to create core file $file"
8917         fi
8918         rm -f $file
8919         sysctl -w kernel.core_pattern=$save_pattern
8920         sysctl -w kernel.core_uses_pid=$save_uses_pid
8921         cd $CDIR
8922 }
8923 run_test 107 "Coredump on SIG"
8924
8925 test_110() {
8926         test_mkdir $DIR/$tdir
8927         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8928         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8929                 error "mkdir with 256 char should fail, but did not"
8930         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8931                 error "create with 255 char failed"
8932         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8933                 error "create with 256 char should fail, but did not"
8934
8935         ls -l $DIR/$tdir
8936         rm -rf $DIR/$tdir
8937 }
8938 run_test 110 "filename length checking"
8939
8940 #
8941 # Purpose: To verify dynamic thread (OSS) creation.
8942 #
8943 test_115() {
8944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8945         remote_ost_nodsh && skip "remote OST with nodsh"
8946
8947         # Lustre does not stop service threads once they are started.
8948         # Reset number of running threads to default.
8949         stopall
8950         setupall
8951
8952         local OSTIO_pre
8953         local save_params="$TMP/sanity-$TESTNAME.parameters"
8954
8955         # Get ll_ost_io count before I/O
8956         OSTIO_pre=$(do_facet ost1 \
8957                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
8958         # Exit if lustre is not running (ll_ost_io not running).
8959         [ -z "$OSTIO_pre" ] && error "no OSS threads"
8960
8961         echo "Starting with $OSTIO_pre threads"
8962         local thread_max=$((OSTIO_pre * 2))
8963         local rpc_in_flight=$((thread_max * 2))
8964         # Number of I/O Process proposed to be started.
8965         local nfiles
8966         local facets=$(get_facets OST)
8967
8968         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
8969         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
8970
8971         # Set in_flight to $rpc_in_flight
8972         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
8973                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
8974         nfiles=${rpc_in_flight}
8975         # Set ost thread_max to $thread_max
8976         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
8977
8978         # 5 Minutes should be sufficient for max number of OSS
8979         # threads(thread_max) to be created.
8980         local timeout=300
8981
8982         # Start I/O.
8983         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
8984         test_mkdir $DIR/$tdir
8985         for i in $(seq $nfiles); do
8986                 local file=$DIR/$tdir/${tfile}-$i
8987                 $LFS setstripe -c -1 -i 0 $file
8988                 ($WTL $file $timeout)&
8989         done
8990
8991         # I/O Started - Wait for thread_started to reach thread_max or report
8992         # error if thread_started is more than thread_max.
8993         echo "Waiting for thread_started to reach thread_max"
8994         local thread_started=0
8995         local end_time=$((SECONDS + timeout))
8996
8997         while [ $SECONDS -le $end_time ] ; do
8998                 echo -n "."
8999                 # Get ost i/o thread_started count.
9000                 thread_started=$(do_facet ost1 \
9001                         "$LCTL get_param \
9002                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9003                 # Break out if thread_started is equal/greater than thread_max
9004                 if [[ $thread_started -ge $thread_max ]]; then
9005                         echo ll_ost_io thread_started $thread_started, \
9006                                 equal/greater than thread_max $thread_max
9007                         break
9008                 fi
9009                 sleep 1
9010         done
9011
9012         # Cleanup - We have the numbers, Kill i/o jobs if running.
9013         jobcount=($(jobs -p))
9014         for i in $(seq 0 $((${#jobcount[@]}-1)))
9015         do
9016                 kill -9 ${jobcount[$i]}
9017                 if [ $? -ne 0 ] ; then
9018                         echo Warning: \
9019                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9020                 fi
9021         done
9022
9023         # Cleanup files left by WTL binary.
9024         for i in $(seq $nfiles); do
9025                 local file=$DIR/$tdir/${tfile}-$i
9026                 rm -rf $file
9027                 if [ $? -ne 0 ] ; then
9028                         echo "Warning: Failed to delete file $file"
9029                 fi
9030         done
9031
9032         restore_lustre_params <$save_params
9033         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9034
9035         # Error out if no new thread has started or Thread started is greater
9036         # than thread max.
9037         if [[ $thread_started -le $OSTIO_pre ||
9038                         $thread_started -gt $thread_max ]]; then
9039                 error "ll_ost_io: thread_started $thread_started" \
9040                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9041                       "No new thread started or thread started greater " \
9042                       "than thread_max."
9043         fi
9044 }
9045 run_test 115 "verify dynamic thread creation===================="
9046
9047 free_min_max () {
9048         wait_delete_completed
9049         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9050         echo "OST kbytes available: ${AVAIL[@]}"
9051         MAXV=${AVAIL[0]}
9052         MAXI=0
9053         MINV=${AVAIL[0]}
9054         MINI=0
9055         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9056                 #echo OST $i: ${AVAIL[i]}kb
9057                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9058                         MAXV=${AVAIL[i]}
9059                         MAXI=$i
9060                 fi
9061                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9062                         MINV=${AVAIL[i]}
9063                         MINI=$i
9064                 fi
9065         done
9066         echo "Min free space: OST $MINI: $MINV"
9067         echo "Max free space: OST $MAXI: $MAXV"
9068 }
9069
9070 test_116a() { # was previously test_116()
9071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9073         remote_mds_nodsh && skip "remote MDS with nodsh"
9074
9075         echo -n "Free space priority "
9076         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9077                 head -n1
9078         declare -a AVAIL
9079         free_min_max
9080
9081         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9082         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9083         trap simple_cleanup_common EXIT
9084
9085         # Check if we need to generate uneven OSTs
9086         test_mkdir -p $DIR/$tdir/OST${MINI}
9087         local FILL=$((MINV / 4))
9088         local DIFF=$((MAXV - MINV))
9089         local DIFF2=$((DIFF * 100 / MINV))
9090
9091         local threshold=$(do_facet $SINGLEMDS \
9092                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9093         threshold=${threshold%%%}
9094         echo -n "Check for uneven OSTs: "
9095         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9096
9097         if [[ $DIFF2 -gt $threshold ]]; then
9098                 echo "ok"
9099                 echo "Don't need to fill OST$MINI"
9100         else
9101                 # generate uneven OSTs. Write 2% over the QOS threshold value
9102                 echo "no"
9103                 DIFF=$((threshold - DIFF2 + 2))
9104                 DIFF2=$((MINV * DIFF / 100))
9105                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9106                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9107                         error "setstripe failed"
9108                 DIFF=$((DIFF2 / 2048))
9109                 i=0
9110                 while [ $i -lt $DIFF ]; do
9111                         i=$((i + 1))
9112                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9113                                 bs=2M count=1 2>/dev/null
9114                         echo -n .
9115                 done
9116                 echo .
9117                 sync
9118                 sleep_maxage
9119                 free_min_max
9120         fi
9121
9122         DIFF=$((MAXV - MINV))
9123         DIFF2=$((DIFF * 100 / MINV))
9124         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9125         if [ $DIFF2 -gt $threshold ]; then
9126                 echo "ok"
9127         else
9128                 echo "failed - QOS mode won't be used"
9129                 simple_cleanup_common
9130                 skip "QOS imbalance criteria not met"
9131         fi
9132
9133         MINI1=$MINI
9134         MINV1=$MINV
9135         MAXI1=$MAXI
9136         MAXV1=$MAXV
9137
9138         # now fill using QOS
9139         $LFS setstripe -c 1 $DIR/$tdir
9140         FILL=$((FILL / 200))
9141         if [ $FILL -gt 600 ]; then
9142                 FILL=600
9143         fi
9144         echo "writing $FILL files to QOS-assigned OSTs"
9145         i=0
9146         while [ $i -lt $FILL ]; do
9147                 i=$((i + 1))
9148                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9149                         count=1 2>/dev/null
9150                 echo -n .
9151         done
9152         echo "wrote $i 200k files"
9153         sync
9154         sleep_maxage
9155
9156         echo "Note: free space may not be updated, so measurements might be off"
9157         free_min_max
9158         DIFF2=$((MAXV - MINV))
9159         echo "free space delta: orig $DIFF final $DIFF2"
9160         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9161         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9162         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9163         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9164         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9165         if [[ $DIFF -gt 0 ]]; then
9166                 FILL=$((DIFF2 * 100 / DIFF - 100))
9167                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9168         fi
9169
9170         # Figure out which files were written where
9171         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9172                awk '/'$MINI1': / {print $2; exit}')
9173         echo $UUID
9174         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9175         echo "$MINC files created on smaller OST $MINI1"
9176         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9177                awk '/'$MAXI1': / {print $2; exit}')
9178         echo $UUID
9179         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9180         echo "$MAXC files created on larger OST $MAXI1"
9181         if [[ $MINC -gt 0 ]]; then
9182                 FILL=$((MAXC * 100 / MINC - 100))
9183                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9184         fi
9185         [[ $MAXC -gt $MINC ]] ||
9186                 error_ignore LU-9 "stripe QOS didn't balance free space"
9187         simple_cleanup_common
9188 }
9189 run_test 116a "stripe QOS: free space balance ==================="
9190
9191 test_116b() { # LU-2093
9192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9193         remote_mds_nodsh && skip "remote MDS with nodsh"
9194
9195 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9196         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9197                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9198         [ -z "$old_rr" ] && skip "no QOS"
9199         do_facet $SINGLEMDS lctl set_param \
9200                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9201         mkdir -p $DIR/$tdir
9202         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9203         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9204         do_facet $SINGLEMDS lctl set_param fail_loc=0
9205         rm -rf $DIR/$tdir
9206         do_facet $SINGLEMDS lctl set_param \
9207                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9208 }
9209 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9210
9211 test_117() # bug 10891
9212 {
9213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9214
9215         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9216         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9217         lctl set_param fail_loc=0x21e
9218         > $DIR/$tfile || error "truncate failed"
9219         lctl set_param fail_loc=0
9220         echo "Truncate succeeded."
9221         rm -f $DIR/$tfile
9222 }
9223 run_test 117 "verify osd extend =========="
9224
9225 NO_SLOW_RESENDCOUNT=4
9226 export OLD_RESENDCOUNT=""
9227 set_resend_count () {
9228         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9229         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9230         lctl set_param -n $PROC_RESENDCOUNT $1
9231         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9232 }
9233
9234 # for reduce test_118* time (b=14842)
9235 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9236
9237 # Reset async IO behavior after error case
9238 reset_async() {
9239         FILE=$DIR/reset_async
9240
9241         # Ensure all OSCs are cleared
9242         $LFS setstripe -c -1 $FILE
9243         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9244         sync
9245         rm $FILE
9246 }
9247
9248 test_118a() #bug 11710
9249 {
9250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9251
9252         reset_async
9253
9254         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9255         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9256         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9257
9258         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9259                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9260                 return 1;
9261         fi
9262         rm -f $DIR/$tfile
9263 }
9264 run_test 118a "verify O_SYNC works =========="
9265
9266 test_118b()
9267 {
9268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9269         remote_ost_nodsh && skip "remote OST with nodsh"
9270
9271         reset_async
9272
9273         #define OBD_FAIL_SRV_ENOENT 0x217
9274         set_nodes_failloc "$(osts_nodes)" 0x217
9275         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9276         RC=$?
9277         set_nodes_failloc "$(osts_nodes)" 0
9278         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9279         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9280                     grep -c writeback)
9281
9282         if [[ $RC -eq 0 ]]; then
9283                 error "Must return error due to dropped pages, rc=$RC"
9284                 return 1;
9285         fi
9286
9287         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9288                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9289                 return 1;
9290         fi
9291
9292         echo "Dirty pages not leaked on ENOENT"
9293
9294         # Due to the above error the OSC will issue all RPCs syncronously
9295         # until a subsequent RPC completes successfully without error.
9296         $MULTIOP $DIR/$tfile Ow4096yc
9297         rm -f $DIR/$tfile
9298
9299         return 0
9300 }
9301 run_test 118b "Reclaim dirty pages on fatal error =========="
9302
9303 test_118c()
9304 {
9305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9306
9307         # for 118c, restore the original resend count, LU-1940
9308         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9309                                 set_resend_count $OLD_RESENDCOUNT
9310         remote_ost_nodsh && skip "remote OST with nodsh"
9311
9312         reset_async
9313
9314         #define OBD_FAIL_OST_EROFS               0x216
9315         set_nodes_failloc "$(osts_nodes)" 0x216
9316
9317         # multiop should block due to fsync until pages are written
9318         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9319         MULTIPID=$!
9320         sleep 1
9321
9322         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9323                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9324         fi
9325
9326         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9327                     grep -c writeback)
9328         if [[ $WRITEBACK -eq 0 ]]; then
9329                 error "No page in writeback, writeback=$WRITEBACK"
9330         fi
9331
9332         set_nodes_failloc "$(osts_nodes)" 0
9333         wait $MULTIPID
9334         RC=$?
9335         if [[ $RC -ne 0 ]]; then
9336                 error "Multiop fsync failed, rc=$RC"
9337         fi
9338
9339         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9340         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9341                     grep -c writeback)
9342         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9343                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9344         fi
9345
9346         rm -f $DIR/$tfile
9347         echo "Dirty pages flushed via fsync on EROFS"
9348         return 0
9349 }
9350 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9351
9352 # continue to use small resend count to reduce test_118* time (b=14842)
9353 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9354
9355 test_118d()
9356 {
9357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9358         remote_ost_nodsh && skip "remote OST with nodsh"
9359
9360         reset_async
9361
9362         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9363         set_nodes_failloc "$(osts_nodes)" 0x214
9364         # multiop should block due to fsync until pages are written
9365         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9366         MULTIPID=$!
9367         sleep 1
9368
9369         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9370                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9371         fi
9372
9373         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9374                     grep -c writeback)
9375         if [[ $WRITEBACK -eq 0 ]]; then
9376                 error "No page in writeback, writeback=$WRITEBACK"
9377         fi
9378
9379         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9380         set_nodes_failloc "$(osts_nodes)" 0
9381
9382         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9384                     grep -c writeback)
9385         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9386                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9387         fi
9388
9389         rm -f $DIR/$tfile
9390         echo "Dirty pages gaurenteed flushed via fsync"
9391         return 0
9392 }
9393 run_test 118d "Fsync validation inject a delay of the bulk =========="
9394
9395 test_118f() {
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397
9398         reset_async
9399
9400         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9401         lctl set_param fail_loc=0x8000040a
9402
9403         # Should simulate EINVAL error which is fatal
9404         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9405         RC=$?
9406         if [[ $RC -eq 0 ]]; then
9407                 error "Must return error due to dropped pages, rc=$RC"
9408         fi
9409
9410         lctl set_param fail_loc=0x0
9411
9412         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9413         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9414         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9415                     grep -c writeback)
9416         if [[ $LOCKED -ne 0 ]]; then
9417                 error "Locked pages remain in cache, locked=$LOCKED"
9418         fi
9419
9420         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9421                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9422         fi
9423
9424         rm -f $DIR/$tfile
9425         echo "No pages locked after fsync"
9426
9427         reset_async
9428         return 0
9429 }
9430 run_test 118f "Simulate unrecoverable OSC side error =========="
9431
9432 test_118g() {
9433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9434
9435         reset_async
9436
9437         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9438         lctl set_param fail_loc=0x406
9439
9440         # simulate local -ENOMEM
9441         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9442         RC=$?
9443
9444         lctl set_param fail_loc=0
9445         if [[ $RC -eq 0 ]]; then
9446                 error "Must return error due to dropped pages, rc=$RC"
9447         fi
9448
9449         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9450         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9451         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9452                         grep -c writeback)
9453         if [[ $LOCKED -ne 0 ]]; then
9454                 error "Locked pages remain in cache, locked=$LOCKED"
9455         fi
9456
9457         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9458                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9459         fi
9460
9461         rm -f $DIR/$tfile
9462         echo "No pages locked after fsync"
9463
9464         reset_async
9465         return 0
9466 }
9467 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9468
9469 test_118h() {
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471         remote_ost_nodsh && skip "remote OST with nodsh"
9472
9473         reset_async
9474
9475         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9476         set_nodes_failloc "$(osts_nodes)" 0x20e
9477         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9478         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9479         RC=$?
9480
9481         set_nodes_failloc "$(osts_nodes)" 0
9482         if [[ $RC -eq 0 ]]; then
9483                 error "Must return error due to dropped pages, rc=$RC"
9484         fi
9485
9486         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9487         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9488         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9489                     grep -c writeback)
9490         if [[ $LOCKED -ne 0 ]]; then
9491                 error "Locked pages remain in cache, locked=$LOCKED"
9492         fi
9493
9494         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9495                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9496         fi
9497
9498         rm -f $DIR/$tfile
9499         echo "No pages locked after fsync"
9500
9501         return 0
9502 }
9503 run_test 118h "Verify timeout in handling recoverables errors  =========="
9504
9505 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9506
9507 test_118i() {
9508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9509         remote_ost_nodsh && skip "remote OST with nodsh"
9510
9511         reset_async
9512
9513         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9514         set_nodes_failloc "$(osts_nodes)" 0x20e
9515
9516         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9517         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9518         PID=$!
9519         sleep 5
9520         set_nodes_failloc "$(osts_nodes)" 0
9521
9522         wait $PID
9523         RC=$?
9524         if [[ $RC -ne 0 ]]; then
9525                 error "got error, but should be not, rc=$RC"
9526         fi
9527
9528         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9529         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9530         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9531         if [[ $LOCKED -ne 0 ]]; then
9532                 error "Locked pages remain in cache, locked=$LOCKED"
9533         fi
9534
9535         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9536                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9537         fi
9538
9539         rm -f $DIR/$tfile
9540         echo "No pages locked after fsync"
9541
9542         return 0
9543 }
9544 run_test 118i "Fix error before timeout in recoverable error  =========="
9545
9546 [ "$SLOW" = "no" ] && set_resend_count 4
9547
9548 test_118j() {
9549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9550         remote_ost_nodsh && skip "remote OST with nodsh"
9551
9552         reset_async
9553
9554         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9555         set_nodes_failloc "$(osts_nodes)" 0x220
9556
9557         # return -EIO from OST
9558         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9559         RC=$?
9560         set_nodes_failloc "$(osts_nodes)" 0x0
9561         if [[ $RC -eq 0 ]]; then
9562                 error "Must return error due to dropped pages, rc=$RC"
9563         fi
9564
9565         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9566         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9567         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9568         if [[ $LOCKED -ne 0 ]]; then
9569                 error "Locked pages remain in cache, locked=$LOCKED"
9570         fi
9571
9572         # in recoverable error on OST we want resend and stay until it finished
9573         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9574                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9575         fi
9576
9577         rm -f $DIR/$tfile
9578         echo "No pages locked after fsync"
9579
9580         return 0
9581 }
9582 run_test 118j "Simulate unrecoverable OST side error =========="
9583
9584 test_118k()
9585 {
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587         remote_ost_nodsh && skip "remote OSTs with nodsh"
9588
9589         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9590         set_nodes_failloc "$(osts_nodes)" 0x20e
9591         test_mkdir $DIR/$tdir
9592
9593         for ((i=0;i<10;i++)); do
9594                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9595                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9596                 SLEEPPID=$!
9597                 sleep 0.500s
9598                 kill $SLEEPPID
9599                 wait $SLEEPPID
9600         done
9601
9602         set_nodes_failloc "$(osts_nodes)" 0
9603         rm -rf $DIR/$tdir
9604 }
9605 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9606
9607 test_118l() # LU-646
9608 {
9609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9610
9611         test_mkdir $DIR/$tdir
9612         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9613         rm -rf $DIR/$tdir
9614 }
9615 run_test 118l "fsync dir"
9616
9617 test_118m() # LU-3066
9618 {
9619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9620
9621         test_mkdir $DIR/$tdir
9622         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9623         rm -rf $DIR/$tdir
9624 }
9625 run_test 118m "fdatasync dir ========="
9626
9627 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9628
9629 test_118n()
9630 {
9631         local begin
9632         local end
9633
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635         remote_ost_nodsh && skip "remote OSTs with nodsh"
9636
9637         # Sleep to avoid a cached response.
9638         #define OBD_STATFS_CACHE_SECONDS 1
9639         sleep 2
9640
9641         # Inject a 10 second delay in the OST_STATFS handler.
9642         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9643         set_nodes_failloc "$(osts_nodes)" 0x242
9644
9645         begin=$SECONDS
9646         stat --file-system $MOUNT > /dev/null
9647         end=$SECONDS
9648
9649         set_nodes_failloc "$(osts_nodes)" 0
9650
9651         if ((end - begin > 20)); then
9652             error "statfs took $((end - begin)) seconds, expected 10"
9653         fi
9654 }
9655 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9656
9657 test_119a() # bug 11737
9658 {
9659         BSIZE=$((512 * 1024))
9660         directio write $DIR/$tfile 0 1 $BSIZE
9661         # We ask to read two blocks, which is more than a file size.
9662         # directio will indicate an error when requested and actual
9663         # sizes aren't equeal (a normal situation in this case) and
9664         # print actual read amount.
9665         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9666         if [ "$NOB" != "$BSIZE" ]; then
9667                 error "read $NOB bytes instead of $BSIZE"
9668         fi
9669         rm -f $DIR/$tfile
9670 }
9671 run_test 119a "Short directIO read must return actual read amount"
9672
9673 test_119b() # bug 11737
9674 {
9675         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9676
9677         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9678         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9679         sync
9680         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9681                 error "direct read failed"
9682         rm -f $DIR/$tfile
9683 }
9684 run_test 119b "Sparse directIO read must return actual read amount"
9685
9686 test_119c() # bug 13099
9687 {
9688         BSIZE=1048576
9689         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9690         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9691         rm -f $DIR/$tfile
9692 }
9693 run_test 119c "Testing for direct read hitting hole"
9694
9695 test_119d() # bug 15950
9696 {
9697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9698
9699         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9700         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9701         BSIZE=1048576
9702         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9703         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9704         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9705         lctl set_param fail_loc=0x40d
9706         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9707         pid_dio=$!
9708         sleep 1
9709         cat $DIR/$tfile > /dev/null &
9710         lctl set_param fail_loc=0
9711         pid_reads=$!
9712         wait $pid_dio
9713         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9714         sleep 2
9715         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9716         error "the read rpcs have not completed in 2s"
9717         rm -f $DIR/$tfile
9718         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9719 }
9720 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9721
9722 test_120a() {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724         remote_mds_nodsh && skip "remote MDS with nodsh"
9725         test_mkdir -i0 -c1 $DIR/$tdir
9726         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9727                 skip_env "no early lock cancel on server"
9728
9729         lru_resize_disable mdc
9730         lru_resize_disable osc
9731         cancel_lru_locks mdc
9732         # asynchronous object destroy at MDT could cause bl ast to client
9733         cancel_lru_locks osc
9734
9735         stat $DIR/$tdir > /dev/null
9736         can1=$(do_facet mds1 \
9737                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9738                awk '/ldlm_cancel/ {print $2}')
9739         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9740                awk '/ldlm_bl_callback/ {print $2}')
9741         test_mkdir -i0 -c1 $DIR/$tdir/d1
9742         can2=$(do_facet mds1 \
9743                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9744                awk '/ldlm_cancel/ {print $2}')
9745         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9746                awk '/ldlm_bl_callback/ {print $2}')
9747         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9748         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9749         lru_resize_enable mdc
9750         lru_resize_enable osc
9751 }
9752 run_test 120a "Early Lock Cancel: mkdir test"
9753
9754 test_120b() {
9755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9756         remote_mds_nodsh && skip "remote MDS with nodsh"
9757         test_mkdir $DIR/$tdir
9758         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9759                 skip_env "no early lock cancel on server"
9760
9761         lru_resize_disable mdc
9762         lru_resize_disable osc
9763         cancel_lru_locks mdc
9764         stat $DIR/$tdir > /dev/null
9765         can1=$(do_facet $SINGLEMDS \
9766                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9767                awk '/ldlm_cancel/ {print $2}')
9768         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9769                awk '/ldlm_bl_callback/ {print $2}')
9770         touch $DIR/$tdir/f1
9771         can2=$(do_facet $SINGLEMDS \
9772                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9773                awk '/ldlm_cancel/ {print $2}')
9774         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9775                awk '/ldlm_bl_callback/ {print $2}')
9776         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9777         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9778         lru_resize_enable mdc
9779         lru_resize_enable osc
9780 }
9781 run_test 120b "Early Lock Cancel: create test"
9782
9783 test_120c() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         remote_mds_nodsh && skip "remote MDS with nodsh"
9786         test_mkdir -i0 -c1 $DIR/$tdir
9787         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9788                 skip "no early lock cancel on server"
9789
9790         lru_resize_disable mdc
9791         lru_resize_disable osc
9792         test_mkdir -i0 -c1 $DIR/$tdir/d1
9793         test_mkdir -i0 -c1 $DIR/$tdir/d2
9794         touch $DIR/$tdir/d1/f1
9795         cancel_lru_locks mdc
9796         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9797         can1=$(do_facet mds1 \
9798                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9799                awk '/ldlm_cancel/ {print $2}')
9800         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9801                awk '/ldlm_bl_callback/ {print $2}')
9802         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9803         can2=$(do_facet mds1 \
9804                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9805                awk '/ldlm_cancel/ {print $2}')
9806         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9807                awk '/ldlm_bl_callback/ {print $2}')
9808         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9809         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9810         lru_resize_enable mdc
9811         lru_resize_enable osc
9812 }
9813 run_test 120c "Early Lock Cancel: link test"
9814
9815 test_120d() {
9816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9817         remote_mds_nodsh && skip "remote MDS with nodsh"
9818         test_mkdir -i0 -c1 $DIR/$tdir
9819         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9820                 skip_env "no early lock cancel on server"
9821
9822         lru_resize_disable mdc
9823         lru_resize_disable osc
9824         touch $DIR/$tdir
9825         cancel_lru_locks mdc
9826         stat $DIR/$tdir > /dev/null
9827         can1=$(do_facet mds1 \
9828                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9829                awk '/ldlm_cancel/ {print $2}')
9830         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9831                awk '/ldlm_bl_callback/ {print $2}')
9832         chmod a+x $DIR/$tdir
9833         can2=$(do_facet mds1 \
9834                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9835                awk '/ldlm_cancel/ {print $2}')
9836         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9837                awk '/ldlm_bl_callback/ {print $2}')
9838         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9839         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9840         lru_resize_enable mdc
9841         lru_resize_enable osc
9842 }
9843 run_test 120d "Early Lock Cancel: setattr test"
9844
9845 test_120e() {
9846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9847         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9848                 skip_env "no early lock cancel on server"
9849         remote_mds_nodsh && skip "remote MDS with nodsh"
9850
9851         local dlmtrace_set=false
9852
9853         test_mkdir -i0 -c1 $DIR/$tdir
9854         lru_resize_disable mdc
9855         lru_resize_disable osc
9856         ! $LCTL get_param debug | grep -q dlmtrace &&
9857                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9858         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9859         cancel_lru_locks mdc
9860         cancel_lru_locks osc
9861         dd if=$DIR/$tdir/f1 of=/dev/null
9862         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9863         # XXX client can not do early lock cancel of OST lock
9864         # during unlink (LU-4206), so cancel osc lock now.
9865         sleep 2
9866         cancel_lru_locks osc
9867         can1=$(do_facet mds1 \
9868                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9869                awk '/ldlm_cancel/ {print $2}')
9870         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9871                awk '/ldlm_bl_callback/ {print $2}')
9872         unlink $DIR/$tdir/f1
9873         sleep 5
9874         can2=$(do_facet mds1 \
9875                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9876                awk '/ldlm_cancel/ {print $2}')
9877         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9878                awk '/ldlm_bl_callback/ {print $2}')
9879         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9880                 $LCTL dk $TMP/cancel.debug.txt
9881         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9882                 $LCTL dk $TMP/blocking.debug.txt
9883         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9884         lru_resize_enable mdc
9885         lru_resize_enable osc
9886 }
9887 run_test 120e "Early Lock Cancel: unlink test"
9888
9889 test_120f() {
9890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9891         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9892                 skip_env "no early lock cancel on server"
9893         remote_mds_nodsh && skip "remote MDS with nodsh"
9894
9895         test_mkdir -i0 -c1 $DIR/$tdir
9896         lru_resize_disable mdc
9897         lru_resize_disable osc
9898         test_mkdir -i0 -c1 $DIR/$tdir/d1
9899         test_mkdir -i0 -c1 $DIR/$tdir/d2
9900         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9901         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9902         cancel_lru_locks mdc
9903         cancel_lru_locks osc
9904         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9905         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9906         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9907         # XXX client can not do early lock cancel of OST lock
9908         # during rename (LU-4206), so cancel osc lock now.
9909         sleep 2
9910         cancel_lru_locks osc
9911         can1=$(do_facet mds1 \
9912                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9913                awk '/ldlm_cancel/ {print $2}')
9914         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9915                awk '/ldlm_bl_callback/ {print $2}')
9916         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9917         sleep 5
9918         can2=$(do_facet mds1 \
9919                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9920                awk '/ldlm_cancel/ {print $2}')
9921         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9922                awk '/ldlm_bl_callback/ {print $2}')
9923         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9924         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9925         lru_resize_enable mdc
9926         lru_resize_enable osc
9927 }
9928 run_test 120f "Early Lock Cancel: rename test"
9929
9930 test_120g() {
9931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9932         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9933                 skip_env "no early lock cancel on server"
9934         remote_mds_nodsh && skip "remote MDS with nodsh"
9935
9936         lru_resize_disable mdc
9937         lru_resize_disable osc
9938         count=10000
9939         echo create $count files
9940         test_mkdir $DIR/$tdir
9941         cancel_lru_locks mdc
9942         cancel_lru_locks osc
9943         t0=$(date +%s)
9944
9945         can0=$(do_facet $SINGLEMDS \
9946                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9947                awk '/ldlm_cancel/ {print $2}')
9948         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9949                awk '/ldlm_bl_callback/ {print $2}')
9950         createmany -o $DIR/$tdir/f $count
9951         sync
9952         can1=$(do_facet $SINGLEMDS \
9953                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9954                awk '/ldlm_cancel/ {print $2}')
9955         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9956                awk '/ldlm_bl_callback/ {print $2}')
9957         t1=$(date +%s)
9958         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
9959         echo rm $count files
9960         rm -r $DIR/$tdir
9961         sync
9962         can2=$(do_facet $SINGLEMDS \
9963                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9964                awk '/ldlm_cancel/ {print $2}')
9965         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9966                awk '/ldlm_bl_callback/ {print $2}')
9967         t2=$(date +%s)
9968         echo total: $count removes in $((t2-t1))
9969         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
9970         sleep 2
9971         # wait for commitment of removal
9972         lru_resize_enable mdc
9973         lru_resize_enable osc
9974 }
9975 run_test 120g "Early Lock Cancel: performance test"
9976
9977 test_121() { #bug #10589
9978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9979
9980         rm -rf $DIR/$tfile
9981         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
9982 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
9983         lctl set_param fail_loc=0x310
9984         cancel_lru_locks osc > /dev/null
9985         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
9986         lctl set_param fail_loc=0
9987         [[ $reads -eq $writes ]] ||
9988                 error "read $reads blocks, must be $writes blocks"
9989 }
9990 run_test 121 "read cancel race ========="
9991
9992 test_123a() { # was test 123, statahead(bug 11401)
9993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9994
9995         SLOWOK=0
9996         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
9997                 log "testing UP system. Performance may be lower than expected."
9998                 SLOWOK=1
9999         fi
10000
10001         rm -rf $DIR/$tdir
10002         test_mkdir $DIR/$tdir
10003         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10004         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10005         MULT=10
10006         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10007                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10008
10009                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10010                 lctl set_param -n llite.*.statahead_max 0
10011                 lctl get_param llite.*.statahead_max
10012                 cancel_lru_locks mdc
10013                 cancel_lru_locks osc
10014                 stime=`date +%s`
10015                 time ls -l $DIR/$tdir | wc -l
10016                 etime=`date +%s`
10017                 delta=$((etime - stime))
10018                 log "ls $i files without statahead: $delta sec"
10019                 lctl set_param llite.*.statahead_max=$max
10020
10021                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10022                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10023                 cancel_lru_locks mdc
10024                 cancel_lru_locks osc
10025                 stime=`date +%s`
10026                 time ls -l $DIR/$tdir | wc -l
10027                 etime=`date +%s`
10028                 delta_sa=$((etime - stime))
10029                 log "ls $i files with statahead: $delta_sa sec"
10030                 lctl get_param -n llite.*.statahead_stats
10031                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10032
10033                 [[ $swrong -lt $ewrong ]] &&
10034                         log "statahead was stopped, maybe too many locks held!"
10035                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10036
10037                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10038                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10039                     lctl set_param -n llite.*.statahead_max 0
10040                     lctl get_param llite.*.statahead_max
10041                     cancel_lru_locks mdc
10042                     cancel_lru_locks osc
10043                     stime=`date +%s`
10044                     time ls -l $DIR/$tdir | wc -l
10045                     etime=`date +%s`
10046                     delta=$((etime - stime))
10047                     log "ls $i files again without statahead: $delta sec"
10048                     lctl set_param llite.*.statahead_max=$max
10049                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10050                         if [  $SLOWOK -eq 0 ]; then
10051                                 error "ls $i files is slower with statahead!"
10052                         else
10053                                 log "ls $i files is slower with statahead!"
10054                         fi
10055                         break
10056                     fi
10057                 fi
10058
10059                 [ $delta -gt 20 ] && break
10060                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10061                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10062         done
10063         log "ls done"
10064
10065         stime=`date +%s`
10066         rm -r $DIR/$tdir
10067         sync
10068         etime=`date +%s`
10069         delta=$((etime - stime))
10070         log "rm -r $DIR/$tdir/: $delta seconds"
10071         log "rm done"
10072         lctl get_param -n llite.*.statahead_stats
10073 }
10074 run_test 123a "verify statahead work"
10075
10076 test_123b () { # statahead(bug 15027)
10077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10078
10079         test_mkdir $DIR/$tdir
10080         createmany -o $DIR/$tdir/$tfile-%d 1000
10081
10082         cancel_lru_locks mdc
10083         cancel_lru_locks osc
10084
10085 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10086         lctl set_param fail_loc=0x80000803
10087         ls -lR $DIR/$tdir > /dev/null
10088         log "ls done"
10089         lctl set_param fail_loc=0x0
10090         lctl get_param -n llite.*.statahead_stats
10091         rm -r $DIR/$tdir
10092         sync
10093
10094 }
10095 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10096
10097 test_124a() {
10098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10099         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10100                 skip_env "no lru resize on server"
10101
10102         local NR=2000
10103
10104         test_mkdir $DIR/$tdir
10105
10106         log "create $NR files at $DIR/$tdir"
10107         createmany -o $DIR/$tdir/f $NR ||
10108                 error "failed to create $NR files in $DIR/$tdir"
10109
10110         cancel_lru_locks mdc
10111         ls -l $DIR/$tdir > /dev/null
10112
10113         local NSDIR=""
10114         local LRU_SIZE=0
10115         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10116                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10117                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10118                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10119                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10120                         log "NSDIR=$NSDIR"
10121                         log "NS=$(basename $NSDIR)"
10122                         break
10123                 fi
10124         done
10125
10126         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10127                 skip "Not enough cached locks created!"
10128         fi
10129         log "LRU=$LRU_SIZE"
10130
10131         local SLEEP=30
10132
10133         # We know that lru resize allows one client to hold $LIMIT locks
10134         # for 10h. After that locks begin to be killed by client.
10135         local MAX_HRS=10
10136         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10137         log "LIMIT=$LIMIT"
10138         if [ $LIMIT -lt $LRU_SIZE ]; then
10139                 skip "Limit is too small $LIMIT"
10140         fi
10141
10142         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10143         # killing locks. Some time was spent for creating locks. This means
10144         # that up to the moment of sleep finish we must have killed some of
10145         # them (10-100 locks). This depends on how fast ther were created.
10146         # Many of them were touched in almost the same moment and thus will
10147         # be killed in groups.
10148         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10149
10150         # Use $LRU_SIZE_B here to take into account real number of locks
10151         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10152         local LRU_SIZE_B=$LRU_SIZE
10153         log "LVF=$LVF"
10154         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10155         log "OLD_LVF=$OLD_LVF"
10156         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10157
10158         # Let's make sure that we really have some margin. Client checks
10159         # cached locks every 10 sec.
10160         SLEEP=$((SLEEP+20))
10161         log "Sleep ${SLEEP} sec"
10162         local SEC=0
10163         while ((SEC<$SLEEP)); do
10164                 echo -n "..."
10165                 sleep 5
10166                 SEC=$((SEC+5))
10167                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10168                 echo -n "$LRU_SIZE"
10169         done
10170         echo ""
10171         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10172         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10173
10174         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10175                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10176                 unlinkmany $DIR/$tdir/f $NR
10177                 return
10178         }
10179
10180         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10181         log "unlink $NR files at $DIR/$tdir"
10182         unlinkmany $DIR/$tdir/f $NR
10183 }
10184 run_test 124a "lru resize ======================================="
10185
10186 get_max_pool_limit()
10187 {
10188         local limit=$($LCTL get_param \
10189                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10190         local max=0
10191         for l in $limit; do
10192                 if [[ $l -gt $max ]]; then
10193                         max=$l
10194                 fi
10195         done
10196         echo $max
10197 }
10198
10199 test_124b() {
10200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10201         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10202                 skip_env "no lru resize on server"
10203
10204         LIMIT=$(get_max_pool_limit)
10205
10206         NR=$(($(default_lru_size)*20))
10207         if [[ $NR -gt $LIMIT ]]; then
10208                 log "Limit lock number by $LIMIT locks"
10209                 NR=$LIMIT
10210         fi
10211
10212         IFree=$(mdsrate_inodes_available)
10213         if [ $IFree -lt $NR ]; then
10214                 log "Limit lock number by $IFree inodes"
10215                 NR=$IFree
10216         fi
10217
10218         lru_resize_disable mdc
10219         test_mkdir -p $DIR/$tdir/disable_lru_resize
10220
10221         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10222         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10223         cancel_lru_locks mdc
10224         stime=`date +%s`
10225         PID=""
10226         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10227         PID="$PID $!"
10228         sleep 2
10229         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10230         PID="$PID $!"
10231         sleep 2
10232         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10233         PID="$PID $!"
10234         wait $PID
10235         etime=`date +%s`
10236         nolruresize_delta=$((etime-stime))
10237         log "ls -la time: $nolruresize_delta seconds"
10238         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10239         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10240
10241         lru_resize_enable mdc
10242         test_mkdir -p $DIR/$tdir/enable_lru_resize
10243
10244         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10245         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10246         cancel_lru_locks mdc
10247         stime=`date +%s`
10248         PID=""
10249         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10250         PID="$PID $!"
10251         sleep 2
10252         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10253         PID="$PID $!"
10254         sleep 2
10255         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10256         PID="$PID $!"
10257         wait $PID
10258         etime=`date +%s`
10259         lruresize_delta=$((etime-stime))
10260         log "ls -la time: $lruresize_delta seconds"
10261         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10262
10263         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10264                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10265         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10266                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10267         else
10268                 log "lru resize performs the same with no lru resize"
10269         fi
10270         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10271 }
10272 run_test 124b "lru resize (performance test) ======================="
10273
10274 test_124c() {
10275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10276         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10277                 skip_env "no lru resize on server"
10278
10279         # cache ununsed locks on client
10280         local nr=100
10281         cancel_lru_locks mdc
10282         test_mkdir $DIR/$tdir
10283         createmany -o $DIR/$tdir/f $nr ||
10284                 error "failed to create $nr files in $DIR/$tdir"
10285         ls -l $DIR/$tdir > /dev/null
10286
10287         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10288         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10289         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10290         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10291         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10292
10293         # set lru_max_age to 1 sec
10294         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10295         echo "sleep $((recalc_p * 2)) seconds..."
10296         sleep $((recalc_p * 2))
10297
10298         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10299         # restore lru_max_age
10300         $LCTL set_param -n $nsdir.lru_max_age $max_age
10301         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10302         unlinkmany $DIR/$tdir/f $nr
10303 }
10304 run_test 124c "LRUR cancel very aged locks"
10305
10306 test_125() { # 13358
10307         $LCTL get_param -n llite.*.client_type | grep -q local ||
10308                 skip "must run as local client"
10309         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10310                 skip_env "must have acl enabled"
10311         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10312
10313         test_mkdir $DIR/$tdir
10314         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10315         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10316         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10317 }
10318 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10319
10320 test_126() { # bug 12829/13455
10321         $GSS && skip_env "must run as gss disabled"
10322         $LCTL get_param -n llite.*.client_type | grep -q local ||
10323                 skip "must run as local client"
10324         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10325
10326         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10327         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10328         rm -f $DIR/$tfile
10329         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10330 }
10331 run_test 126 "check that the fsgid provided by the client is taken into account"
10332
10333 test_127a() { # bug 15521
10334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10335
10336         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10337         $LCTL set_param osc.*.stats=0
10338         FSIZE=$((2048 * 1024))
10339         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10340         cancel_lru_locks osc
10341         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10342
10343         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10344         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10345                 echo "got $COUNT $NAME"
10346                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10347                 eval $NAME=$COUNT || error "Wrong proc format"
10348
10349                 case $NAME in
10350                         read_bytes|write_bytes)
10351                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10352                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10353                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10354                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10355                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10356                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10357                                 error "sumsquare is too small: $SUMSQ"
10358                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10359                                 error "sumsquare is too big: $SUMSQ"
10360                         ;;
10361                         *) ;;
10362                 esac
10363         done < $DIR/${tfile}.tmp
10364
10365         #check that we actually got some stats
10366         [ "$read_bytes" ] || error "Missing read_bytes stats"
10367         [ "$write_bytes" ] || error "Missing write_bytes stats"
10368         [ "$read_bytes" != 0 ] || error "no read done"
10369         [ "$write_bytes" != 0 ] || error "no write done"
10370 }
10371 run_test 127a "verify the client stats are sane"
10372
10373 test_127b() { # bug LU-333
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375         local name count samp unit min max sum sumsq
10376
10377         $LCTL set_param llite.*.stats=0
10378
10379         # perform 2 reads and writes so MAX is different from SUM.
10380         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10381         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10382         cancel_lru_locks osc
10383         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10384         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10385
10386         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10387         while read name count samp unit min max sum sumsq; do
10388                 echo "got $count $name"
10389                 eval $name=$count || error "Wrong proc format"
10390
10391                 case $name in
10392                 read_bytes)
10393                         [ $count -ne 2 ] && error "count is not 2: $count"
10394                         [ $min -ne $PAGE_SIZE ] &&
10395                                 error "min is not $PAGE_SIZE: $min"
10396                         [ $max -ne $PAGE_SIZE ] &&
10397                                 error "max is incorrect: $max"
10398                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10399                                 error "sum is wrong: $sum"
10400                         ;;
10401                 write_bytes)
10402                         [ $count -ne 2 ] && error "count is not 2: $count"
10403                         [ $min -ne $PAGE_SIZE ] &&
10404                                 error "min is not $PAGE_SIZE: $min"
10405                         [ $max -ne $PAGE_SIZE ] &&
10406                                 error "max is incorrect: $max"
10407                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10408                                 error "sum is wrong: $sum"
10409                         ;;
10410                 *) ;;
10411                 esac
10412         done < $TMP/$tfile.tmp
10413
10414         #check that we actually got some stats
10415         [ "$read_bytes" ] || error "Missing read_bytes stats"
10416         [ "$write_bytes" ] || error "Missing write_bytes stats"
10417         [ "$read_bytes" != 0 ] || error "no read done"
10418         [ "$write_bytes" != 0 ] || error "no write done"
10419
10420         rm -f $TMP/${tfile}.tmp
10421 }
10422 run_test 127b "verify the llite client stats are sane"
10423
10424 test_128() { # bug 15212
10425         touch $DIR/$tfile
10426         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10427                 find $DIR/$tfile
10428                 find $DIR/$tfile
10429         EOF
10430
10431         result=$(grep error $TMP/$tfile.log)
10432         rm -f $DIR/$tfile $TMP/$tfile.log
10433         [ -z "$result" ] ||
10434                 error "consecutive find's under interactive lfs failed"
10435 }
10436 run_test 128 "interactive lfs for 2 consecutive find's"
10437
10438 set_dir_limits () {
10439         local mntdev
10440         local canondev
10441         local node
10442
10443         local ldproc=/proc/fs/ldiskfs
10444         local facets=$(get_facets MDS)
10445
10446         for facet in ${facets//,/ }; do
10447                 canondev=$(ldiskfs_canon \
10448                            *.$(convert_facet2label $facet).mntdev $facet)
10449                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10450                         ldproc=/sys/fs/ldiskfs
10451                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10452                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10453         done
10454 }
10455
10456 check_mds_dmesg() {
10457         local facets=$(get_facets MDS)
10458         for facet in ${facets//,/ }; do
10459                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10460         done
10461         return 1
10462 }
10463
10464 test_129() {
10465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10466         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10467                 skip "Need MDS version with at least 2.5.56"
10468         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10469                 skip_env "ldiskfs only test"
10470         fi
10471         remote_mds_nodsh && skip "remote MDS with nodsh"
10472
10473         local ENOSPC=28
10474         local EFBIG=27
10475         local has_warning=false
10476
10477         rm -rf $DIR/$tdir
10478         mkdir -p $DIR/$tdir
10479
10480         # block size of mds1
10481         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10482         set_dir_limits $maxsize $maxsize
10483         local dirsize=$(stat -c%s "$DIR/$tdir")
10484         local nfiles=0
10485         while [[ $dirsize -le $maxsize ]]; do
10486                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10487                 rc=$?
10488                 if ! $has_warning; then
10489                         check_mds_dmesg '"is approaching"' && has_warning=true
10490                 fi
10491                 # check two errors:
10492                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10493                 # EFBIG for previous versions included in ldiskfs series
10494                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
10495                         set_dir_limits 0 0
10496                         echo "return code $rc received as expected"
10497
10498                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10499                                 error_exit "create failed w/o dir size limit"
10500
10501                         check_mds_dmesg '"has reached"' ||
10502                                 error_exit "reached message should be output"
10503
10504                         [ $has_warning = "false" ] &&
10505                                 error_exit "warning message should be output"
10506
10507                         dirsize=$(stat -c%s "$DIR/$tdir")
10508
10509                         [[ $dirsize -ge $maxsize ]] && return 0
10510                         error_exit "current dir size $dirsize, " \
10511                                    "previous limit $maxsize"
10512                 elif [ $rc -ne 0 ]; then
10513                         set_dir_limits 0 0
10514                         error_exit "return $rc received instead of expected " \
10515                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10516                 fi
10517                 nfiles=$((nfiles + 1))
10518                 dirsize=$(stat -c%s "$DIR/$tdir")
10519         done
10520
10521         set_dir_limits 0 0
10522         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10523 }
10524 run_test 129 "test directory size limit ========================"
10525
10526 OLDIFS="$IFS"
10527 cleanup_130() {
10528         trap 0
10529         IFS="$OLDIFS"
10530 }
10531
10532 test_130a() {
10533         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10534         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10535
10536         trap cleanup_130 EXIT RETURN
10537
10538         local fm_file=$DIR/$tfile
10539         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10540         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10541                 error "dd failed for $fm_file"
10542
10543         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10544         filefrag -ves $fm_file
10545         RC=$?
10546         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10547                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10548         [ $RC != 0 ] && error "filefrag $fm_file failed"
10549
10550         filefrag_op=$(filefrag -ve -k $fm_file |
10551                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10552         lun=$($LFS getstripe -i $fm_file)
10553
10554         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10555         IFS=$'\n'
10556         tot_len=0
10557         for line in $filefrag_op
10558         do
10559                 frag_lun=`echo $line | cut -d: -f5`
10560                 ext_len=`echo $line | cut -d: -f4`
10561                 if (( $frag_lun != $lun )); then
10562                         cleanup_130
10563                         error "FIEMAP on 1-stripe file($fm_file) failed"
10564                         return
10565                 fi
10566                 (( tot_len += ext_len ))
10567         done
10568
10569         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10570                 cleanup_130
10571                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10572                 return
10573         fi
10574
10575         cleanup_130
10576
10577         echo "FIEMAP on single striped file succeeded"
10578 }
10579 run_test 130a "FIEMAP (1-stripe file)"
10580
10581 test_130b() {
10582         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10583
10584         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10585         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10586
10587         trap cleanup_130 EXIT RETURN
10588
10589         local fm_file=$DIR/$tfile
10590         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10591                         error "setstripe on $fm_file"
10592         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10593                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10594
10595         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10596                 error "dd failed on $fm_file"
10597
10598         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10599         filefrag_op=$(filefrag -ve -k $fm_file |
10600                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10601
10602         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10603                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10604
10605         IFS=$'\n'
10606         tot_len=0
10607         num_luns=1
10608         for line in $filefrag_op
10609         do
10610                 frag_lun=$(echo $line | cut -d: -f5 |
10611                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10612                 ext_len=$(echo $line | cut -d: -f4)
10613                 if (( $frag_lun != $last_lun )); then
10614                         if (( tot_len != 1024 )); then
10615                                 cleanup_130
10616                                 error "FIEMAP on $fm_file failed; returned " \
10617                                 "len $tot_len for OST $last_lun instead of 1024"
10618                                 return
10619                         else
10620                                 (( num_luns += 1 ))
10621                                 tot_len=0
10622                         fi
10623                 fi
10624                 (( tot_len += ext_len ))
10625                 last_lun=$frag_lun
10626         done
10627         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10628                 cleanup_130
10629                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10630                         "luns or wrong len for OST $last_lun"
10631                 return
10632         fi
10633
10634         cleanup_130
10635
10636         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10637 }
10638 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10639
10640 test_130c() {
10641         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10642
10643         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10644         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10645
10646         trap cleanup_130 EXIT RETURN
10647
10648         local fm_file=$DIR/$tfile
10649         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10650         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10651                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10652
10653         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10654                         error "dd failed on $fm_file"
10655
10656         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10657         filefrag_op=$(filefrag -ve -k $fm_file |
10658                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10659
10660         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10661                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10662
10663         IFS=$'\n'
10664         tot_len=0
10665         num_luns=1
10666         for line in $filefrag_op
10667         do
10668                 frag_lun=$(echo $line | cut -d: -f5 |
10669                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10670                 ext_len=$(echo $line | cut -d: -f4)
10671                 if (( $frag_lun != $last_lun )); then
10672                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10673                         if (( logical != 512 )); then
10674                                 cleanup_130
10675                                 error "FIEMAP on $fm_file failed; returned " \
10676                                 "logical start for lun $logical instead of 512"
10677                                 return
10678                         fi
10679                         if (( tot_len != 512 )); then
10680                                 cleanup_130
10681                                 error "FIEMAP on $fm_file failed; returned " \
10682                                 "len $tot_len for OST $last_lun instead of 1024"
10683                                 return
10684                         else
10685                                 (( num_luns += 1 ))
10686                                 tot_len=0
10687                         fi
10688                 fi
10689                 (( tot_len += ext_len ))
10690                 last_lun=$frag_lun
10691         done
10692         if (( num_luns != 2 || tot_len != 512 )); then
10693                 cleanup_130
10694                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10695                         "luns or wrong len for OST $last_lun"
10696                 return
10697         fi
10698
10699         cleanup_130
10700
10701         echo "FIEMAP on 2-stripe file with hole succeeded"
10702 }
10703 run_test 130c "FIEMAP (2-stripe file with hole)"
10704
10705 test_130d() {
10706         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10707
10708         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10709         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10710
10711         trap cleanup_130 EXIT RETURN
10712
10713         local fm_file=$DIR/$tfile
10714         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10715                         error "setstripe on $fm_file"
10716         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10717                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10718
10719         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10720         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10721                 error "dd failed on $fm_file"
10722
10723         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10724         filefrag_op=$(filefrag -ve -k $fm_file |
10725                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10726
10727         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10728                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10729
10730         IFS=$'\n'
10731         tot_len=0
10732         num_luns=1
10733         for line in $filefrag_op
10734         do
10735                 frag_lun=$(echo $line | cut -d: -f5 |
10736                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10737                 ext_len=$(echo $line | cut -d: -f4)
10738                 if (( $frag_lun != $last_lun )); then
10739                         if (( tot_len != 1024 )); then
10740                                 cleanup_130
10741                                 error "FIEMAP on $fm_file failed; returned " \
10742                                 "len $tot_len for OST $last_lun instead of 1024"
10743                                 return
10744                         else
10745                                 (( num_luns += 1 ))
10746                                 tot_len=0
10747                         fi
10748                 fi
10749                 (( tot_len += ext_len ))
10750                 last_lun=$frag_lun
10751         done
10752         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10753                 cleanup_130
10754                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10755                         "luns or wrong len for OST $last_lun"
10756                 return
10757         fi
10758
10759         cleanup_130
10760
10761         echo "FIEMAP on N-stripe file succeeded"
10762 }
10763 run_test 130d "FIEMAP (N-stripe file)"
10764
10765 test_130e() {
10766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10767
10768         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10769         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10770
10771         trap cleanup_130 EXIT RETURN
10772
10773         local fm_file=$DIR/$tfile
10774         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10775         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10776                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10777
10778         NUM_BLKS=512
10779         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10780         for ((i = 0; i < $NUM_BLKS; i++))
10781         do
10782                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10783         done
10784
10785         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10786         filefrag_op=$(filefrag -ve -k $fm_file |
10787                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10788
10789         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10790                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10791
10792         IFS=$'\n'
10793         tot_len=0
10794         num_luns=1
10795         for line in $filefrag_op
10796         do
10797                 frag_lun=$(echo $line | cut -d: -f5 |
10798                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10799                 ext_len=$(echo $line | cut -d: -f4)
10800                 if (( $frag_lun != $last_lun )); then
10801                         if (( tot_len != $EXPECTED_LEN )); then
10802                                 cleanup_130
10803                                 error "FIEMAP on $fm_file failed; returned " \
10804                                 "len $tot_len for OST $last_lun instead " \
10805                                 "of $EXPECTED_LEN"
10806                                 return
10807                         else
10808                                 (( num_luns += 1 ))
10809                                 tot_len=0
10810                         fi
10811                 fi
10812                 (( tot_len += ext_len ))
10813                 last_lun=$frag_lun
10814         done
10815         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10816                 cleanup_130
10817                 error "FIEMAP on $fm_file failed; returned wrong number " \
10818                         "of luns or wrong len for OST $last_lun"
10819                 return
10820         fi
10821
10822         cleanup_130
10823
10824         echo "FIEMAP with continuation calls succeeded"
10825 }
10826 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10827
10828 test_130f() {
10829         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10830         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10831
10832         local fm_file=$DIR/$tfile
10833         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10834                 error "multiop create with lov_delay_create on $fm_file"
10835
10836         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10837         filefrag_extents=$(filefrag -vek $fm_file |
10838                            awk '/extents? found/ { print $2 }')
10839         if [[ "$filefrag_extents" != "0" ]]; then
10840                 error "FIEMAP on $fm_file failed; " \
10841                       "returned $filefrag_extents expected 0"
10842         fi
10843
10844         rm -f $fm_file
10845 }
10846 run_test 130f "FIEMAP (unstriped file)"
10847
10848 # Test for writev/readv
10849 test_131a() {
10850         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10851                 error "writev test failed"
10852         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10853                 error "readv failed"
10854         rm -f $DIR/$tfile
10855 }
10856 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10857
10858 test_131b() {
10859         local fsize=$((524288 + 1048576 + 1572864))
10860         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10861                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10862                         error "append writev test failed"
10863
10864         ((fsize += 1572864 + 1048576))
10865         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10866                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10867                         error "append writev test failed"
10868         rm -f $DIR/$tfile
10869 }
10870 run_test 131b "test append writev"
10871
10872 test_131c() {
10873         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10874         error "NOT PASS"
10875 }
10876 run_test 131c "test read/write on file w/o objects"
10877
10878 test_131d() {
10879         rwv -f $DIR/$tfile -w -n 1 1572864
10880         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10881         if [ "$NOB" != 1572864 ]; then
10882                 error "Short read filed: read $NOB bytes instead of 1572864"
10883         fi
10884         rm -f $DIR/$tfile
10885 }
10886 run_test 131d "test short read"
10887
10888 test_131e() {
10889         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10890         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10891         error "read hitting hole failed"
10892         rm -f $DIR/$tfile
10893 }
10894 run_test 131e "test read hitting hole"
10895
10896 check_stats() {
10897         local facet=$1
10898         local op=$2
10899         local want=${3:-0}
10900         local res
10901
10902         case $facet in
10903         mds*) res=$(do_facet $facet \
10904                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10905                  ;;
10906         ost*) res=$(do_facet $facet \
10907                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10908                  ;;
10909         *) error "Wrong facet '$facet'" ;;
10910         esac
10911         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10912         # if the argument $3 is zero, it means any stat increment is ok.
10913         if [[ $want -gt 0 ]]; then
10914                 local count=$(echo $res | awk '{ print $2 }')
10915                 [[ $count -ne $want ]] &&
10916                         error "The $op counter on $facet is $count, not $want"
10917         fi
10918 }
10919
10920 test_133a() {
10921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10922         remote_ost_nodsh && skip "remote OST with nodsh"
10923         remote_mds_nodsh && skip "remote MDS with nodsh"
10924         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10925                 skip_env "MDS doesn't support rename stats"
10926
10927         local testdir=$DIR/${tdir}/stats_testdir
10928
10929         mkdir -p $DIR/${tdir}
10930
10931         # clear stats.
10932         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10933         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10934
10935         # verify mdt stats first.
10936         mkdir ${testdir} || error "mkdir failed"
10937         check_stats $SINGLEMDS "mkdir" 1
10938         touch ${testdir}/${tfile} || error "touch failed"
10939         check_stats $SINGLEMDS "open" 1
10940         check_stats $SINGLEMDS "close" 1
10941         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10942                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10943                 check_stats $SINGLEMDS "mknod" 2
10944         }
10945         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10946         check_stats $SINGLEMDS "unlink" 1
10947         rm -f ${testdir}/${tfile} || error "file remove failed"
10948         check_stats $SINGLEMDS "unlink" 2
10949
10950         # remove working dir and check mdt stats again.
10951         rmdir ${testdir} || error "rmdir failed"
10952         check_stats $SINGLEMDS "rmdir" 1
10953
10954         local testdir1=$DIR/${tdir}/stats_testdir1
10955         mkdir -p ${testdir}
10956         mkdir -p ${testdir1}
10957         touch ${testdir1}/test1
10958         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
10959         check_stats $SINGLEMDS "crossdir_rename" 1
10960
10961         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
10962         check_stats $SINGLEMDS "samedir_rename" 1
10963
10964         rm -rf $DIR/${tdir}
10965 }
10966 run_test 133a "Verifying MDT stats ========================================"
10967
10968 test_133b() {
10969         local res
10970
10971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10972         remote_ost_nodsh && skip "remote OST with nodsh"
10973         remote_mds_nodsh && skip "remote MDS with nodsh"
10974
10975         local testdir=$DIR/${tdir}/stats_testdir
10976
10977         mkdir -p ${testdir} || error "mkdir failed"
10978         touch ${testdir}/${tfile} || error "touch failed"
10979         cancel_lru_locks mdc
10980
10981         # clear stats.
10982         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10983         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10984
10985         # extra mdt stats verification.
10986         chmod 444 ${testdir}/${tfile} || error "chmod failed"
10987         check_stats $SINGLEMDS "setattr" 1
10988         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10989         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
10990         then            # LU-1740
10991                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
10992                 check_stats $SINGLEMDS "getattr" 1
10993         fi
10994         rm -rf $DIR/${tdir}
10995
10996         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
10997         # so the check below is not reliable
10998         [ $MDSCOUNT -eq 1 ] || return 0
10999
11000         # Sleep to avoid a cached response.
11001         #define OBD_STATFS_CACHE_SECONDS 1
11002         sleep 2
11003         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11004         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11005         $LFS df || error "lfs failed"
11006         check_stats $SINGLEMDS "statfs" 1
11007
11008         # check aggregated statfs (LU-10018)
11009         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11010                 return 0
11011         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11012                 return 0
11013         sleep 2
11014         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11015         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11016         df $DIR
11017         check_stats $SINGLEMDS "statfs" 1
11018
11019         # We want to check that the client didn't send OST_STATFS to
11020         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11021         # extra care is needed here.
11022         if remote_mds; then
11023                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11024                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11025
11026                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11027                 [ "$res" ] && error "OST got STATFS"
11028         fi
11029
11030         return 0
11031 }
11032 run_test 133b "Verifying extra MDT stats =================================="
11033
11034 test_133c() {
11035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11036         remote_ost_nodsh && skip "remote OST with nodsh"
11037         remote_mds_nodsh && skip "remote MDS with nodsh"
11038
11039         local testdir=$DIR/$tdir/stats_testdir
11040
11041         test_mkdir -p $testdir
11042
11043         # verify obdfilter stats.
11044         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11045         sync
11046         cancel_lru_locks osc
11047         wait_delete_completed
11048
11049         # clear stats.
11050         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11051         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11052
11053         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11054                 error "dd failed"
11055         sync
11056         cancel_lru_locks osc
11057         check_stats ost1 "write" 1
11058
11059         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11060         check_stats ost1 "read" 1
11061
11062         > $testdir/$tfile || error "truncate failed"
11063         check_stats ost1 "punch" 1
11064
11065         rm -f $testdir/$tfile || error "file remove failed"
11066         wait_delete_completed
11067         check_stats ost1 "destroy" 1
11068
11069         rm -rf $DIR/$tdir
11070 }
11071 run_test 133c "Verifying OST stats ========================================"
11072
11073 order_2() {
11074         local value=$1
11075         local orig=$value
11076         local order=1
11077
11078         while [ $value -ge 2 ]; do
11079                 order=$((order*2))
11080                 value=$((value/2))
11081         done
11082
11083         if [ $orig -gt $order ]; then
11084                 order=$((order*2))
11085         fi
11086         echo $order
11087 }
11088
11089 size_in_KMGT() {
11090     local value=$1
11091     local size=('K' 'M' 'G' 'T');
11092     local i=0
11093     local size_string=$value
11094
11095     while [ $value -ge 1024 ]; do
11096         if [ $i -gt 3 ]; then
11097             #T is the biggest unit we get here, if that is bigger,
11098             #just return XXXT
11099             size_string=${value}T
11100             break
11101         fi
11102         value=$((value >> 10))
11103         if [ $value -lt 1024 ]; then
11104             size_string=${value}${size[$i]}
11105             break
11106         fi
11107         i=$((i + 1))
11108     done
11109
11110     echo $size_string
11111 }
11112
11113 get_rename_size() {
11114         local size=$1
11115         local context=${2:-.}
11116         local sample=$(do_facet $SINGLEMDS $LCTL \
11117                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11118                 grep -A1 $context |
11119                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11120         echo $sample
11121 }
11122
11123 test_133d() {
11124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11125         remote_ost_nodsh && skip "remote OST with nodsh"
11126         remote_mds_nodsh && skip "remote MDS with nodsh"
11127         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11128                 skip_env "MDS doesn't support rename stats"
11129
11130         local testdir1=$DIR/${tdir}/stats_testdir1
11131         local testdir2=$DIR/${tdir}/stats_testdir2
11132         mkdir -p $DIR/${tdir}
11133
11134         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11135
11136         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11137         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11138
11139         createmany -o $testdir1/test 512 || error "createmany failed"
11140
11141         # check samedir rename size
11142         mv ${testdir1}/test0 ${testdir1}/test_0
11143
11144         local testdir1_size=$(ls -l $DIR/${tdir} |
11145                 awk '/stats_testdir1/ {print $5}')
11146         local testdir2_size=$(ls -l $DIR/${tdir} |
11147                 awk '/stats_testdir2/ {print $5}')
11148
11149         testdir1_size=$(order_2 $testdir1_size)
11150         testdir2_size=$(order_2 $testdir2_size)
11151
11152         testdir1_size=$(size_in_KMGT $testdir1_size)
11153         testdir2_size=$(size_in_KMGT $testdir2_size)
11154
11155         echo "source rename dir size: ${testdir1_size}"
11156         echo "target rename dir size: ${testdir2_size}"
11157
11158         local cmd="do_facet $SINGLEMDS $LCTL "
11159         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11160
11161         eval $cmd || error "$cmd failed"
11162         local samedir=$($cmd | grep 'same_dir')
11163         local same_sample=$(get_rename_size $testdir1_size)
11164         [ -z "$samedir" ] && error "samedir_rename_size count error"
11165         [[ $same_sample -eq 1 ]] ||
11166                 error "samedir_rename_size error $same_sample"
11167         echo "Check same dir rename stats success"
11168
11169         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11170
11171         # check crossdir rename size
11172         mv ${testdir1}/test_0 ${testdir2}/test_0
11173
11174         testdir1_size=$(ls -l $DIR/${tdir} |
11175                 awk '/stats_testdir1/ {print $5}')
11176         testdir2_size=$(ls -l $DIR/${tdir} |
11177                 awk '/stats_testdir2/ {print $5}')
11178
11179         testdir1_size=$(order_2 $testdir1_size)
11180         testdir2_size=$(order_2 $testdir2_size)
11181
11182         testdir1_size=$(size_in_KMGT $testdir1_size)
11183         testdir2_size=$(size_in_KMGT $testdir2_size)
11184
11185         echo "source rename dir size: ${testdir1_size}"
11186         echo "target rename dir size: ${testdir2_size}"
11187
11188         eval $cmd || error "$cmd failed"
11189         local crossdir=$($cmd | grep 'crossdir')
11190         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11191         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11192         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11193         [[ $src_sample -eq 1 ]] ||
11194                 error "crossdir_rename_size error $src_sample"
11195         [[ $tgt_sample -eq 1 ]] ||
11196                 error "crossdir_rename_size error $tgt_sample"
11197         echo "Check cross dir rename stats success"
11198         rm -rf $DIR/${tdir}
11199 }
11200 run_test 133d "Verifying rename_stats ========================================"
11201
11202 test_133e() {
11203         remote_mds_nodsh && skip "remote MDS with nodsh"
11204         remote_ost_nodsh && skip "remote OST with nodsh"
11205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11206
11207         local testdir=$DIR/${tdir}/stats_testdir
11208         local ctr f0 f1 bs=32768 count=42 sum
11209
11210         mkdir -p ${testdir} || error "mkdir failed"
11211
11212         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11213
11214         for ctr in {write,read}_bytes; do
11215                 sync
11216                 cancel_lru_locks osc
11217
11218                 do_facet ost1 $LCTL set_param -n \
11219                         "obdfilter.*.exports.clear=clear"
11220
11221                 if [ $ctr = write_bytes ]; then
11222                         f0=/dev/zero
11223                         f1=${testdir}/${tfile}
11224                 else
11225                         f0=${testdir}/${tfile}
11226                         f1=/dev/null
11227                 fi
11228
11229                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11230                         error "dd failed"
11231                 sync
11232                 cancel_lru_locks osc
11233
11234                 sum=$(do_facet ost1 $LCTL get_param \
11235                         "obdfilter.*.exports.*.stats" |
11236                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11237                                 $1 == ctr { sum += $7 }
11238                                 END { printf("%0.0f", sum) }')
11239
11240                 if ((sum != bs * count)); then
11241                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11242                 fi
11243         done
11244
11245         rm -rf $DIR/${tdir}
11246 }
11247 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11248
11249 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11250
11251 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11252 # not honor the -ignore_readdir_race option correctly. So we call
11253 # error_ignore() rather than error() in these cases. See LU-11152.
11254 error_133() {
11255         if (find --version; do_facet mds1 find --version) |
11256                 grep -q '\b4\.5\.1[1-4]\b'; then
11257                 error_ignore LU-11152 "$@"
11258         else
11259                 error "$@"
11260         fi
11261 }
11262
11263 test_133f() {
11264         # First without trusting modes.
11265         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11266         echo "proc_dirs='$proc_dirs'"
11267         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11268         find $proc_dirs -exec cat '{}' \; &> /dev/null
11269
11270         # Second verifying readability.
11271         $LCTL get_param -R '*' &> /dev/null
11272
11273         # Verifing writability with badarea_io.
11274         find $proc_dirs \
11275                 -ignore_readdir_race \
11276                 -type f \
11277                 -not -name force_lbug \
11278                 -not -name changelog_mask \
11279                 -exec badarea_io '{}' \; ||
11280                         error_133 "find $proc_dirs failed"
11281 }
11282 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11283
11284 test_133g() {
11285         remote_mds_nodsh && skip "remote MDS with nodsh"
11286         remote_ost_nodsh && skip "remote OST with nodsh"
11287
11288         # eventually, this can also be replaced with "lctl get_param -R",
11289         # but not until that option is always available on the server
11290         local facet
11291         for facet in mds1 ost1; do
11292                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11293                         skip_noexit "Too old lustre on $facet"
11294                 local facet_proc_dirs=$(do_facet $facet \
11295                                         \\\ls -d $proc_regexp 2>/dev/null)
11296                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11297                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11298                 do_facet $facet find $facet_proc_dirs \
11299                         ! -name req_history \
11300                         -exec cat '{}' \\\; &> /dev/null
11301
11302                 do_facet $facet find $facet_proc_dirs \
11303                         ! -name req_history \
11304                         -type f \
11305                         -exec cat '{}' \\\; &> /dev/null ||
11306                                 error "proc file read failed"
11307
11308                 do_facet $facet find $facet_proc_dirs \
11309                         -ignore_readdir_race \
11310                         -type f \
11311                         -not -name force_lbug \
11312                         -not -name changelog_mask \
11313                         -exec badarea_io '{}' \\\; ||
11314                                 error_133 "$facet find $facet_proc_dirs failed"
11315         done
11316
11317         # remount the FS in case writes/reads /proc break the FS
11318         cleanup || error "failed to unmount"
11319         setup || error "failed to setup"
11320         true
11321 }
11322 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11323
11324 test_133h() {
11325         remote_mds_nodsh && skip "remote MDS with nodsh"
11326         remote_ost_nodsh && skip "remote OST with nodsh"
11327         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11328                 skip "Need MDS version at least 2.9.54"
11329
11330         local facet
11331
11332         for facet in client mds1 ost1; do
11333                 local facet_proc_dirs=$(do_facet $facet \
11334                                         \\\ls -d $proc_regexp 2> /dev/null)
11335                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11336                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11337                 # Get the list of files that are missing the terminating newline
11338                 local missing=($(do_facet $facet \
11339                         find ${facet_proc_dirs} -type f \|              \
11340                                 while read F\; do                       \
11341                                         awk -v FS='\v' -v RS='\v\v'     \
11342                                         "'END { if(NR>0 &&              \
11343                                         \\\$NF !~ /.*\\\n\$/)           \
11344                                                 print FILENAME}'"       \
11345                                         '\$F'\;                         \
11346                                 done 2>/dev/null))
11347                 [ ${#missing[*]} -eq 0 ] ||
11348                         error "files do not end with newline: ${missing[*]}"
11349         done
11350 }
11351 run_test 133h "Proc files should end with newlines"
11352
11353 test_134a() {
11354         remote_mds_nodsh && skip "remote MDS with nodsh"
11355         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11356                 skip "Need MDS version at least 2.7.54"
11357
11358         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11359         cancel_lru_locks mdc
11360
11361         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11362         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11363         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11364
11365         local nr=1000
11366         createmany -o $DIR/$tdir/f $nr ||
11367                 error "failed to create $nr files in $DIR/$tdir"
11368         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11369
11370         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11371         do_facet mds1 $LCTL set_param fail_loc=0x327
11372         do_facet mds1 $LCTL set_param fail_val=500
11373         touch $DIR/$tdir/m
11374
11375         echo "sleep 10 seconds ..."
11376         sleep 10
11377         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11378
11379         do_facet mds1 $LCTL set_param fail_loc=0
11380         do_facet mds1 $LCTL set_param fail_val=0
11381         [ $lck_cnt -lt $unused ] ||
11382                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11383
11384         rm $DIR/$tdir/m
11385         unlinkmany $DIR/$tdir/f $nr
11386 }
11387 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11388
11389 test_134b() {
11390         remote_mds_nodsh && skip "remote MDS with nodsh"
11391         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11392                 skip "Need MDS version at least 2.7.54"
11393
11394         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11395         cancel_lru_locks mdc
11396
11397         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11398                         ldlm.lock_reclaim_threshold_mb)
11399         # disable reclaim temporarily
11400         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11401
11402         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11403         do_facet mds1 $LCTL set_param fail_loc=0x328
11404         do_facet mds1 $LCTL set_param fail_val=500
11405
11406         $LCTL set_param debug=+trace
11407
11408         local nr=600
11409         createmany -o $DIR/$tdir/f $nr &
11410         local create_pid=$!
11411
11412         echo "Sleep $TIMEOUT seconds ..."
11413         sleep $TIMEOUT
11414         if ! ps -p $create_pid  > /dev/null 2>&1; then
11415                 do_facet mds1 $LCTL set_param fail_loc=0
11416                 do_facet mds1 $LCTL set_param fail_val=0
11417                 do_facet mds1 $LCTL set_param \
11418                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11419                 error "createmany finished incorrectly!"
11420         fi
11421         do_facet mds1 $LCTL set_param fail_loc=0
11422         do_facet mds1 $LCTL set_param fail_val=0
11423         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11424         wait $create_pid || return 1
11425
11426         unlinkmany $DIR/$tdir/f $nr
11427 }
11428 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11429
11430 test_140() { #bug-17379
11431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11432
11433         test_mkdir $DIR/$tdir
11434         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11435         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11436
11437         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11438         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11439         local i=0
11440         while i=$((i + 1)); do
11441                 test_mkdir $i
11442                 cd $i || error "Changing to $i"
11443                 ln -s ../stat stat || error "Creating stat symlink"
11444                 # Read the symlink until ELOOP present,
11445                 # not LBUGing the system is considered success,
11446                 # we didn't overrun the stack.
11447                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11448                 if [ $ret -ne 0 ]; then
11449                         if [ $ret -eq 40 ]; then
11450                                 break  # -ELOOP
11451                         else
11452                                 error "Open stat symlink"
11453                                         return
11454                         fi
11455                 fi
11456         done
11457         i=$((i - 1))
11458         echo "The symlink depth = $i"
11459         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
11460                                         error "Invalid symlink depth"
11461
11462         # Test recursive symlink
11463         ln -s symlink_self symlink_self
11464         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11465         echo "open symlink_self returns $ret"
11466         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11467 }
11468 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11469
11470 test_150() {
11471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11472
11473         local TF="$TMP/$tfile"
11474
11475         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11476         cp $TF $DIR/$tfile
11477         cancel_lru_locks $OSC
11478         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11479         remount_client $MOUNT
11480         df -P $MOUNT
11481         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11482
11483         $TRUNCATE $TF 6000
11484         $TRUNCATE $DIR/$tfile 6000
11485         cancel_lru_locks $OSC
11486         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11487
11488         echo "12345" >>$TF
11489         echo "12345" >>$DIR/$tfile
11490         cancel_lru_locks $OSC
11491         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11492
11493         echo "12345" >>$TF
11494         echo "12345" >>$DIR/$tfile
11495         cancel_lru_locks $OSC
11496         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11497
11498         rm -f $TF
11499         true
11500 }
11501 run_test 150 "truncate/append tests"
11502
11503 #LU-2902 roc_hit was not able to read all values from lproc
11504 function roc_hit_init() {
11505         local list=$(comma_list $(osts_nodes))
11506         local dir=$DIR/$tdir-check
11507         local file=$dir/$tfile
11508         local BEFORE
11509         local AFTER
11510         local idx
11511
11512         test_mkdir $dir
11513         #use setstripe to do a write to every ost
11514         for i in $(seq 0 $((OSTCOUNT-1))); do
11515                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11516                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11517                 idx=$(printf %04x $i)
11518                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11519                         awk '$1 == "cache_access" {sum += $7}
11520                                 END { printf("%0.0f", sum) }')
11521
11522                 cancel_lru_locks osc
11523                 cat $file >/dev/null
11524
11525                 AFTER=$(get_osd_param $list *OST*$idx stats |
11526                         awk '$1 == "cache_access" {sum += $7}
11527                                 END { printf("%0.0f", sum) }')
11528
11529                 echo BEFORE:$BEFORE AFTER:$AFTER
11530                 if ! let "AFTER - BEFORE == 4"; then
11531                         rm -rf $dir
11532                         error "roc_hit is not safe to use"
11533                 fi
11534                 rm $file
11535         done
11536
11537         rm -rf $dir
11538 }
11539
11540 function roc_hit() {
11541         local list=$(comma_list $(osts_nodes))
11542         echo $(get_osd_param $list '' stats |
11543                 awk '$1 == "cache_hit" {sum += $7}
11544                         END { printf("%0.0f", sum) }')
11545 }
11546
11547 function set_cache() {
11548         local on=1
11549
11550         if [ "$2" == "off" ]; then
11551                 on=0;
11552         fi
11553         local list=$(comma_list $(osts_nodes))
11554         set_osd_param $list '' $1_cache_enable $on
11555
11556         cancel_lru_locks osc
11557 }
11558
11559 test_151() {
11560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11561         remote_ost_nodsh && skip "remote OST with nodsh"
11562
11563         local CPAGES=3
11564         local list=$(comma_list $(osts_nodes))
11565
11566         # check whether obdfilter is cache capable at all
11567         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11568                 skip "not cache-capable obdfilter"
11569         fi
11570
11571         # check cache is enabled on all obdfilters
11572         if get_osd_param $list '' read_cache_enable | grep 0; then
11573                 skip "oss cache is disabled"
11574         fi
11575
11576         set_osd_param $list '' writethrough_cache_enable 1
11577
11578         # check write cache is enabled on all obdfilters
11579         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11580                 skip "oss write cache is NOT enabled"
11581         fi
11582
11583         roc_hit_init
11584
11585         #define OBD_FAIL_OBD_NO_LRU  0x609
11586         do_nodes $list $LCTL set_param fail_loc=0x609
11587
11588         # pages should be in the case right after write
11589         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11590                 error "dd failed"
11591
11592         local BEFORE=$(roc_hit)
11593         cancel_lru_locks osc
11594         cat $DIR/$tfile >/dev/null
11595         local AFTER=$(roc_hit)
11596
11597         do_nodes $list $LCTL set_param fail_loc=0
11598
11599         if ! let "AFTER - BEFORE == CPAGES"; then
11600                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11601         fi
11602
11603         # the following read invalidates the cache
11604         cancel_lru_locks osc
11605         set_osd_param $list '' read_cache_enable 0
11606         cat $DIR/$tfile >/dev/null
11607
11608         # now data shouldn't be found in the cache
11609         BEFORE=$(roc_hit)
11610         cancel_lru_locks osc
11611         cat $DIR/$tfile >/dev/null
11612         AFTER=$(roc_hit)
11613         if let "AFTER - BEFORE != 0"; then
11614                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11615         fi
11616
11617         set_osd_param $list '' read_cache_enable 1
11618         rm -f $DIR/$tfile
11619 }
11620 run_test 151 "test cache on oss and controls ==============================="
11621
11622 test_152() {
11623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11624
11625         local TF="$TMP/$tfile"
11626
11627         # simulate ENOMEM during write
11628 #define OBD_FAIL_OST_NOMEM      0x226
11629         lctl set_param fail_loc=0x80000226
11630         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11631         cp $TF $DIR/$tfile
11632         sync || error "sync failed"
11633         lctl set_param fail_loc=0
11634
11635         # discard client's cache
11636         cancel_lru_locks osc
11637
11638         # simulate ENOMEM during read
11639         lctl set_param fail_loc=0x80000226
11640         cmp $TF $DIR/$tfile || error "cmp failed"
11641         lctl set_param fail_loc=0
11642
11643         rm -f $TF
11644 }
11645 run_test 152 "test read/write with enomem ============================"
11646
11647 test_153() {
11648         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11649 }
11650 run_test 153 "test if fdatasync does not crash ======================="
11651
11652 dot_lustre_fid_permission_check() {
11653         local fid=$1
11654         local ffid=$MOUNT/.lustre/fid/$fid
11655         local test_dir=$2
11656
11657         echo "stat fid $fid"
11658         stat $ffid > /dev/null || error "stat $ffid failed."
11659         echo "touch fid $fid"
11660         touch $ffid || error "touch $ffid failed."
11661         echo "write to fid $fid"
11662         cat /etc/hosts > $ffid || error "write $ffid failed."
11663         echo "read fid $fid"
11664         diff /etc/hosts $ffid || error "read $ffid failed."
11665         echo "append write to fid $fid"
11666         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11667         echo "rename fid $fid"
11668         mv $ffid $test_dir/$tfile.1 &&
11669                 error "rename $ffid to $tfile.1 should fail."
11670         touch $test_dir/$tfile.1
11671         mv $test_dir/$tfile.1 $ffid &&
11672                 error "rename $tfile.1 to $ffid should fail."
11673         rm -f $test_dir/$tfile.1
11674         echo "truncate fid $fid"
11675         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11676         echo "link fid $fid"
11677         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11678         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11679                 echo "setfacl fid $fid"
11680                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11681                 echo "getfacl fid $fid"
11682                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11683         fi
11684         echo "unlink fid $fid"
11685         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11686         echo "mknod fid $fid"
11687         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11688
11689         fid=[0xf00000400:0x1:0x0]
11690         ffid=$MOUNT/.lustre/fid/$fid
11691
11692         echo "stat non-exist fid $fid"
11693         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11694         echo "write to non-exist fid $fid"
11695         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11696         echo "link new fid $fid"
11697         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11698
11699         mkdir -p $test_dir/$tdir
11700         touch $test_dir/$tdir/$tfile
11701         fid=$($LFS path2fid $test_dir/$tdir)
11702         rc=$?
11703         [ $rc -ne 0 ] &&
11704                 error "error: could not get fid for $test_dir/$dir/$tfile."
11705
11706         ffid=$MOUNT/.lustre/fid/$fid
11707
11708         echo "ls $fid"
11709         ls $ffid > /dev/null || error "ls $ffid failed."
11710         echo "touch $fid/$tfile.1"
11711         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11712
11713         echo "touch $MOUNT/.lustre/fid/$tfile"
11714         touch $MOUNT/.lustre/fid/$tfile && \
11715                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11716
11717         echo "setxattr to $MOUNT/.lustre/fid"
11718         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11719
11720         echo "listxattr for $MOUNT/.lustre/fid"
11721         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11722
11723         echo "delxattr from $MOUNT/.lustre/fid"
11724         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11725
11726         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11727         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11728                 error "touch invalid fid should fail."
11729
11730         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11731         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11732                 error "touch non-normal fid should fail."
11733
11734         echo "rename $tdir to $MOUNT/.lustre/fid"
11735         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11736                 error "rename to $MOUNT/.lustre/fid should fail."
11737
11738         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11739         then            # LU-3547
11740                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11741                 local new_obf_mode=777
11742
11743                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11744                 chmod $new_obf_mode $DIR/.lustre/fid ||
11745                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11746
11747                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11748                 [ $obf_mode -eq $new_obf_mode ] ||
11749                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11750
11751                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11752                 chmod $old_obf_mode $DIR/.lustre/fid ||
11753                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11754         fi
11755
11756         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11757         fid=$($LFS path2fid $test_dir/$tfile-2)
11758
11759         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11760         then # LU-5424
11761                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11762                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11763                         error "create lov data thru .lustre failed"
11764         fi
11765         echo "cp /etc/passwd $test_dir/$tfile-2"
11766         cp /etc/passwd $test_dir/$tfile-2 ||
11767                 error "copy to $test_dir/$tfile-2 failed."
11768         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11769         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11770                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11771
11772         rm -rf $test_dir/tfile.lnk
11773         rm -rf $test_dir/$tfile-2
11774 }
11775
11776 test_154A() {
11777         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11778                 skip "Need MDS version at least 2.4.1"
11779
11780         local tf=$DIR/$tfile
11781         touch $tf
11782
11783         local fid=$($LFS path2fid $tf)
11784         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11785
11786         # check that we get the same pathname back
11787         local found=$($LFS fid2path $MOUNT "$fid")
11788         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11789         [ "$found" == "$tf" ] ||
11790                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11791 }
11792 run_test 154A "lfs path2fid and fid2path basic checks"
11793
11794 test_154B() {
11795         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11796                 skip "Need MDS version at least 2.4.1"
11797
11798         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11799         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11800         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11801         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11802
11803         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11804         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11805
11806         # check that we get the same pathname
11807         echo "PFID: $PFID, name: $name"
11808         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11809         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11810         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11811                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11812
11813         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11814 }
11815 run_test 154B "verify the ll_decode_linkea tool"
11816
11817 test_154a() {
11818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11819         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11820         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11821                 skip "Need MDS version at least 2.2.51"
11822         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11823
11824         cp /etc/hosts $DIR/$tfile
11825
11826         fid=$($LFS path2fid $DIR/$tfile)
11827         rc=$?
11828         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11829
11830         dot_lustre_fid_permission_check "$fid" $DIR ||
11831                 error "dot lustre permission check $fid failed"
11832
11833         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11834
11835         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11836
11837         touch $MOUNT/.lustre/file &&
11838                 error "creation is not allowed under .lustre"
11839
11840         mkdir $MOUNT/.lustre/dir &&
11841                 error "mkdir is not allowed under .lustre"
11842
11843         rm -rf $DIR/$tfile
11844 }
11845 run_test 154a "Open-by-FID"
11846
11847 test_154b() {
11848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11849         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11851         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11852                 skip "Need MDS version at least 2.2.51"
11853
11854         local remote_dir=$DIR/$tdir/remote_dir
11855         local MDTIDX=1
11856         local rc=0
11857
11858         mkdir -p $DIR/$tdir
11859         $LFS mkdir -i $MDTIDX $remote_dir ||
11860                 error "create remote directory failed"
11861
11862         cp /etc/hosts $remote_dir/$tfile
11863
11864         fid=$($LFS path2fid $remote_dir/$tfile)
11865         rc=$?
11866         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11867
11868         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11869                 error "dot lustre permission check $fid failed"
11870         rm -rf $DIR/$tdir
11871 }
11872 run_test 154b "Open-by-FID for remote directory"
11873
11874 test_154c() {
11875         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11876                 skip "Need MDS version at least 2.4.1"
11877
11878         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11879         local FID1=$($LFS path2fid $DIR/$tfile.1)
11880         local FID2=$($LFS path2fid $DIR/$tfile.2)
11881         local FID3=$($LFS path2fid $DIR/$tfile.3)
11882
11883         local N=1
11884         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11885                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11886                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11887                 local want=FID$N
11888                 [ "$FID" = "${!want}" ] ||
11889                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11890                 N=$((N + 1))
11891         done
11892
11893         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11894         do
11895                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11896                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11897                 N=$((N + 1))
11898         done
11899 }
11900 run_test 154c "lfs path2fid and fid2path multiple arguments"
11901
11902 test_154d() {
11903         remote_mds_nodsh && skip "remote MDS with nodsh"
11904         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11905                 skip "Need MDS version at least 2.5.53"
11906
11907         if remote_mds; then
11908                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11909         else
11910                 nid="0@lo"
11911         fi
11912         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11913         local fd
11914         local cmd
11915
11916         rm -f $DIR/$tfile
11917         touch $DIR/$tfile
11918
11919         local fid=$($LFS path2fid $DIR/$tfile)
11920         # Open the file
11921         fd=$(free_fd)
11922         cmd="exec $fd<$DIR/$tfile"
11923         eval $cmd
11924         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11925         echo "$fid_list" | grep "$fid"
11926         rc=$?
11927
11928         cmd="exec $fd>/dev/null"
11929         eval $cmd
11930         if [ $rc -ne 0 ]; then
11931                 error "FID $fid not found in open files list $fid_list"
11932         fi
11933 }
11934 run_test 154d "Verify open file fid"
11935
11936 test_154e()
11937 {
11938         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11939                 skip "Need MDS version at least 2.6.50"
11940
11941         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11942                 error ".lustre returned by readdir"
11943         fi
11944 }
11945 run_test 154e ".lustre is not returned by readdir"
11946
11947 test_154f() {
11948         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11949
11950         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11951         test_mkdir -p -c1 $DIR/$tdir/d
11952         # test dirs inherit from its stripe
11953         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11954         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11955         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11956         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
11957         touch $DIR/f
11958
11959         # get fid of parents
11960         local FID0=$($LFS path2fid $DIR/$tdir/d)
11961         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
11962         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
11963         local FID3=$($LFS path2fid $DIR)
11964
11965         # check that path2fid --parents returns expected <parent_fid>/name
11966         # 1) test for a directory (single parent)
11967         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
11968         [ "$parent" == "$FID0/foo1" ] ||
11969                 error "expected parent: $FID0/foo1, got: $parent"
11970
11971         # 2) test for a file with nlink > 1 (multiple parents)
11972         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
11973         echo "$parent" | grep -F "$FID1/$tfile" ||
11974                 error "$FID1/$tfile not returned in parent list"
11975         echo "$parent" | grep -F "$FID2/link" ||
11976                 error "$FID2/link not returned in parent list"
11977
11978         # 3) get parent by fid
11979         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
11980         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11981         echo "$parent" | grep -F "$FID1/$tfile" ||
11982                 error "$FID1/$tfile not returned in parent list (by fid)"
11983         echo "$parent" | grep -F "$FID2/link" ||
11984                 error "$FID2/link not returned in parent list (by fid)"
11985
11986         # 4) test for entry in root directory
11987         parent=$($LFS path2fid --parents $DIR/f)
11988         echo "$parent" | grep -F "$FID3/f" ||
11989                 error "$FID3/f not returned in parent list"
11990
11991         # 5) test it on root directory
11992         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
11993                 error "$MOUNT should not have parents"
11994
11995         # enable xattr caching and check that linkea is correctly updated
11996         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11997         save_lustre_params client "llite.*.xattr_cache" > $save
11998         lctl set_param llite.*.xattr_cache 1
11999
12000         # 6.1) linkea update on rename
12001         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12002
12003         # get parents by fid
12004         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12005         # foo1 should no longer be returned in parent list
12006         echo "$parent" | grep -F "$FID1" &&
12007                 error "$FID1 should no longer be in parent list"
12008         # the new path should appear
12009         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12010                 error "$FID2/$tfile.moved is not in parent list"
12011
12012         # 6.2) linkea update on unlink
12013         rm -f $DIR/$tdir/d/foo2/link
12014         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12015         # foo2/link should no longer be returned in parent list
12016         echo "$parent" | grep -F "$FID2/link" &&
12017                 error "$FID2/link should no longer be in parent list"
12018         true
12019
12020         rm -f $DIR/f
12021         restore_lustre_params < $save
12022         rm -f $save
12023 }
12024 run_test 154f "get parent fids by reading link ea"
12025
12026 test_154g()
12027 {
12028         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12029         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12030            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12031                 skip "Need MDS version at least 2.6.92"
12032
12033         mkdir -p $DIR/$tdir
12034         llapi_fid_test -d $DIR/$tdir
12035 }
12036 run_test 154g "various llapi FID tests"
12037
12038 test_155_small_load() {
12039     local temp=$TMP/$tfile
12040     local file=$DIR/$tfile
12041
12042     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12043         error "dd of=$temp bs=6096 count=1 failed"
12044     cp $temp $file
12045     cancel_lru_locks $OSC
12046     cmp $temp $file || error "$temp $file differ"
12047
12048     $TRUNCATE $temp 6000
12049     $TRUNCATE $file 6000
12050     cmp $temp $file || error "$temp $file differ (truncate1)"
12051
12052     echo "12345" >>$temp
12053     echo "12345" >>$file
12054     cmp $temp $file || error "$temp $file differ (append1)"
12055
12056     echo "12345" >>$temp
12057     echo "12345" >>$file
12058     cmp $temp $file || error "$temp $file differ (append2)"
12059
12060     rm -f $temp $file
12061     true
12062 }
12063
12064 test_155_big_load() {
12065         remote_ost_nodsh && skip "remote OST with nodsh"
12066
12067         local temp=$TMP/$tfile
12068         local file=$DIR/$tfile
12069
12070         free_min_max
12071         local cache_size=$(do_facet ost$((MAXI+1)) \
12072                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12073         local large_file_size=$((cache_size * 2))
12074
12075         echo "OSS cache size: $cache_size KB"
12076         echo "Large file size: $large_file_size KB"
12077
12078         [ $MAXV -le $large_file_size ] &&
12079                 skip_env "max available OST size needs > $large_file_size KB"
12080
12081         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12082
12083         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12084                 error "dd of=$temp bs=$large_file_size count=1k failed"
12085         cp $temp $file
12086         ls -lh $temp $file
12087         cancel_lru_locks osc
12088         cmp $temp $file || error "$temp $file differ"
12089
12090         rm -f $temp $file
12091         true
12092 }
12093
12094 save_writethrough() {
12095         local facets=$(get_facets OST)
12096
12097         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12098 }
12099
12100 test_155a() {
12101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12102
12103         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12104
12105         save_writethrough $p
12106
12107         set_cache read on
12108         set_cache writethrough on
12109         test_155_small_load
12110         restore_lustre_params < $p
12111         rm -f $p
12112 }
12113 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12114
12115 test_155b() {
12116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12117
12118         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12119
12120         save_writethrough $p
12121
12122         set_cache read on
12123         set_cache writethrough off
12124         test_155_small_load
12125         restore_lustre_params < $p
12126         rm -f $p
12127 }
12128 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12129
12130 test_155c() {
12131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12132
12133         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12134
12135         save_writethrough $p
12136
12137         set_cache read off
12138         set_cache writethrough on
12139         test_155_small_load
12140         restore_lustre_params < $p
12141         rm -f $p
12142 }
12143 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12144
12145 test_155d() {
12146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12147
12148         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12149
12150         save_writethrough $p
12151
12152         set_cache read off
12153         set_cache writethrough off
12154         test_155_small_load
12155         restore_lustre_params < $p
12156         rm -f $p
12157 }
12158 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12159
12160 test_155e() {
12161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12162
12163         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12164
12165         save_writethrough $p
12166
12167         set_cache read on
12168         set_cache writethrough on
12169         test_155_big_load
12170         restore_lustre_params < $p
12171         rm -f $p
12172 }
12173 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12174
12175 test_155f() {
12176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12177
12178         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12179
12180         save_writethrough $p
12181
12182         set_cache read on
12183         set_cache writethrough off
12184         test_155_big_load
12185         restore_lustre_params < $p
12186         rm -f $p
12187 }
12188 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12189
12190 test_155g() {
12191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12192
12193         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12194
12195         save_writethrough $p
12196
12197         set_cache read off
12198         set_cache writethrough on
12199         test_155_big_load
12200         restore_lustre_params < $p
12201         rm -f $p
12202 }
12203 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12204
12205 test_155h() {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207
12208         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12209
12210         save_writethrough $p
12211
12212         set_cache read off
12213         set_cache writethrough off
12214         test_155_big_load
12215         restore_lustre_params < $p
12216         rm -f $p
12217 }
12218 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12219
12220 test_156() {
12221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12222         remote_ost_nodsh && skip "remote OST with nodsh"
12223         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12224                 skip "stats not implemented on old servers"
12225         [ "$ost1_FSTYPE" = "zfs" ] &&
12226                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12227
12228         local CPAGES=3
12229         local BEFORE
12230         local AFTER
12231         local file="$DIR/$tfile"
12232         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12233
12234         save_writethrough $p
12235         roc_hit_init
12236
12237         log "Turn on read and write cache"
12238         set_cache read on
12239         set_cache writethrough on
12240
12241         log "Write data and read it back."
12242         log "Read should be satisfied from the cache."
12243         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12244         BEFORE=$(roc_hit)
12245         cancel_lru_locks osc
12246         cat $file >/dev/null
12247         AFTER=$(roc_hit)
12248         if ! let "AFTER - BEFORE == CPAGES"; then
12249                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12250         else
12251                 log "cache hits:: before: $BEFORE, after: $AFTER"
12252         fi
12253
12254         log "Read again; it should be satisfied from the cache."
12255         BEFORE=$AFTER
12256         cancel_lru_locks osc
12257         cat $file >/dev/null
12258         AFTER=$(roc_hit)
12259         if ! let "AFTER - BEFORE == CPAGES"; then
12260                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12261         else
12262                 log "cache hits:: before: $BEFORE, after: $AFTER"
12263         fi
12264
12265         log "Turn off the read cache and turn on the write cache"
12266         set_cache read off
12267         set_cache writethrough on
12268
12269         log "Read again; it should be satisfied from the cache."
12270         BEFORE=$(roc_hit)
12271         cancel_lru_locks osc
12272         cat $file >/dev/null
12273         AFTER=$(roc_hit)
12274         if ! let "AFTER - BEFORE == CPAGES"; then
12275                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12276         else
12277                 log "cache hits:: before: $BEFORE, after: $AFTER"
12278         fi
12279
12280         log "Read again; it should not be satisfied from the cache."
12281         BEFORE=$AFTER
12282         cancel_lru_locks osc
12283         cat $file >/dev/null
12284         AFTER=$(roc_hit)
12285         if ! let "AFTER - BEFORE == 0"; then
12286                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12287         else
12288                 log "cache hits:: before: $BEFORE, after: $AFTER"
12289         fi
12290
12291         log "Write data and read it back."
12292         log "Read should be satisfied from the cache."
12293         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12294         BEFORE=$(roc_hit)
12295         cancel_lru_locks osc
12296         cat $file >/dev/null
12297         AFTER=$(roc_hit)
12298         if ! let "AFTER - BEFORE == CPAGES"; then
12299                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12300         else
12301                 log "cache hits:: before: $BEFORE, after: $AFTER"
12302         fi
12303
12304         log "Read again; it should not be satisfied from the cache."
12305         BEFORE=$AFTER
12306         cancel_lru_locks osc
12307         cat $file >/dev/null
12308         AFTER=$(roc_hit)
12309         if ! let "AFTER - BEFORE == 0"; then
12310                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12311         else
12312                 log "cache hits:: before: $BEFORE, after: $AFTER"
12313         fi
12314
12315         log "Turn off read and write cache"
12316         set_cache read off
12317         set_cache writethrough off
12318
12319         log "Write data and read it back"
12320         log "It should not be satisfied from the cache."
12321         rm -f $file
12322         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12323         cancel_lru_locks osc
12324         BEFORE=$(roc_hit)
12325         cat $file >/dev/null
12326         AFTER=$(roc_hit)
12327         if ! let "AFTER - BEFORE == 0"; then
12328                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12329         else
12330                 log "cache hits:: before: $BEFORE, after: $AFTER"
12331         fi
12332
12333         log "Turn on the read cache and turn off the write cache"
12334         set_cache read on
12335         set_cache writethrough off
12336
12337         log "Write data and read it back"
12338         log "It should not be satisfied from the cache."
12339         rm -f $file
12340         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12341         BEFORE=$(roc_hit)
12342         cancel_lru_locks osc
12343         cat $file >/dev/null
12344         AFTER=$(roc_hit)
12345         if ! let "AFTER - BEFORE == 0"; then
12346                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12347         else
12348                 log "cache hits:: before: $BEFORE, after: $AFTER"
12349         fi
12350
12351         log "Read again; it should be satisfied from the cache."
12352         BEFORE=$(roc_hit)
12353         cancel_lru_locks osc
12354         cat $file >/dev/null
12355         AFTER=$(roc_hit)
12356         if ! let "AFTER - BEFORE == CPAGES"; then
12357                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12358         else
12359                 log "cache hits:: before: $BEFORE, after: $AFTER"
12360         fi
12361
12362         restore_lustre_params < $p
12363         rm -f $p $file
12364 }
12365 run_test 156 "Verification of tunables"
12366
12367 test_160a() {
12368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12369         remote_mds_nodsh && skip "remote MDS with nodsh"
12370         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12371                 skip "Need MDS version at least 2.2.0"
12372
12373         changelog_register || error "changelog_register failed"
12374         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12375         changelog_users $SINGLEMDS | grep -q $cl_user ||
12376                 error "User $cl_user not found in changelog_users"
12377
12378         # change something
12379         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12380         changelog_clear 0 || error "changelog_clear failed"
12381         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12382         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12383         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12384         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12385         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12386         rm $DIR/$tdir/pics/desktop.jpg
12387
12388         changelog_dump | tail -10
12389
12390         echo "verifying changelog mask"
12391         changelog_chmask "-MKDIR"
12392         changelog_chmask "-CLOSE"
12393
12394         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12395         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12396
12397         changelog_chmask "+MKDIR"
12398         changelog_chmask "+CLOSE"
12399
12400         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12401         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12402
12403         changelog_dump | tail -10
12404         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12405         CLOSES=$(changelog_dump | grep -c "CLOSE")
12406         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12407         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12408
12409         # verify contents
12410         echo "verifying target fid"
12411         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12412         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12413         [ "$fidc" == "$fidf" ] ||
12414                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12415         echo "verifying parent fid"
12416         # The FID returned from the Changelog may be the directory shard on
12417         # a different MDT, and not the FID returned by path2fid on the parent.
12418         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12419         # since this is what will matter when recreating this file in the tree.
12420         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12421         local pathp=$($LFS fid2path $MOUNT "$fidp")
12422         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12423                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12424
12425         echo "getting records for $cl_user"
12426         changelog_users $SINGLEMDS
12427         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12428         local nclr=3
12429         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12430                 error "changelog_clear failed"
12431         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12432         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12433         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12434                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12435
12436         local min0_rec=$(changelog_users $SINGLEMDS |
12437                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12438         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12439                           awk '{ print $1; exit; }')
12440
12441         changelog_dump | tail -n 5
12442         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12443         [ $first_rec == $((min0_rec + 1)) ] ||
12444                 error "first index should be $min0_rec + 1 not $first_rec"
12445
12446         # LU-3446 changelog index reset on MDT restart
12447         local cur_rec1=$(changelog_users $SINGLEMDS |
12448                          awk '/^current.index:/ { print $NF }')
12449         changelog_clear 0 ||
12450                 error "clear all changelog records for $cl_user failed"
12451         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12452         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12453                 error "Fail to start $SINGLEMDS"
12454         local cur_rec2=$(changelog_users $SINGLEMDS |
12455                          awk '/^current.index:/ { print $NF }')
12456         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12457         [ $cur_rec1 == $cur_rec2 ] ||
12458                 error "current index should be $cur_rec1 not $cur_rec2"
12459
12460         echo "verifying users from this test are deregistered"
12461         changelog_deregister || error "changelog_deregister failed"
12462         changelog_users $SINGLEMDS | grep -q $cl_user &&
12463                 error "User '$cl_user' still in changelog_users"
12464
12465         # lctl get_param -n mdd.*.changelog_users
12466         # current index: 144
12467         # ID    index (idle seconds)
12468         # cl3   144 (2)
12469         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12470                 # this is the normal case where all users were deregistered
12471                 # make sure no new records are added when no users are present
12472                 local last_rec1=$(changelog_users $SINGLEMDS |
12473                                   awk '/^current.index:/ { print $NF }')
12474                 touch $DIR/$tdir/chloe
12475                 local last_rec2=$(changelog_users $SINGLEMDS |
12476                                   awk '/^current.index:/ { print $NF }')
12477                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12478                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12479         else
12480                 # any changelog users must be leftovers from a previous test
12481                 changelog_users $SINGLEMDS
12482                 echo "other changelog users; can't verify off"
12483         fi
12484 }
12485 run_test 160a "changelog sanity"
12486
12487 test_160b() { # LU-3587
12488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12489         remote_mds_nodsh && skip "remote MDS with nodsh"
12490         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12491                 skip "Need MDS version at least 2.2.0"
12492
12493         changelog_register || error "changelog_register failed"
12494         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12495         changelog_users $SINGLEMDS | grep -q $cl_user ||
12496                 error "User '$cl_user' not found in changelog_users"
12497
12498         local longname1=$(str_repeat a 255)
12499         local longname2=$(str_repeat b 255)
12500
12501         cd $DIR
12502         echo "creating very long named file"
12503         touch $longname1 || error "create of '$longname1' failed"
12504         echo "renaming very long named file"
12505         mv $longname1 $longname2
12506
12507         changelog_dump | grep RENME | tail -n 5
12508         rm -f $longname2
12509 }
12510 run_test 160b "Verify that very long rename doesn't crash in changelog"
12511
12512 test_160c() {
12513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12514         remote_mds_nodsh && skip "remote MDS with nodsh"
12515
12516         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12517                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12518                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12519                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12520
12521         local rc=0
12522
12523         # Registration step
12524         changelog_register || error "changelog_register failed"
12525
12526         rm -rf $DIR/$tdir
12527         mkdir -p $DIR/$tdir
12528         $MCREATE $DIR/$tdir/foo_160c
12529         changelog_chmask "-TRUNC"
12530         $TRUNCATE $DIR/$tdir/foo_160c 200
12531         changelog_chmask "+TRUNC"
12532         $TRUNCATE $DIR/$tdir/foo_160c 199
12533         changelog_dump | tail -n 5
12534         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12535         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12536 }
12537 run_test 160c "verify that changelog log catch the truncate event"
12538
12539 test_160d() {
12540         remote_mds_nodsh && skip "remote MDS with nodsh"
12541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12543         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12544                 skip "Need MDS version at least 2.7.60"
12545
12546         # Registration step
12547         changelog_register || error "changelog_register failed"
12548
12549         mkdir -p $DIR/$tdir/migrate_dir
12550         changelog_clear 0 || error "changelog_clear failed"
12551
12552         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12553         changelog_dump | tail -n 5
12554         local migrates=$(changelog_dump | grep -c "MIGRT")
12555         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12556 }
12557 run_test 160d "verify that changelog log catch the migrate event"
12558
12559 test_160e() {
12560         remote_mds_nodsh && skip "remote MDS with nodsh"
12561
12562         # Create a user
12563         changelog_register || error "changelog_register failed"
12564
12565         # Delete a future user (expect fail)
12566         local MDT0=$(facet_svc $SINGLEMDS)
12567         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12568         local rc=$?
12569
12570         if [ $rc -eq 0 ]; then
12571                 error "Deleted non-existant user cl77"
12572         elif [ $rc -ne 2 ]; then
12573                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12574         fi
12575
12576         # Clear to a bad index (1 billion should be safe)
12577         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12578         rc=$?
12579
12580         if [ $rc -eq 0 ]; then
12581                 error "Successfully cleared to invalid CL index"
12582         elif [ $rc -ne 22 ]; then
12583                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12584         fi
12585 }
12586 run_test 160e "changelog negative testing (should return errors)"
12587
12588 test_160f() {
12589         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12590         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12591                 skip "Need MDS version at least 2.10.56"
12592
12593         local mdts=$(comma_list $(mdts_nodes))
12594
12595         # Create a user
12596         changelog_register || error "first changelog_register failed"
12597         changelog_register || error "second changelog_register failed"
12598         local cl_users
12599         declare -A cl_user1
12600         declare -A cl_user2
12601         local user_rec1
12602         local user_rec2
12603         local i
12604
12605         # generate some changelog records to accumulate on each MDT
12606         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12607         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12608                 error "create $DIR/$tdir/$tfile failed"
12609
12610         # check changelogs have been generated
12611         local nbcl=$(changelog_dump | wc -l)
12612         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12613
12614         for param in "changelog_max_idle_time=10" \
12615                      "changelog_gc=1" \
12616                      "changelog_min_gc_interval=2" \
12617                      "changelog_min_free_cat_entries=3"; do
12618                 local MDT0=$(facet_svc $SINGLEMDS)
12619                 local var="${param%=*}"
12620                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12621
12622                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12623                 do_nodes $mdts $LCTL set_param mdd.*.$param
12624         done
12625
12626         # force cl_user2 to be idle (1st part)
12627         sleep 9
12628
12629         # simulate changelog catalog almost full
12630         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12631         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12632
12633         for i in $(seq $MDSCOUNT); do
12634                 cl_users=(${CL_USERS[mds$i]})
12635                 cl_user1[mds$i]="${cl_users[0]}"
12636                 cl_user2[mds$i]="${cl_users[1]}"
12637
12638                 [ -n "${cl_user1[mds$i]}" ] ||
12639                         error "mds$i: no user registered"
12640                 [ -n "${cl_user2[mds$i]}" ] ||
12641                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12642
12643                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12644                 [ -n "$user_rec1" ] ||
12645                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12646                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12647                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12648                 [ -n "$user_rec2" ] ||
12649                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12650                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12651                      "$user_rec1 + 2 == $user_rec2"
12652                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12653                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12654                               "$user_rec1 + 2, but is $user_rec2"
12655                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12656                 [ -n "$user_rec2" ] ||
12657                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12658                 [ $user_rec1 == $user_rec2 ] ||
12659                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12660                               "$user_rec1, but is $user_rec2"
12661         done
12662
12663         # force cl_user2 to be idle (2nd part) and to reach
12664         # changelog_max_idle_time
12665         sleep 2
12666
12667         # generate one more changelog to trigger fail_loc
12668         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12669                 error "create $DIR/$tdir/${tfile}bis failed"
12670
12671         # ensure gc thread is done
12672         for i in $(mdts_nodes); do
12673                 wait_update $i \
12674                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12675                         error "$i: GC-thread not done"
12676         done
12677
12678         local first_rec
12679         for i in $(seq $MDSCOUNT); do
12680                 # check cl_user1 still registered
12681                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12682                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12683                 # check cl_user2 unregistered
12684                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12685                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12686
12687                 # check changelogs are present and starting at $user_rec1 + 1
12688                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12689                 [ -n "$user_rec1" ] ||
12690                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12691                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12692                             awk '{ print $1; exit; }')
12693
12694                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12695                 [ $((user_rec1 + 1)) == $first_rec ] ||
12696                         error "mds$i: first index should be $user_rec1 + 1, " \
12697                               "but is $first_rec"
12698         done
12699 }
12700 run_test 160f "changelog garbage collect (timestamped users)"
12701
12702 test_160g() {
12703         remote_mds_nodsh && skip "remote MDS with nodsh"
12704         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12705                 skip "Need MDS version at least 2.10.56"
12706
12707         local mdts=$(comma_list $(mdts_nodes))
12708
12709         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12710         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12711
12712         # Create a user
12713         changelog_register || error "first changelog_register failed"
12714         changelog_register || error "second changelog_register failed"
12715         local cl_users
12716         declare -A cl_user1
12717         declare -A cl_user2
12718         local user_rec1
12719         local user_rec2
12720         local i
12721
12722         # generate some changelog records to accumulate on each MDT
12723         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12724         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12725                 error "create $DIR/$tdir/$tfile failed"
12726
12727         # check changelogs have been generated
12728         local nbcl=$(changelog_dump | wc -l)
12729         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12730
12731         # reduce the max_idle_indexes value to make sure we exceed it
12732         max_ndx=$((nbcl / 2 - 1))
12733
12734         for param in "changelog_max_idle_indexes=$max_ndx" \
12735                      "changelog_gc=1" \
12736                      "changelog_min_gc_interval=2" \
12737                      "changelog_min_free_cat_entries=3"; do
12738                 local MDT0=$(facet_svc $SINGLEMDS)
12739                 local var="${param%=*}"
12740                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12741
12742                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12743                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12744                         error "unable to set mdd.*.$param"
12745         done
12746
12747         # simulate changelog catalog almost full
12748         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12749         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12750
12751         for i in $(seq $MDSCOUNT); do
12752                 cl_users=(${CL_USERS[mds$i]})
12753                 cl_user1[mds$i]="${cl_users[0]}"
12754                 cl_user2[mds$i]="${cl_users[1]}"
12755
12756                 [ -n "${cl_user1[mds$i]}" ] ||
12757                         error "mds$i: no user registered"
12758                 [ -n "${cl_user2[mds$i]}" ] ||
12759                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12760
12761                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12762                 [ -n "$user_rec1" ] ||
12763                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12764                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12765                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12766                 [ -n "$user_rec2" ] ||
12767                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12768                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12769                      "$user_rec1 + 2 == $user_rec2"
12770                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12771                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12772                               "$user_rec1 + 2, but is $user_rec2"
12773                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12774                 [ -n "$user_rec2" ] ||
12775                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12776                 [ $user_rec1 == $user_rec2 ] ||
12777                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12778                               "$user_rec1, but is $user_rec2"
12779         done
12780
12781         # ensure we are past the previous changelog_min_gc_interval set above
12782         sleep 2
12783
12784         # generate one more changelog to trigger fail_loc
12785         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12786                 error "create $DIR/$tdir/${tfile}bis failed"
12787
12788         # ensure gc thread is done
12789         for i in $(mdts_nodes); do
12790                 wait_update $i \
12791                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12792                         error "$i: GC-thread not done"
12793         done
12794
12795         local first_rec
12796         for i in $(seq $MDSCOUNT); do
12797                 # check cl_user1 still registered
12798                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12799                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12800                 # check cl_user2 unregistered
12801                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12802                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12803
12804                 # check changelogs are present and starting at $user_rec1 + 1
12805                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12806                 [ -n "$user_rec1" ] ||
12807                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12808                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12809                             awk '{ print $1; exit; }')
12810
12811                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12812                 [ $((user_rec1 + 1)) == $first_rec ] ||
12813                         error "mds$i: first index should be $user_rec1 + 1, " \
12814                               "but is $first_rec"
12815         done
12816 }
12817 run_test 160g "changelog garbage collect (old users)"
12818
12819 test_160h() {
12820         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12821         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12822                 skip "Need MDS version at least 2.10.56"
12823
12824         local mdts=$(comma_list $(mdts_nodes))
12825
12826         # Create a user
12827         changelog_register || error "first changelog_register failed"
12828         changelog_register || error "second changelog_register failed"
12829         local cl_users
12830         declare -A cl_user1
12831         declare -A cl_user2
12832         local user_rec1
12833         local user_rec2
12834         local i
12835
12836         # generate some changelog records to accumulate on each MDT
12837         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12838         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12839                 error "create $DIR/$tdir/$tfile failed"
12840
12841         # check changelogs have been generated
12842         local nbcl=$(changelog_dump | wc -l)
12843         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12844
12845         for param in "changelog_max_idle_time=10" \
12846                      "changelog_gc=1" \
12847                      "changelog_min_gc_interval=2"; do
12848                 local MDT0=$(facet_svc $SINGLEMDS)
12849                 local var="${param%=*}"
12850                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12851
12852                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12853                 do_nodes $mdts $LCTL set_param mdd.*.$param
12854         done
12855
12856         # force cl_user2 to be idle (1st part)
12857         sleep 9
12858
12859         for i in $(seq $MDSCOUNT); do
12860                 cl_users=(${CL_USERS[mds$i]})
12861                 cl_user1[mds$i]="${cl_users[0]}"
12862                 cl_user2[mds$i]="${cl_users[1]}"
12863
12864                 [ -n "${cl_user1[mds$i]}" ] ||
12865                         error "mds$i: no user registered"
12866                 [ -n "${cl_user2[mds$i]}" ] ||
12867                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12868
12869                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12870                 [ -n "$user_rec1" ] ||
12871                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12872                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12873                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12874                 [ -n "$user_rec2" ] ||
12875                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12876                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12877                      "$user_rec1 + 2 == $user_rec2"
12878                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12879                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12880                               "$user_rec1 + 2, but is $user_rec2"
12881                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12882                 [ -n "$user_rec2" ] ||
12883                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12884                 [ $user_rec1 == $user_rec2 ] ||
12885                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12886                               "$user_rec1, but is $user_rec2"
12887         done
12888
12889         # force cl_user2 to be idle (2nd part) and to reach
12890         # changelog_max_idle_time
12891         sleep 2
12892
12893         # force each GC-thread start and block then
12894         # one per MDT/MDD, set fail_val accordingly
12895         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12896         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12897
12898         # generate more changelogs to trigger fail_loc
12899         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12900                 error "create $DIR/$tdir/${tfile}bis failed"
12901
12902         # stop MDT to stop GC-thread, should be done in back-ground as it will
12903         # block waiting for the thread to be released and exit
12904         declare -A stop_pids
12905         for i in $(seq $MDSCOUNT); do
12906                 stop mds$i &
12907                 stop_pids[mds$i]=$!
12908         done
12909
12910         for i in $(mdts_nodes); do
12911                 local facet
12912                 local nb=0
12913                 local facets=$(facets_up_on_host $i)
12914
12915                 for facet in ${facets//,/ }; do
12916                         if [[ $facet == mds* ]]; then
12917                                 nb=$((nb + 1))
12918                         fi
12919                 done
12920                 # ensure each MDS's gc threads are still present and all in "R"
12921                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12922                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12923                         error "$i: expected $nb GC-thread"
12924                 wait_update $i \
12925                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12926                         "R" 20 ||
12927                         error "$i: GC-thread not found in R-state"
12928                 # check umounts of each MDT on MDS have reached kthread_stop()
12929                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12930                         error "$i: expected $nb umount"
12931                 wait_update $i \
12932                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12933                         error "$i: umount not found in D-state"
12934         done
12935
12936         # release all GC-threads
12937         do_nodes $mdts $LCTL set_param fail_loc=0
12938
12939         # wait for MDT stop to complete
12940         for i in $(seq $MDSCOUNT); do
12941                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12942         done
12943
12944         # XXX
12945         # may try to check if any orphan changelog records are present
12946         # via ldiskfs/zfs and llog_reader...
12947
12948         # re-start/mount MDTs
12949         for i in $(seq $MDSCOUNT); do
12950                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12951                         error "Fail to start mds$i"
12952         done
12953
12954         local first_rec
12955         for i in $(seq $MDSCOUNT); do
12956                 # check cl_user1 still registered
12957                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12958                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12959                 # check cl_user2 unregistered
12960                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12961                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12962
12963                 # check changelogs are present and starting at $user_rec1 + 1
12964                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12965                 [ -n "$user_rec1" ] ||
12966                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12967                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12968                             awk '{ print $1; exit; }')
12969
12970                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12971                 [ $((user_rec1 + 1)) == $first_rec ] ||
12972                         error "mds$i: first index should be $user_rec1 + 1, " \
12973                               "but is $first_rec"
12974         done
12975 }
12976 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
12977               "during mount"
12978
12979 test_160i() {
12980
12981         local mdts=$(comma_list $(mdts_nodes))
12982
12983         changelog_register || error "first changelog_register failed"
12984
12985         # generate some changelog records to accumulate on each MDT
12986         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12987         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12988                 error "create $DIR/$tdir/$tfile failed"
12989
12990         # check changelogs have been generated
12991         local nbcl=$(changelog_dump | wc -l)
12992         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12993
12994         # simulate race between register and unregister
12995         # XXX as fail_loc is set per-MDS, with DNE configs the race
12996         # simulation will only occur for one MDT per MDS and for the
12997         # others the normal race scenario will take place
12998         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
12999         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13000         do_nodes $mdts $LCTL set_param fail_val=1
13001
13002         # unregister 1st user
13003         changelog_deregister &
13004         local pid1=$!
13005         # wait some time for deregister work to reach race rdv
13006         sleep 2
13007         # register 2nd user
13008         changelog_register || error "2nd user register failed"
13009
13010         wait $pid1 || error "1st user deregister failed"
13011
13012         local i
13013         local last_rec
13014         declare -A LAST_REC
13015         for i in $(seq $MDSCOUNT); do
13016                 if changelog_users mds$i | grep "^cl"; then
13017                         # make sure new records are added with one user present
13018                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13019                                           awk '/^current.index:/ { print $NF }')
13020                 else
13021                         error "mds$i has no user registered"
13022                 fi
13023         done
13024
13025         # generate more changelog records to accumulate on each MDT
13026         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13027                 error "create $DIR/$tdir/${tfile}bis failed"
13028
13029         for i in $(seq $MDSCOUNT); do
13030                 last_rec=$(changelog_users $SINGLEMDS |
13031                            awk '/^current.index:/ { print $NF }')
13032                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13033                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13034                         error "changelogs are off on mds$i"
13035         done
13036 }
13037 run_test 160i "changelog user register/unregister race"
13038
13039 test_161a() {
13040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13041
13042         test_mkdir -c1 $DIR/$tdir
13043         cp /etc/hosts $DIR/$tdir/$tfile
13044         test_mkdir -c1 $DIR/$tdir/foo1
13045         test_mkdir -c1 $DIR/$tdir/foo2
13046         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13047         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13048         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13049         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13050         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13051         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13052                 $LFS fid2path $DIR $FID
13053                 error "bad link ea"
13054         fi
13055         # middle
13056         rm $DIR/$tdir/foo2/zachary
13057         # last
13058         rm $DIR/$tdir/foo2/thor
13059         # first
13060         rm $DIR/$tdir/$tfile
13061         # rename
13062         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13063         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13064                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13065         rm $DIR/$tdir/foo2/maggie
13066
13067         # overflow the EA
13068         local longname=$tfile.avg_len_is_thirty_two_
13069         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13070                 error_noexit 'failed to unlink many hardlinks'" EXIT
13071         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13072                 error "failed to hardlink many files"
13073         links=$($LFS fid2path $DIR $FID | wc -l)
13074         echo -n "${links}/1000 links in link EA"
13075         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13076 }
13077 run_test 161a "link ea sanity"
13078
13079 test_161b() {
13080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13081         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13082
13083         local MDTIDX=1
13084         local remote_dir=$DIR/$tdir/remote_dir
13085
13086         mkdir -p $DIR/$tdir
13087         $LFS mkdir -i $MDTIDX $remote_dir ||
13088                 error "create remote directory failed"
13089
13090         cp /etc/hosts $remote_dir/$tfile
13091         mkdir -p $remote_dir/foo1
13092         mkdir -p $remote_dir/foo2
13093         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13094         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13095         ln $remote_dir/$tfile $remote_dir/foo1/luna
13096         ln $remote_dir/$tfile $remote_dir/foo2/thor
13097
13098         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13099                      tr -d ']')
13100         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13101                 $LFS fid2path $DIR $FID
13102                 error "bad link ea"
13103         fi
13104         # middle
13105         rm $remote_dir/foo2/zachary
13106         # last
13107         rm $remote_dir/foo2/thor
13108         # first
13109         rm $remote_dir/$tfile
13110         # rename
13111         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13112         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13113         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13114                 $LFS fid2path $DIR $FID
13115                 error "bad link rename"
13116         fi
13117         rm $remote_dir/foo2/maggie
13118
13119         # overflow the EA
13120         local longname=filename_avg_len_is_thirty_two_
13121         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13122                 error "failed to hardlink many files"
13123         links=$($LFS fid2path $DIR $FID | wc -l)
13124         echo -n "${links}/1000 links in link EA"
13125         [[ ${links} -gt 60 ]] ||
13126                 error "expected at least 60 links in link EA"
13127         unlinkmany $remote_dir/foo2/$longname 1000 ||
13128         error "failed to unlink many hardlinks"
13129 }
13130 run_test 161b "link ea sanity under remote directory"
13131
13132 test_161c() {
13133         remote_mds_nodsh && skip "remote MDS with nodsh"
13134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13135         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13136                 skip "Need MDS version at least 2.1.5"
13137
13138         # define CLF_RENAME_LAST 0x0001
13139         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13140         changelog_register || error "changelog_register failed"
13141
13142         rm -rf $DIR/$tdir
13143         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13144         touch $DIR/$tdir/foo_161c
13145         touch $DIR/$tdir/bar_161c
13146         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13147         changelog_dump | grep RENME | tail -n 5
13148         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13149         changelog_clear 0 || error "changelog_clear failed"
13150         if [ x$flags != "x0x1" ]; then
13151                 error "flag $flags is not 0x1"
13152         fi
13153
13154         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13155         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13156         touch $DIR/$tdir/foo_161c
13157         touch $DIR/$tdir/bar_161c
13158         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13159         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13160         changelog_dump | grep RENME | tail -n 5
13161         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13162         changelog_clear 0 || error "changelog_clear failed"
13163         if [ x$flags != "x0x0" ]; then
13164                 error "flag $flags is not 0x0"
13165         fi
13166         echo "rename overwrite a target having nlink > 1," \
13167                 "changelog record has flags of $flags"
13168
13169         # rename doesn't overwrite a target (changelog flag 0x0)
13170         touch $DIR/$tdir/foo_161c
13171         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13172         changelog_dump | grep RENME | tail -n 5
13173         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13174         changelog_clear 0 || error "changelog_clear failed"
13175         if [ x$flags != "x0x0" ]; then
13176                 error "flag $flags is not 0x0"
13177         fi
13178         echo "rename doesn't overwrite a target," \
13179                 "changelog record has flags of $flags"
13180
13181         # define CLF_UNLINK_LAST 0x0001
13182         # unlink a file having nlink = 1 (changelog flag 0x1)
13183         rm -f $DIR/$tdir/foo2_161c
13184         changelog_dump | grep UNLNK | tail -n 5
13185         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13186         changelog_clear 0 || error "changelog_clear failed"
13187         if [ x$flags != "x0x1" ]; then
13188                 error "flag $flags is not 0x1"
13189         fi
13190         echo "unlink a file having nlink = 1," \
13191                 "changelog record has flags of $flags"
13192
13193         # unlink a file having nlink > 1 (changelog flag 0x0)
13194         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13195         rm -f $DIR/$tdir/foobar_161c
13196         changelog_dump | grep UNLNK | tail -n 5
13197         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13198         changelog_clear 0 || error "changelog_clear failed"
13199         if [ x$flags != "x0x0" ]; then
13200                 error "flag $flags is not 0x0"
13201         fi
13202         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13203 }
13204 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13205
13206 test_161d() {
13207         remote_mds_nodsh && skip "remote MDS with nodsh"
13208         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13209
13210         local pid
13211         local fid
13212
13213         changelog_register || error "changelog_register failed"
13214
13215         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13216         # interfer with $MOUNT/.lustre/fid/ access
13217         mkdir $DIR/$tdir
13218         [[ $? -eq 0 ]] || error "mkdir failed"
13219
13220         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13221         $LCTL set_param fail_loc=0x8000140c
13222         # 5s pause
13223         $LCTL set_param fail_val=5
13224
13225         # create file
13226         echo foofoo > $DIR/$tdir/$tfile &
13227         pid=$!
13228
13229         # wait for create to be delayed
13230         sleep 2
13231
13232         ps -p $pid
13233         [[ $? -eq 0 ]] || error "create should be blocked"
13234
13235         local tempfile=$(mktemp)
13236         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13237         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13238         # some delay may occur during ChangeLog publishing and file read just
13239         # above, that could allow file write to happen finally
13240         [[ -s $tempfile ]] && echo "file should be empty"
13241
13242         $LCTL set_param fail_loc=0
13243
13244         wait $pid
13245         [[ $? -eq 0 ]] || error "create failed"
13246 }
13247 run_test 161d "create with concurrent .lustre/fid access"
13248
13249 check_path() {
13250         local expected="$1"
13251         shift
13252         local fid="$2"
13253
13254         local path
13255         path=$($LFS fid2path "$@")
13256         local rc=$?
13257
13258         if [ $rc -ne 0 ]; then
13259                 error "path looked up of '$expected' failed: rc=$rc"
13260         elif [ "$path" != "$expected" ]; then
13261                 error "path looked up '$path' instead of '$expected'"
13262         else
13263                 echo "FID '$fid' resolves to path '$path' as expected"
13264         fi
13265 }
13266
13267 test_162a() { # was test_162
13268         test_mkdir -p -c1 $DIR/$tdir/d2
13269         touch $DIR/$tdir/d2/$tfile
13270         touch $DIR/$tdir/d2/x1
13271         touch $DIR/$tdir/d2/x2
13272         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13273         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13274         # regular file
13275         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13276         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13277
13278         # softlink
13279         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13280         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13281         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13282
13283         # softlink to wrong file
13284         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13285         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13286         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13287
13288         # hardlink
13289         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13290         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13291         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13292         # fid2path dir/fsname should both work
13293         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13294         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13295
13296         # hardlink count: check that there are 2 links
13297         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13298         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13299
13300         # hardlink indexing: remove the first link
13301         rm $DIR/$tdir/d2/p/q/r/hlink
13302         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13303 }
13304 run_test 162a "path lookup sanity"
13305
13306 test_162b() {
13307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13309
13310         mkdir $DIR/$tdir
13311         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13312                                 error "create striped dir failed"
13313
13314         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13315                                         tail -n 1 | awk '{print $2}')
13316         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13317
13318         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13319         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13320
13321         # regular file
13322         for ((i=0;i<5;i++)); do
13323                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13324                         error "get fid for f$i failed"
13325                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13326
13327                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13328                         error "get fid for d$i failed"
13329                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13330         done
13331
13332         return 0
13333 }
13334 run_test 162b "striped directory path lookup sanity"
13335
13336 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13337 test_162c() {
13338         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13339                 skip "Need MDS version at least 2.7.51"
13340
13341         local lpath=$tdir.local
13342         local rpath=$tdir.remote
13343
13344         test_mkdir $DIR/$lpath
13345         test_mkdir $DIR/$rpath
13346
13347         for ((i = 0; i <= 101; i++)); do
13348                 lpath="$lpath/$i"
13349                 mkdir $DIR/$lpath
13350                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13351                         error "get fid for local directory $DIR/$lpath failed"
13352                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13353
13354                 rpath="$rpath/$i"
13355                 test_mkdir $DIR/$rpath
13356                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13357                         error "get fid for remote directory $DIR/$rpath failed"
13358                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13359         done
13360
13361         return 0
13362 }
13363 run_test 162c "fid2path works with paths 100 or more directories deep"
13364
13365 test_169() {
13366         # do directio so as not to populate the page cache
13367         log "creating a 10 Mb file"
13368         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13369         log "starting reads"
13370         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13371         log "truncating the file"
13372         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13373         log "killing dd"
13374         kill %+ || true # reads might have finished
13375         echo "wait until dd is finished"
13376         wait
13377         log "removing the temporary file"
13378         rm -rf $DIR/$tfile || error "tmp file removal failed"
13379 }
13380 run_test 169 "parallel read and truncate should not deadlock"
13381
13382 test_170() {
13383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13384
13385         $LCTL clear     # bug 18514
13386         $LCTL debug_daemon start $TMP/${tfile}_log_good
13387         touch $DIR/$tfile
13388         $LCTL debug_daemon stop
13389         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13390                 error "sed failed to read log_good"
13391
13392         $LCTL debug_daemon start $TMP/${tfile}_log_good
13393         rm -rf $DIR/$tfile
13394         $LCTL debug_daemon stop
13395
13396         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13397                error "lctl df log_bad failed"
13398
13399         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13400         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13401
13402         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13403         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13404
13405         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13406                 error "bad_line good_line1 good_line2 are empty"
13407
13408         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13409         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13410         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13411
13412         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13413         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13414         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13415
13416         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13417                 error "bad_line_new good_line_new are empty"
13418
13419         local expected_good=$((good_line1 + good_line2*2))
13420
13421         rm -f $TMP/${tfile}*
13422         # LU-231, short malformed line may not be counted into bad lines
13423         if [ $bad_line -ne $bad_line_new ] &&
13424                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13425                 error "expected $bad_line bad lines, but got $bad_line_new"
13426                 return 1
13427         fi
13428
13429         if [ $expected_good -ne $good_line_new ]; then
13430                 error "expected $expected_good good lines, but got $good_line_new"
13431                 return 2
13432         fi
13433         true
13434 }
13435 run_test 170 "test lctl df to handle corrupted log ====================="
13436
13437 test_171() { # bug20592
13438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13439
13440         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13441         $LCTL set_param fail_loc=0x50e
13442         $LCTL set_param fail_val=3000
13443         multiop_bg_pause $DIR/$tfile O_s || true
13444         local MULTIPID=$!
13445         kill -USR1 $MULTIPID
13446         # cause log dump
13447         sleep 3
13448         wait $MULTIPID
13449         if dmesg | grep "recursive fault"; then
13450                 error "caught a recursive fault"
13451         fi
13452         $LCTL set_param fail_loc=0
13453         true
13454 }
13455 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13456
13457 # it would be good to share it with obdfilter-survey/iokit-libecho code
13458 setup_obdecho_osc () {
13459         local rc=0
13460         local ost_nid=$1
13461         local obdfilter_name=$2
13462         echo "Creating new osc for $obdfilter_name on $ost_nid"
13463         # make sure we can find loopback nid
13464         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13465
13466         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13467                            ${obdfilter_name}_osc_UUID || rc=2; }
13468         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13469                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13470         return $rc
13471 }
13472
13473 cleanup_obdecho_osc () {
13474         local obdfilter_name=$1
13475         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13476         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13477         return 0
13478 }
13479
13480 obdecho_test() {
13481         local OBD=$1
13482         local node=$2
13483         local pages=${3:-64}
13484         local rc=0
13485         local id
13486
13487         local count=10
13488         local obd_size=$(get_obd_size $node $OBD)
13489         local page_size=$(get_page_size $node)
13490         if [[ -n "$obd_size" ]]; then
13491                 local new_count=$((obd_size / (pages * page_size / 1024)))
13492                 [[ $new_count -ge $count ]] || count=$new_count
13493         fi
13494
13495         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13496         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13497                            rc=2; }
13498         if [ $rc -eq 0 ]; then
13499             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13500             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13501         fi
13502         echo "New object id is $id"
13503         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13504                            rc=4; }
13505         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13506                            "test_brw $count w v $pages $id" || rc=4; }
13507         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13508                            rc=4; }
13509         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
13510                                         "cleanup" || rc=5; }
13511         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
13512                                         "detach" || rc=6; }
13513         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13514         return $rc
13515 }
13516
13517 test_180a() {
13518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13519
13520         if ! module_loaded obdecho; then
13521                 load_module obdecho/obdecho &&
13522                         stack_trap "rmmod obdecho" EXIT ||
13523                         error "unable to load obdecho on client"
13524         fi
13525
13526         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13527         local host=$($LCTL get_param -n osc.$osc.import |
13528                      awk '/current_connection:/ { print $2 }' )
13529         local target=$($LCTL get_param -n osc.$osc.import |
13530                        awk '/target:/ { print $2 }' )
13531         target=${target%_UUID}
13532
13533         if [ -n "$target" ]; then
13534                 setup_obdecho_osc $host $target &&
13535                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13536                         { error "obdecho setup failed with $?"; return; }
13537
13538                 obdecho_test ${target}_osc client ||
13539                         error "obdecho_test failed on ${target}_osc"
13540         else
13541                 $LCTL get_param osc.$osc.import
13542                 error "there is no osc.$osc.import target"
13543         fi
13544 }
13545 run_test 180a "test obdecho on osc"
13546
13547 test_180b() {
13548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13549         remote_ost_nodsh && skip "remote OST with nodsh"
13550
13551         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13552                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13553                 error "failed to load module obdecho"
13554
13555         local target=$(do_facet ost1 $LCTL dl |
13556                        awk '/obdfilter/ { print $4; exit; }')
13557
13558         if [ -n "$target" ]; then
13559                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13560         else
13561                 do_facet ost1 $LCTL dl
13562                 error "there is no obdfilter target on ost1"
13563         fi
13564 }
13565 run_test 180b "test obdecho directly on obdfilter"
13566
13567 test_180c() { # LU-2598
13568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13569         remote_ost_nodsh && skip "remote OST with nodsh"
13570         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13571                 skip "Need MDS version at least 2.4.0"
13572
13573         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13574                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13575                 error "failed to load module obdecho"
13576
13577         local target=$(do_facet ost1 $LCTL dl |
13578                        awk '/obdfilter/ { print $4; exit; }')
13579
13580         if [ -n "$target" ]; then
13581                 local pages=16384 # 64MB bulk I/O RPC size
13582
13583                 obdecho_test "$target" ost1 "$pages" ||
13584                         error "obdecho_test with pages=$pages failed with $?"
13585         else
13586                 do_facet ost1 $LCTL dl
13587                 error "there is no obdfilter target on ost1"
13588         fi
13589 }
13590 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13591
13592 test_181() { # bug 22177
13593         test_mkdir $DIR/$tdir
13594         # create enough files to index the directory
13595         createmany -o $DIR/$tdir/foobar 4000
13596         # print attributes for debug purpose
13597         lsattr -d .
13598         # open dir
13599         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13600         MULTIPID=$!
13601         # remove the files & current working dir
13602         unlinkmany $DIR/$tdir/foobar 4000
13603         rmdir $DIR/$tdir
13604         kill -USR1 $MULTIPID
13605         wait $MULTIPID
13606         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13607         return 0
13608 }
13609 run_test 181 "Test open-unlinked dir ========================"
13610
13611 test_182() {
13612         local fcount=1000
13613         local tcount=10
13614
13615         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13616
13617         $LCTL set_param mdc.*.rpc_stats=clear
13618
13619         for (( i = 0; i < $tcount; i++ )) ; do
13620                 mkdir $DIR/$tdir/$i
13621         done
13622
13623         for (( i = 0; i < $tcount; i++ )) ; do
13624                 createmany -o $DIR/$tdir/$i/f- $fcount &
13625         done
13626         wait
13627
13628         for (( i = 0; i < $tcount; i++ )) ; do
13629                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13630         done
13631         wait
13632
13633         $LCTL get_param mdc.*.rpc_stats
13634
13635         rm -rf $DIR/$tdir
13636 }
13637 run_test 182 "Test parallel modify metadata operations ================"
13638
13639 test_183() { # LU-2275
13640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13641         remote_mds_nodsh && skip "remote MDS with nodsh"
13642         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13643                 skip "Need MDS version at least 2.3.56"
13644
13645         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13646         echo aaa > $DIR/$tdir/$tfile
13647
13648 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13649         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13650
13651         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13652         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13653
13654         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13655
13656         # Flush negative dentry cache
13657         touch $DIR/$tdir/$tfile
13658
13659         # We are not checking for any leaked references here, they'll
13660         # become evident next time we do cleanup with module unload.
13661         rm -rf $DIR/$tdir
13662 }
13663 run_test 183 "No crash or request leak in case of strange dispositions ========"
13664
13665 # test suite 184 is for LU-2016, LU-2017
13666 test_184a() {
13667         check_swap_layouts_support
13668
13669         dir0=$DIR/$tdir/$testnum
13670         test_mkdir -p -c1 $dir0
13671         ref1=/etc/passwd
13672         ref2=/etc/group
13673         file1=$dir0/f1
13674         file2=$dir0/f2
13675         $LFS setstripe -c1 $file1
13676         cp $ref1 $file1
13677         $LFS setstripe -c2 $file2
13678         cp $ref2 $file2
13679         gen1=$($LFS getstripe -g $file1)
13680         gen2=$($LFS getstripe -g $file2)
13681
13682         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13683         gen=$($LFS getstripe -g $file1)
13684         [[ $gen1 != $gen ]] ||
13685                 "Layout generation on $file1 does not change"
13686         gen=$($LFS getstripe -g $file2)
13687         [[ $gen2 != $gen ]] ||
13688                 "Layout generation on $file2 does not change"
13689
13690         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13691         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13692
13693         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13694 }
13695 run_test 184a "Basic layout swap"
13696
13697 test_184b() {
13698         check_swap_layouts_support
13699
13700         dir0=$DIR/$tdir/$testnum
13701         mkdir -p $dir0 || error "creating dir $dir0"
13702         file1=$dir0/f1
13703         file2=$dir0/f2
13704         file3=$dir0/f3
13705         dir1=$dir0/d1
13706         dir2=$dir0/d2
13707         mkdir $dir1 $dir2
13708         $LFS setstripe -c1 $file1
13709         $LFS setstripe -c2 $file2
13710         $LFS setstripe -c1 $file3
13711         chown $RUNAS_ID $file3
13712         gen1=$($LFS getstripe -g $file1)
13713         gen2=$($LFS getstripe -g $file2)
13714
13715         $LFS swap_layouts $dir1 $dir2 &&
13716                 error "swap of directories layouts should fail"
13717         $LFS swap_layouts $dir1 $file1 &&
13718                 error "swap of directory and file layouts should fail"
13719         $RUNAS $LFS swap_layouts $file1 $file2 &&
13720                 error "swap of file we cannot write should fail"
13721         $LFS swap_layouts $file1 $file3 &&
13722                 error "swap of file with different owner should fail"
13723         /bin/true # to clear error code
13724 }
13725 run_test 184b "Forbidden layout swap (will generate errors)"
13726
13727 test_184c() {
13728         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13729         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13730         check_swap_layouts_support
13731
13732         local dir0=$DIR/$tdir/$testnum
13733         mkdir -p $dir0 || error "creating dir $dir0"
13734
13735         local ref1=$dir0/ref1
13736         local ref2=$dir0/ref2
13737         local file1=$dir0/file1
13738         local file2=$dir0/file2
13739         # create a file large enough for the concurrent test
13740         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13741         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13742         echo "ref file size: ref1($(stat -c %s $ref1))," \
13743              "ref2($(stat -c %s $ref2))"
13744
13745         cp $ref2 $file2
13746         dd if=$ref1 of=$file1 bs=16k &
13747         local DD_PID=$!
13748
13749         # Make sure dd starts to copy file
13750         while [ ! -f $file1 ]; do sleep 0.1; done
13751
13752         $LFS swap_layouts $file1 $file2
13753         local rc=$?
13754         wait $DD_PID
13755         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13756         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13757
13758         # how many bytes copied before swapping layout
13759         local copied=$(stat -c %s $file2)
13760         local remaining=$(stat -c %s $ref1)
13761         remaining=$((remaining - copied))
13762         echo "Copied $copied bytes before swapping layout..."
13763
13764         cmp -n $copied $file1 $ref2 | grep differ &&
13765                 error "Content mismatch [0, $copied) of ref2 and file1"
13766         cmp -n $copied $file2 $ref1 ||
13767                 error "Content mismatch [0, $copied) of ref1 and file2"
13768         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13769                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13770
13771         # clean up
13772         rm -f $ref1 $ref2 $file1 $file2
13773 }
13774 run_test 184c "Concurrent write and layout swap"
13775
13776 test_184d() {
13777         check_swap_layouts_support
13778         [ -z "$(which getfattr 2>/dev/null)" ] &&
13779                 skip_env "no getfattr command"
13780
13781         local file1=$DIR/$tdir/$tfile-1
13782         local file2=$DIR/$tdir/$tfile-2
13783         local file3=$DIR/$tdir/$tfile-3
13784         local lovea1
13785         local lovea2
13786
13787         mkdir -p $DIR/$tdir
13788         touch $file1 || error "create $file1 failed"
13789         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13790                 error "create $file2 failed"
13791         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13792                 error "create $file3 failed"
13793         lovea1=$(get_layout_param $file1)
13794
13795         $LFS swap_layouts $file2 $file3 ||
13796                 error "swap $file2 $file3 layouts failed"
13797         $LFS swap_layouts $file1 $file2 ||
13798                 error "swap $file1 $file2 layouts failed"
13799
13800         lovea2=$(get_layout_param $file2)
13801         echo "$lovea1"
13802         echo "$lovea2"
13803         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13804
13805         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13806         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13807 }
13808 run_test 184d "allow stripeless layouts swap"
13809
13810 test_184e() {
13811         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13812                 skip "Need MDS version at least 2.6.94"
13813         check_swap_layouts_support
13814         [ -z "$(which getfattr 2>/dev/null)" ] &&
13815                 skip_env "no getfattr command"
13816
13817         local file1=$DIR/$tdir/$tfile-1
13818         local file2=$DIR/$tdir/$tfile-2
13819         local file3=$DIR/$tdir/$tfile-3
13820         local lovea
13821
13822         mkdir -p $DIR/$tdir
13823         touch $file1 || error "create $file1 failed"
13824         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13825                 error "create $file2 failed"
13826         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13827                 error "create $file3 failed"
13828
13829         $LFS swap_layouts $file1 $file2 ||
13830                 error "swap $file1 $file2 layouts failed"
13831
13832         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13833         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13834
13835         echo 123 > $file1 || error "Should be able to write into $file1"
13836
13837         $LFS swap_layouts $file1 $file3 ||
13838                 error "swap $file1 $file3 layouts failed"
13839
13840         echo 123 > $file1 || error "Should be able to write into $file1"
13841
13842         rm -rf $file1 $file2 $file3
13843 }
13844 run_test 184e "Recreate layout after stripeless layout swaps"
13845
13846 test_184f() {
13847         # Create a file with name longer than sizeof(struct stat) ==
13848         # 144 to see if we can get chars from the file name to appear
13849         # in the returned striping. Note that 'f' == 0x66.
13850         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13851
13852         mkdir -p $DIR/$tdir
13853         mcreate $DIR/$tdir/$file
13854         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13855                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13856         fi
13857 }
13858 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13859
13860 test_185() { # LU-2441
13861         # LU-3553 - no volatile file support in old servers
13862         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13863                 skip "Need MDS version at least 2.3.60"
13864
13865         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13866         touch $DIR/$tdir/spoo
13867         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13868         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13869                 error "cannot create/write a volatile file"
13870         [ "$FILESET" == "" ] &&
13871         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13872                 error "FID is still valid after close"
13873
13874         multiop_bg_pause $DIR/$tdir vVw4096_c
13875         local multi_pid=$!
13876
13877         local OLD_IFS=$IFS
13878         IFS=":"
13879         local fidv=($fid)
13880         IFS=$OLD_IFS
13881         # assume that the next FID for this client is sequential, since stdout
13882         # is unfortunately eaten by multiop_bg_pause
13883         local n=$((${fidv[1]} + 1))
13884         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13885         if [ "$FILESET" == "" ]; then
13886                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13887                         error "FID is missing before close"
13888         fi
13889         kill -USR1 $multi_pid
13890         # 1 second delay, so if mtime change we will see it
13891         sleep 1
13892         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13893         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13894 }
13895 run_test 185 "Volatile file support"
13896
13897 test_187a() {
13898         remote_mds_nodsh && skip "remote MDS with nodsh"
13899         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13900                 skip "Need MDS version at least 2.3.0"
13901
13902         local dir0=$DIR/$tdir/$testnum
13903         mkdir -p $dir0 || error "creating dir $dir0"
13904
13905         local file=$dir0/file1
13906         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13907         local dv1=$($LFS data_version $file)
13908         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13909         local dv2=$($LFS data_version $file)
13910         [[ $dv1 != $dv2 ]] ||
13911                 error "data version did not change on write $dv1 == $dv2"
13912
13913         # clean up
13914         rm -f $file1
13915 }
13916 run_test 187a "Test data version change"
13917
13918 test_187b() {
13919         remote_mds_nodsh && skip "remote MDS with nodsh"
13920         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13921                 skip "Need MDS version at least 2.3.0"
13922
13923         local dir0=$DIR/$tdir/$testnum
13924         mkdir -p $dir0 || error "creating dir $dir0"
13925
13926         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13927         [[ ${DV[0]} != ${DV[1]} ]] ||
13928                 error "data version did not change on write"\
13929                       " ${DV[0]} == ${DV[1]}"
13930
13931         # clean up
13932         rm -f $file1
13933 }
13934 run_test 187b "Test data version change on volatile file"
13935
13936 test_200() {
13937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13938         remote_mgs_nodsh && skip "remote MGS with nodsh"
13939         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13940
13941         local POOL=${POOL:-cea1}
13942         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13943         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13944         # Pool OST targets
13945         local first_ost=0
13946         local last_ost=$(($OSTCOUNT - 1))
13947         local ost_step=2
13948         local ost_list=$(seq $first_ost $ost_step $last_ost)
13949         local ost_range="$first_ost $last_ost $ost_step"
13950         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13951         local file_dir=$POOL_ROOT/file_tst
13952         local subdir=$test_path/subdir
13953         local rc=0
13954
13955         if ! combined_mgs_mds ; then
13956                 mount_mgs_client
13957         fi
13958
13959         while : ; do
13960                 # former test_200a test_200b
13961                 pool_add $POOL                          || { rc=$? ; break; }
13962                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
13963                 # former test_200c test_200d
13964                 mkdir -p $test_path
13965                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
13966                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
13967                 mkdir -p $subdir
13968                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
13969                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
13970                                                         || { rc=$? ; break; }
13971                 # former test_200e test_200f
13972                 local files=$((OSTCOUNT*3))
13973                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
13974                                                         || { rc=$? ; break; }
13975                 pool_create_files $POOL $file_dir $files "$ost_list" \
13976                                                         || { rc=$? ; break; }
13977                 # former test_200g test_200h
13978                 pool_lfs_df $POOL                       || { rc=$? ; break; }
13979                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
13980
13981                 # former test_201a test_201b test_201c
13982                 pool_remove_first_target $POOL          || { rc=$? ; break; }
13983
13984                 local f=$test_path/$tfile
13985                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
13986                 pool_remove $POOL $f                    || { rc=$? ; break; }
13987                 break
13988         done
13989
13990         destroy_test_pools
13991
13992         if ! combined_mgs_mds ; then
13993                 umount_mgs_client
13994         fi
13995         return $rc
13996 }
13997 run_test 200 "OST pools"
13998
13999 # usage: default_attr <count | size | offset>
14000 default_attr() {
14001         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14002 }
14003
14004 # usage: check_default_stripe_attr
14005 check_default_stripe_attr() {
14006         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14007         case $1 in
14008         --stripe-count|-c)
14009                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14010         --stripe-size|-S)
14011                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14012         --stripe-index|-i)
14013                 EXPECTED=-1;;
14014         *)
14015                 error "unknown getstripe attr '$1'"
14016         esac
14017
14018         [ $ACTUAL == $EXPECTED ] ||
14019                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14020 }
14021
14022 test_204a() {
14023         test_mkdir $DIR/$tdir
14024         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14025
14026         check_default_stripe_attr --stripe-count
14027         check_default_stripe_attr --stripe-size
14028         check_default_stripe_attr --stripe-index
14029 }
14030 run_test 204a "Print default stripe attributes"
14031
14032 test_204b() {
14033         test_mkdir $DIR/$tdir
14034         $LFS setstripe --stripe-count 1 $DIR/$tdir
14035
14036         check_default_stripe_attr --stripe-size
14037         check_default_stripe_attr --stripe-index
14038 }
14039 run_test 204b "Print default stripe size and offset"
14040
14041 test_204c() {
14042         test_mkdir $DIR/$tdir
14043         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14044
14045         check_default_stripe_attr --stripe-count
14046         check_default_stripe_attr --stripe-index
14047 }
14048 run_test 204c "Print default stripe count and offset"
14049
14050 test_204d() {
14051         test_mkdir $DIR/$tdir
14052         $LFS setstripe --stripe-index 0 $DIR/$tdir
14053
14054         check_default_stripe_attr --stripe-count
14055         check_default_stripe_attr --stripe-size
14056 }
14057 run_test 204d "Print default stripe count and size"
14058
14059 test_204e() {
14060         test_mkdir $DIR/$tdir
14061         $LFS setstripe -d $DIR/$tdir
14062
14063         check_default_stripe_attr --stripe-count --raw
14064         check_default_stripe_attr --stripe-size --raw
14065         check_default_stripe_attr --stripe-index --raw
14066 }
14067 run_test 204e "Print raw stripe attributes"
14068
14069 test_204f() {
14070         test_mkdir $DIR/$tdir
14071         $LFS setstripe --stripe-count 1 $DIR/$tdir
14072
14073         check_default_stripe_attr --stripe-size --raw
14074         check_default_stripe_attr --stripe-index --raw
14075 }
14076 run_test 204f "Print raw stripe size and offset"
14077
14078 test_204g() {
14079         test_mkdir $DIR/$tdir
14080         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14081
14082         check_default_stripe_attr --stripe-count --raw
14083         check_default_stripe_attr --stripe-index --raw
14084 }
14085 run_test 204g "Print raw stripe count and offset"
14086
14087 test_204h() {
14088         test_mkdir $DIR/$tdir
14089         $LFS setstripe --stripe-index 0 $DIR/$tdir
14090
14091         check_default_stripe_attr --stripe-count --raw
14092         check_default_stripe_attr --stripe-size --raw
14093 }
14094 run_test 204h "Print raw stripe count and size"
14095
14096 # Figure out which job scheduler is being used, if any,
14097 # or use a fake one
14098 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14099         JOBENV=SLURM_JOB_ID
14100 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14101         JOBENV=LSB_JOBID
14102 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14103         JOBENV=PBS_JOBID
14104 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14105         JOBENV=LOADL_STEP_ID
14106 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14107         JOBENV=JOB_ID
14108 else
14109         $LCTL list_param jobid_name > /dev/null 2>&1
14110         if [ $? -eq 0 ]; then
14111                 JOBENV=nodelocal
14112         else
14113                 JOBENV=FAKE_JOBID
14114         fi
14115 fi
14116 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14117
14118 verify_jobstats() {
14119         local cmd=($1)
14120         shift
14121         local facets="$@"
14122
14123 # we don't really need to clear the stats for this test to work, since each
14124 # command has a unique jobid, but it makes debugging easier if needed.
14125 #       for facet in $facets; do
14126 #               local dev=$(convert_facet2label $facet)
14127 #               # clear old jobstats
14128 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14129 #       done
14130
14131         # use a new JobID for each test, or we might see an old one
14132         [ "$JOBENV" = "FAKE_JOBID" ] &&
14133                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14134
14135         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14136
14137         [ "$JOBENV" = "nodelocal" ] && {
14138                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14139                 $LCTL set_param jobid_name=$FAKE_JOBID
14140                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14141         }
14142
14143         log "Test: ${cmd[*]}"
14144         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14145
14146         if [ $JOBENV = "FAKE_JOBID" ]; then
14147                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14148         else
14149                 ${cmd[*]}
14150         fi
14151
14152         # all files are created on OST0000
14153         for facet in $facets; do
14154                 local stats="*.$(convert_facet2label $facet).job_stats"
14155
14156                 # strip out libtool wrappers for in-tree executables
14157                 if [ $(do_facet $facet lctl get_param $stats |
14158                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14159                         do_facet $facet lctl get_param $stats
14160                         error "No jobstats for $JOBVAL found on $facet::$stats"
14161                 fi
14162         done
14163 }
14164
14165 jobstats_set() {
14166         local new_jobenv=$1
14167
14168         set_persistent_param_and_check client "jobid_var" \
14169                 "$FSNAME.sys.jobid_var" $new_jobenv
14170 }
14171
14172 test_205() { # Job stats
14173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14174         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14175                 skip "Need MDS version with at least 2.7.1"
14176         remote_mgs_nodsh && skip "remote MGS with nodsh"
14177         remote_mds_nodsh && skip "remote MDS with nodsh"
14178         remote_ost_nodsh && skip "remote OST with nodsh"
14179         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14180                 skip "Server doesn't support jobstats"
14181         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14182
14183         local old_jobenv=$($LCTL get_param -n jobid_var)
14184         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14185
14186         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14187                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14188         else
14189                 stack_trap "do_facet mgs $PERM_CMD \
14190                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14191         fi
14192         changelog_register
14193
14194         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14195                                 mdt.*.job_cleanup_interval | head -n 1)
14196         local new_interval=5
14197         do_facet $SINGLEMDS \
14198                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14199         stack_trap "do_facet $SINGLEMDS \
14200                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14201         local start=$SECONDS
14202
14203         local cmd
14204         # mkdir
14205         cmd="mkdir $DIR/$tdir"
14206         verify_jobstats "$cmd" "$SINGLEMDS"
14207         # rmdir
14208         cmd="rmdir $DIR/$tdir"
14209         verify_jobstats "$cmd" "$SINGLEMDS"
14210         # mkdir on secondary MDT
14211         if [ $MDSCOUNT -gt 1 ]; then
14212                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14213                 verify_jobstats "$cmd" "mds2"
14214         fi
14215         # mknod
14216         cmd="mknod $DIR/$tfile c 1 3"
14217         verify_jobstats "$cmd" "$SINGLEMDS"
14218         # unlink
14219         cmd="rm -f $DIR/$tfile"
14220         verify_jobstats "$cmd" "$SINGLEMDS"
14221         # create all files on OST0000 so verify_jobstats can find OST stats
14222         # open & close
14223         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14224         verify_jobstats "$cmd" "$SINGLEMDS"
14225         # setattr
14226         cmd="touch $DIR/$tfile"
14227         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14228         # write
14229         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14230         verify_jobstats "$cmd" "ost1"
14231         # read
14232         cancel_lru_locks osc
14233         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14234         verify_jobstats "$cmd" "ost1"
14235         # truncate
14236         cmd="$TRUNCATE $DIR/$tfile 0"
14237         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14238         # rename
14239         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14240         verify_jobstats "$cmd" "$SINGLEMDS"
14241         # jobstats expiry - sleep until old stats should be expired
14242         local left=$((new_interval + 5 - (SECONDS - start)))
14243         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14244                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14245                         "0" $left
14246         cmd="mkdir $DIR/$tdir.expire"
14247         verify_jobstats "$cmd" "$SINGLEMDS"
14248         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14249             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14250
14251         # Ensure that jobid are present in changelog (if supported by MDS)
14252         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14253                 changelog_dump | tail -10
14254                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14255                 [ $jobids -eq 9 ] ||
14256                         error "Wrong changelog jobid count $jobids != 9"
14257
14258                 # LU-5862
14259                 JOBENV="disable"
14260                 jobstats_set $JOBENV
14261                 touch $DIR/$tfile
14262                 changelog_dump | grep $tfile
14263                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14264                 [ $jobids -eq 0 ] ||
14265                         error "Unexpected jobids when jobid_var=$JOBENV"
14266         fi
14267
14268         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14269         JOBENV="JOBCOMPLEX"
14270         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14271
14272         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14273 }
14274 run_test 205 "Verify job stats"
14275
14276 # LU-1480, LU-1773 and LU-1657
14277 test_206() {
14278         mkdir -p $DIR/$tdir
14279         $LFS setstripe -c -1 $DIR/$tdir
14280 #define OBD_FAIL_LOV_INIT 0x1403
14281         $LCTL set_param fail_loc=0xa0001403
14282         $LCTL set_param fail_val=1
14283         touch $DIR/$tdir/$tfile || true
14284 }
14285 run_test 206 "fail lov_init_raid0() doesn't lbug"
14286
14287 test_207a() {
14288         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14289         local fsz=`stat -c %s $DIR/$tfile`
14290         cancel_lru_locks mdc
14291
14292         # do not return layout in getattr intent
14293 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14294         $LCTL set_param fail_loc=0x170
14295         local sz=`stat -c %s $DIR/$tfile`
14296
14297         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14298
14299         rm -rf $DIR/$tfile
14300 }
14301 run_test 207a "can refresh layout at glimpse"
14302
14303 test_207b() {
14304         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14305         local cksum=`md5sum $DIR/$tfile`
14306         local fsz=`stat -c %s $DIR/$tfile`
14307         cancel_lru_locks mdc
14308         cancel_lru_locks osc
14309
14310         # do not return layout in getattr intent
14311 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14312         $LCTL set_param fail_loc=0x171
14313
14314         # it will refresh layout after the file is opened but before read issues
14315         echo checksum is "$cksum"
14316         echo "$cksum" |md5sum -c --quiet || error "file differs"
14317
14318         rm -rf $DIR/$tfile
14319 }
14320 run_test 207b "can refresh layout at open"
14321
14322 test_208() {
14323         # FIXME: in this test suite, only RD lease is used. This is okay
14324         # for now as only exclusive open is supported. After generic lease
14325         # is done, this test suite should be revised. - Jinshan
14326
14327         remote_mds_nodsh && skip "remote MDS with nodsh"
14328         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14329                 skip "Need MDS version at least 2.4.52"
14330
14331         echo "==== test 1: verify get lease work"
14332         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14333
14334         echo "==== test 2: verify lease can be broken by upcoming open"
14335         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14336         local PID=$!
14337         sleep 1
14338
14339         $MULTIOP $DIR/$tfile oO_RDONLY:c
14340         kill -USR1 $PID && wait $PID || error "break lease error"
14341
14342         echo "==== test 3: verify lease can't be granted if an open already exists"
14343         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14344         local PID=$!
14345         sleep 1
14346
14347         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14348         kill -USR1 $PID && wait $PID || error "open file error"
14349
14350         echo "==== test 4: lease can sustain over recovery"
14351         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14352         PID=$!
14353         sleep 1
14354
14355         fail mds1
14356
14357         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14358
14359         echo "==== test 5: lease broken can't be regained by replay"
14360         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14361         PID=$!
14362         sleep 1
14363
14364         # open file to break lease and then recovery
14365         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14366         fail mds1
14367
14368         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14369
14370         rm -f $DIR/$tfile
14371 }
14372 run_test 208 "Exclusive open"
14373
14374 test_209() {
14375         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14376                 skip_env "must have disp_stripe"
14377
14378         touch $DIR/$tfile
14379         sync; sleep 5; sync;
14380
14381         echo 3 > /proc/sys/vm/drop_caches
14382         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14383
14384         # open/close 500 times
14385         for i in $(seq 500); do
14386                 cat $DIR/$tfile
14387         done
14388
14389         echo 3 > /proc/sys/vm/drop_caches
14390         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14391
14392         echo "before: $req_before, after: $req_after"
14393         [ $((req_after - req_before)) -ge 300 ] &&
14394                 error "open/close requests are not freed"
14395         return 0
14396 }
14397 run_test 209 "read-only open/close requests should be freed promptly"
14398
14399 test_212() {
14400         size=`date +%s`
14401         size=$((size % 8192 + 1))
14402         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14403         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14404         rm -f $DIR/f212 $DIR/f212.xyz
14405 }
14406 run_test 212 "Sendfile test ============================================"
14407
14408 test_213() {
14409         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14410         cancel_lru_locks osc
14411         lctl set_param fail_loc=0x8000040f
14412         # generate a read lock
14413         cat $DIR/$tfile > /dev/null
14414         # write to the file, it will try to cancel the above read lock.
14415         cat /etc/hosts >> $DIR/$tfile
14416 }
14417 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14418
14419 test_214() { # for bug 20133
14420         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14421         for (( i=0; i < 340; i++ )) ; do
14422                 touch $DIR/$tdir/d214c/a$i
14423         done
14424
14425         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14426         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14427         ls $DIR/d214c || error "ls $DIR/d214c failed"
14428         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14429         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14430 }
14431 run_test 214 "hash-indexed directory test - bug 20133"
14432
14433 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14434 create_lnet_proc_files() {
14435         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14436 }
14437
14438 # counterpart of create_lnet_proc_files
14439 remove_lnet_proc_files() {
14440         rm -f $TMP/lnet_$1.sys
14441 }
14442
14443 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14444 # 3rd arg as regexp for body
14445 check_lnet_proc_stats() {
14446         local l=$(cat "$TMP/lnet_$1" |wc -l)
14447         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14448
14449         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14450 }
14451
14452 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14453 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14454 # optional and can be regexp for 2nd line (lnet.routes case)
14455 check_lnet_proc_entry() {
14456         local blp=2          # blp stands for 'position of 1st line of body'
14457         [ -z "$5" ] || blp=3 # lnet.routes case
14458
14459         local l=$(cat "$TMP/lnet_$1" |wc -l)
14460         # subtracting one from $blp because the body can be empty
14461         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14462
14463         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14464                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14465
14466         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14467                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14468
14469         # bail out if any unexpected line happened
14470         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14471         [ "$?" != 0 ] || error "$2 misformatted"
14472 }
14473
14474 test_215() { # for bugs 18102, 21079, 21517
14475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14476
14477         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14478         local P='[1-9][0-9]*'           # positive numeric
14479         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14480         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14481         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14482         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14483
14484         local L1 # regexp for 1st line
14485         local L2 # regexp for 2nd line (optional)
14486         local BR # regexp for the rest (body)
14487
14488         # lnet.stats should look as 11 space-separated non-negative numerics
14489         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14490         create_lnet_proc_files "stats"
14491         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14492         remove_lnet_proc_files "stats"
14493
14494         # lnet.routes should look like this:
14495         # Routing disabled/enabled
14496         # net hops priority state router
14497         # where net is a string like tcp0, hops > 0, priority >= 0,
14498         # state is up/down,
14499         # router is a string like 192.168.1.1@tcp2
14500         L1="^Routing (disabled|enabled)$"
14501         L2="^net +hops +priority +state +router$"
14502         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14503         create_lnet_proc_files "routes"
14504         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14505         remove_lnet_proc_files "routes"
14506
14507         # lnet.routers should look like this:
14508         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14509         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14510         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14511         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14512         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14513         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14514         create_lnet_proc_files "routers"
14515         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14516         remove_lnet_proc_files "routers"
14517
14518         # lnet.peers should look like this:
14519         # nid refs state last max rtr min tx min queue
14520         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14521         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14522         # numeric (0 or >0 or <0), queue >= 0.
14523         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14524         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14525         create_lnet_proc_files "peers"
14526         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14527         remove_lnet_proc_files "peers"
14528
14529         # lnet.buffers  should look like this:
14530         # pages count credits min
14531         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14532         L1="^pages +count +credits +min$"
14533         BR="^ +$N +$N +$I +$I$"
14534         create_lnet_proc_files "buffers"
14535         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14536         remove_lnet_proc_files "buffers"
14537
14538         # lnet.nis should look like this:
14539         # nid status alive refs peer rtr max tx min
14540         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14541         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14542         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14543         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14544         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14545         create_lnet_proc_files "nis"
14546         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14547         remove_lnet_proc_files "nis"
14548
14549         # can we successfully write to lnet.stats?
14550         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14551 }
14552 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14553
14554 test_216() { # bug 20317
14555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14556         remote_ost_nodsh && skip "remote OST with nodsh"
14557
14558         local node
14559         local facets=$(get_facets OST)
14560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14561
14562         save_lustre_params client "osc.*.contention_seconds" > $p
14563         save_lustre_params $facets \
14564                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14565         save_lustre_params $facets \
14566                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14567         save_lustre_params $facets \
14568                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14569         clear_stats osc.*.osc_stats
14570
14571         # agressive lockless i/o settings
14572         do_nodes $(comma_list $(osts_nodes)) \
14573                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14574                         ldlm.namespaces.filter-*.contended_locks=0 \
14575                         ldlm.namespaces.filter-*.contention_seconds=60"
14576         lctl set_param -n osc.*.contention_seconds=60
14577
14578         $DIRECTIO write $DIR/$tfile 0 10 4096
14579         $CHECKSTAT -s 40960 $DIR/$tfile
14580
14581         # disable lockless i/o
14582         do_nodes $(comma_list $(osts_nodes)) \
14583                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14584                         ldlm.namespaces.filter-*.contended_locks=32 \
14585                         ldlm.namespaces.filter-*.contention_seconds=0"
14586         lctl set_param -n osc.*.contention_seconds=0
14587         clear_stats osc.*.osc_stats
14588
14589         dd if=/dev/zero of=$DIR/$tfile count=0
14590         $CHECKSTAT -s 0 $DIR/$tfile
14591
14592         restore_lustre_params <$p
14593         rm -f $p
14594         rm $DIR/$tfile
14595 }
14596 run_test 216 "check lockless direct write updates file size and kms correctly"
14597
14598 test_217() { # bug 22430
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600
14601         local node
14602         local nid
14603
14604         for node in $(nodes_list); do
14605                 nid=$(host_nids_address $node $NETTYPE)
14606                 if [[ $nid = *-* ]] ; then
14607                         echo "lctl ping $(h2nettype $nid)"
14608                         lctl ping $(h2nettype $nid)
14609                 else
14610                         echo "skipping $node (no hyphen detected)"
14611                 fi
14612         done
14613 }
14614 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14615
14616 test_218() {
14617        # do directio so as not to populate the page cache
14618        log "creating a 10 Mb file"
14619        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14620        log "starting reads"
14621        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14622        log "truncating the file"
14623        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14624        log "killing dd"
14625        kill %+ || true # reads might have finished
14626        echo "wait until dd is finished"
14627        wait
14628        log "removing the temporary file"
14629        rm -rf $DIR/$tfile || error "tmp file removal failed"
14630 }
14631 run_test 218 "parallel read and truncate should not deadlock"
14632
14633 test_219() {
14634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14635
14636         # write one partial page
14637         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14638         # set no grant so vvp_io_commit_write will do sync write
14639         $LCTL set_param fail_loc=0x411
14640         # write a full page at the end of file
14641         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14642
14643         $LCTL set_param fail_loc=0
14644         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14645         $LCTL set_param fail_loc=0x411
14646         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14647
14648         # LU-4201
14649         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14650         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14651 }
14652 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14653
14654 test_220() { #LU-325
14655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14656         remote_ost_nodsh && skip "remote OST with nodsh"
14657         remote_mds_nodsh && skip "remote MDS with nodsh"
14658         remote_mgs_nodsh && skip "remote MGS with nodsh"
14659
14660         local OSTIDX=0
14661
14662         # create on MDT0000 so the last_id and next_id are correct
14663         mkdir $DIR/$tdir
14664         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14665         OST=${OST%_UUID}
14666
14667         # on the mdt's osc
14668         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14669         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14670                         osc.$mdtosc_proc1.prealloc_last_id)
14671         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14672                         osc.$mdtosc_proc1.prealloc_next_id)
14673
14674         $LFS df -i
14675
14676         if ! combined_mgs_mds ; then
14677                 mount_mgs_client
14678         fi
14679
14680         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14681         #define OBD_FAIL_OST_ENOINO              0x229
14682         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14683         create_pool $FSNAME.$TESTNAME || return 1
14684         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14685
14686         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14687
14688         MDSOBJS=$((last_id - next_id))
14689         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14690
14691         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14692         echo "OST still has $count kbytes free"
14693
14694         echo "create $MDSOBJS files @next_id..."
14695         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14696
14697         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14698                         osc.$mdtosc_proc1.prealloc_last_id)
14699         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14700                         osc.$mdtosc_proc1.prealloc_next_id)
14701
14702         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14703         $LFS df -i
14704
14705         echo "cleanup..."
14706
14707         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14708         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14709
14710         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14711                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14712         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14713                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14714         echo "unlink $MDSOBJS files @$next_id..."
14715         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14716
14717         if ! combined_mgs_mds ; then
14718                 umount_mgs_client
14719         fi
14720 }
14721 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14722
14723 test_221() {
14724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14725
14726         dd if=`which date` of=$MOUNT/date oflag=sync
14727         chmod +x $MOUNT/date
14728
14729         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14730         $LCTL set_param fail_loc=0x80001401
14731
14732         $MOUNT/date > /dev/null
14733         rm -f $MOUNT/date
14734 }
14735 run_test 221 "make sure fault and truncate race to not cause OOM"
14736
14737 test_222a () {
14738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14739
14740         rm -rf $DIR/$tdir
14741         test_mkdir $DIR/$tdir
14742         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14743         createmany -o $DIR/$tdir/$tfile 10
14744         cancel_lru_locks mdc
14745         cancel_lru_locks osc
14746         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14747         $LCTL set_param fail_loc=0x31a
14748         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14749         $LCTL set_param fail_loc=0
14750         rm -r $DIR/$tdir
14751 }
14752 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14753
14754 test_222b () {
14755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14756
14757         rm -rf $DIR/$tdir
14758         test_mkdir $DIR/$tdir
14759         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14760         createmany -o $DIR/$tdir/$tfile 10
14761         cancel_lru_locks mdc
14762         cancel_lru_locks osc
14763         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14764         $LCTL set_param fail_loc=0x31a
14765         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14766         $LCTL set_param fail_loc=0
14767 }
14768 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14769
14770 test_223 () {
14771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14772
14773         rm -rf $DIR/$tdir
14774         test_mkdir $DIR/$tdir
14775         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14776         createmany -o $DIR/$tdir/$tfile 10
14777         cancel_lru_locks mdc
14778         cancel_lru_locks osc
14779         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14780         $LCTL set_param fail_loc=0x31b
14781         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14782         $LCTL set_param fail_loc=0
14783         rm -r $DIR/$tdir
14784 }
14785 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14786
14787 test_224a() { # LU-1039, MRP-303
14788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14789
14790         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14791         $LCTL set_param fail_loc=0x508
14792         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14793         $LCTL set_param fail_loc=0
14794         df $DIR
14795 }
14796 run_test 224a "Don't panic on bulk IO failure"
14797
14798 test_224b() { # LU-1039, MRP-303
14799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14800
14801         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14802         cancel_lru_locks osc
14803         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14804         $LCTL set_param fail_loc=0x515
14805         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14806         $LCTL set_param fail_loc=0
14807         df $DIR
14808 }
14809 run_test 224b "Don't panic on bulk IO failure"
14810
14811 test_224c() { # LU-6441
14812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14813         remote_mds_nodsh && skip "remote MDS with nodsh"
14814
14815         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14816         save_writethrough $p
14817         set_cache writethrough on
14818
14819         local pages_per_rpc=$($LCTL get_param \
14820                                 osc.*.max_pages_per_rpc)
14821         local at_max=$($LCTL get_param -n at_max)
14822         local timeout=$($LCTL get_param -n timeout)
14823         local test_at="at_max"
14824         local param_at="$FSNAME.sys.at_max"
14825         local test_timeout="timeout"
14826         local param_timeout="$FSNAME.sys.timeout"
14827
14828         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14829
14830         set_persistent_param_and_check client "$test_at" "$param_at" 0
14831         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14832
14833         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14834         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14835         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14836         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14837         sync
14838         do_facet ost1 "$LCTL set_param fail_loc=0"
14839
14840         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14841         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14842                 $timeout
14843
14844         $LCTL set_param -n $pages_per_rpc
14845         restore_lustre_params < $p
14846         rm -f $p
14847 }
14848 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14849
14850 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14851 test_225a () {
14852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14853         if [ -z ${MDSSURVEY} ]; then
14854                 skip_env "mds-survey not found"
14855         fi
14856         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14857                 skip "Need MDS version at least 2.2.51"
14858
14859         local mds=$(facet_host $SINGLEMDS)
14860         local target=$(do_nodes $mds 'lctl dl' |
14861                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14862
14863         local cmd1="file_count=1000 thrhi=4"
14864         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14865         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14866         local cmd="$cmd1 $cmd2 $cmd3"
14867
14868         rm -f ${TMP}/mds_survey*
14869         echo + $cmd
14870         eval $cmd || error "mds-survey with zero-stripe failed"
14871         cat ${TMP}/mds_survey*
14872         rm -f ${TMP}/mds_survey*
14873 }
14874 run_test 225a "Metadata survey sanity with zero-stripe"
14875
14876 test_225b () {
14877         if [ -z ${MDSSURVEY} ]; then
14878                 skip_env "mds-survey not found"
14879         fi
14880         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14881                 skip "Need MDS version at least 2.2.51"
14882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14883         remote_mds_nodsh && skip "remote MDS with nodsh"
14884         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14885                 skip_env "Need to mount OST to test"
14886         fi
14887
14888         local mds=$(facet_host $SINGLEMDS)
14889         local target=$(do_nodes $mds 'lctl dl' |
14890                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14891
14892         local cmd1="file_count=1000 thrhi=4"
14893         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14894         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14895         local cmd="$cmd1 $cmd2 $cmd3"
14896
14897         rm -f ${TMP}/mds_survey*
14898         echo + $cmd
14899         eval $cmd || error "mds-survey with stripe_count failed"
14900         cat ${TMP}/mds_survey*
14901         rm -f ${TMP}/mds_survey*
14902 }
14903 run_test 225b "Metadata survey sanity with stripe_count = 1"
14904
14905 mcreate_path2fid () {
14906         local mode=$1
14907         local major=$2
14908         local minor=$3
14909         local name=$4
14910         local desc=$5
14911         local path=$DIR/$tdir/$name
14912         local fid
14913         local rc
14914         local fid_path
14915
14916         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14917                 error "cannot create $desc"
14918
14919         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14920         rc=$?
14921         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14922
14923         fid_path=$($LFS fid2path $MOUNT $fid)
14924         rc=$?
14925         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14926
14927         [ "$path" == "$fid_path" ] ||
14928                 error "fid2path returned $fid_path, expected $path"
14929
14930         echo "pass with $path and $fid"
14931 }
14932
14933 test_226a () {
14934         rm -rf $DIR/$tdir
14935         mkdir -p $DIR/$tdir
14936
14937         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14938         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14939         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14940         mcreate_path2fid 0040666 0 0 dir "directory"
14941         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14942         mcreate_path2fid 0100666 0 0 file "regular file"
14943         mcreate_path2fid 0120666 0 0 link "symbolic link"
14944         mcreate_path2fid 0140666 0 0 sock "socket"
14945 }
14946 run_test 226a "call path2fid and fid2path on files of all type"
14947
14948 test_226b () {
14949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14950
14951         local MDTIDX=1
14952
14953         rm -rf $DIR/$tdir
14954         mkdir -p $DIR/$tdir
14955         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
14956                 error "create remote directory failed"
14957         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
14958         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
14959                                 "character special file (null)"
14960         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
14961                                 "character special file (no device)"
14962         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
14963         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
14964                                 "block special file (loop)"
14965         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
14966         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
14967         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
14968 }
14969 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
14970
14971 # LU-1299 Executing or running ldd on a truncated executable does not
14972 # cause an out-of-memory condition.
14973 test_227() {
14974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14975         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
14976
14977         dd if=$(which date) of=$MOUNT/date bs=1k count=1
14978         chmod +x $MOUNT/date
14979
14980         $MOUNT/date > /dev/null
14981         ldd $MOUNT/date > /dev/null
14982         rm -f $MOUNT/date
14983 }
14984 run_test 227 "running truncated executable does not cause OOM"
14985
14986 # LU-1512 try to reuse idle OI blocks
14987 test_228a() {
14988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14989         remote_mds_nodsh && skip "remote MDS with nodsh"
14990         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
14991
14992         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
14993         local myDIR=$DIR/$tdir
14994
14995         mkdir -p $myDIR
14996         #define OBD_FAIL_SEQ_EXHAUST             0x1002
14997         $LCTL set_param fail_loc=0x80001002
14998         createmany -o $myDIR/t- 10000
14999         $LCTL set_param fail_loc=0
15000         # The guard is current the largest FID holder
15001         touch $myDIR/guard
15002         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15003                     tr -d '[')
15004         local IDX=$(($SEQ % 64))
15005
15006         do_facet $SINGLEMDS sync
15007         # Make sure journal flushed.
15008         sleep 6
15009         local blk1=$(do_facet $SINGLEMDS \
15010                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15011                      grep Blockcount | awk '{print $4}')
15012
15013         # Remove old files, some OI blocks will become idle.
15014         unlinkmany $myDIR/t- 10000
15015         # Create new files, idle OI blocks should be reused.
15016         createmany -o $myDIR/t- 2000
15017         do_facet $SINGLEMDS sync
15018         # Make sure journal flushed.
15019         sleep 6
15020         local blk2=$(do_facet $SINGLEMDS \
15021                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15022                      grep Blockcount | awk '{print $4}')
15023
15024         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15025 }
15026 run_test 228a "try to reuse idle OI blocks"
15027
15028 test_228b() {
15029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15030         remote_mds_nodsh && skip "remote MDS with nodsh"
15031         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15032
15033         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15034         local myDIR=$DIR/$tdir
15035
15036         mkdir -p $myDIR
15037         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15038         $LCTL set_param fail_loc=0x80001002
15039         createmany -o $myDIR/t- 10000
15040         $LCTL set_param fail_loc=0
15041         # The guard is current the largest FID holder
15042         touch $myDIR/guard
15043         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15044                     tr -d '[')
15045         local IDX=$(($SEQ % 64))
15046
15047         do_facet $SINGLEMDS sync
15048         # Make sure journal flushed.
15049         sleep 6
15050         local blk1=$(do_facet $SINGLEMDS \
15051                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15052                      grep Blockcount | awk '{print $4}')
15053
15054         # Remove old files, some OI blocks will become idle.
15055         unlinkmany $myDIR/t- 10000
15056
15057         # stop the MDT
15058         stop $SINGLEMDS || error "Fail to stop MDT."
15059         # remount the MDT
15060         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15061
15062         df $MOUNT || error "Fail to df."
15063         # Create new files, idle OI blocks should be reused.
15064         createmany -o $myDIR/t- 2000
15065         do_facet $SINGLEMDS sync
15066         # Make sure journal flushed.
15067         sleep 6
15068         local blk2=$(do_facet $SINGLEMDS \
15069                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15070                      grep Blockcount | awk '{print $4}')
15071
15072         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15073 }
15074 run_test 228b "idle OI blocks can be reused after MDT restart"
15075
15076 #LU-1881
15077 test_228c() {
15078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15079         remote_mds_nodsh && skip "remote MDS with nodsh"
15080         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15081
15082         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15083         local myDIR=$DIR/$tdir
15084
15085         mkdir -p $myDIR
15086         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15087         $LCTL set_param fail_loc=0x80001002
15088         # 20000 files can guarantee there are index nodes in the OI file
15089         createmany -o $myDIR/t- 20000
15090         $LCTL set_param fail_loc=0
15091         # The guard is current the largest FID holder
15092         touch $myDIR/guard
15093         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15094                     tr -d '[')
15095         local IDX=$(($SEQ % 64))
15096
15097         do_facet $SINGLEMDS sync
15098         # Make sure journal flushed.
15099         sleep 6
15100         local blk1=$(do_facet $SINGLEMDS \
15101                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15102                      grep Blockcount | awk '{print $4}')
15103
15104         # Remove old files, some OI blocks will become idle.
15105         unlinkmany $myDIR/t- 20000
15106         rm -f $myDIR/guard
15107         # The OI file should become empty now
15108
15109         # Create new files, idle OI blocks should be reused.
15110         createmany -o $myDIR/t- 2000
15111         do_facet $SINGLEMDS sync
15112         # Make sure journal flushed.
15113         sleep 6
15114         local blk2=$(do_facet $SINGLEMDS \
15115                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15116                      grep Blockcount | awk '{print $4}')
15117
15118         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15119 }
15120 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15121
15122 test_229() { # LU-2482, LU-3448
15123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15124         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15125         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15126                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15127
15128         rm -f $DIR/$tfile
15129
15130         # Create a file with a released layout and stripe count 2.
15131         $MULTIOP $DIR/$tfile H2c ||
15132                 error "failed to create file with released layout"
15133
15134         $LFS getstripe -v $DIR/$tfile
15135
15136         local pattern=$($LFS getstripe -L $DIR/$tfile)
15137         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15138
15139         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15140                 error "getstripe"
15141         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15142         stat $DIR/$tfile || error "failed to stat released file"
15143
15144         chown $RUNAS_ID $DIR/$tfile ||
15145                 error "chown $RUNAS_ID $DIR/$tfile failed"
15146
15147         chgrp $RUNAS_ID $DIR/$tfile ||
15148                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15149
15150         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15151         rm $DIR/$tfile || error "failed to remove released file"
15152 }
15153 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15154
15155 test_230a() {
15156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15159                 skip "Need MDS version at least 2.11.52"
15160
15161         local MDTIDX=1
15162
15163         test_mkdir $DIR/$tdir
15164         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15165         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15166         [ $mdt_idx -ne 0 ] &&
15167                 error "create local directory on wrong MDT $mdt_idx"
15168
15169         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15170                         error "create remote directory failed"
15171         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15172         [ $mdt_idx -ne $MDTIDX ] &&
15173                 error "create remote directory on wrong MDT $mdt_idx"
15174
15175         createmany -o $DIR/$tdir/test_230/t- 10 ||
15176                 error "create files on remote directory failed"
15177         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15178         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15179         rm -r $DIR/$tdir || error "unlink remote directory failed"
15180 }
15181 run_test 230a "Create remote directory and files under the remote directory"
15182
15183 test_230b() {
15184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15186         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15187                 skip "Need MDS version at least 2.11.52"
15188
15189         local MDTIDX=1
15190         local mdt_index
15191         local i
15192         local file
15193         local pid
15194         local stripe_count
15195         local migrate_dir=$DIR/$tdir/migrate_dir
15196         local other_dir=$DIR/$tdir/other_dir
15197
15198         test_mkdir $DIR/$tdir
15199         test_mkdir -i0 -c1 $migrate_dir
15200         test_mkdir -i0 -c1 $other_dir
15201         for ((i=0; i<10; i++)); do
15202                 mkdir -p $migrate_dir/dir_${i}
15203                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15204                         error "create files under remote dir failed $i"
15205         done
15206
15207         cp /etc/passwd $migrate_dir/$tfile
15208         cp /etc/passwd $other_dir/$tfile
15209         chattr +SAD $migrate_dir
15210         chattr +SAD $migrate_dir/$tfile
15211
15212         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15213         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15214         local old_dir_mode=$(stat -c%f $migrate_dir)
15215         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15216
15217         mkdir -p $migrate_dir/dir_default_stripe2
15218         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15219         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15220
15221         mkdir -p $other_dir
15222         ln $migrate_dir/$tfile $other_dir/luna
15223         ln $migrate_dir/$tfile $migrate_dir/sofia
15224         ln $other_dir/$tfile $migrate_dir/david
15225         ln -s $migrate_dir/$tfile $other_dir/zachary
15226         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15227         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15228
15229         $LFS migrate -m $MDTIDX $migrate_dir ||
15230                 error "fails on migrating remote dir to MDT1"
15231
15232         echo "migratate to MDT1, then checking.."
15233         for ((i = 0; i < 10; i++)); do
15234                 for file in $(find $migrate_dir/dir_${i}); do
15235                         mdt_index=$($LFS getstripe -m $file)
15236                         [ $mdt_index == $MDTIDX ] ||
15237                                 error "$file is not on MDT${MDTIDX}"
15238                 done
15239         done
15240
15241         # the multiple link file should still in MDT0
15242         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15243         [ $mdt_index == 0 ] ||
15244                 error "$file is not on MDT${MDTIDX}"
15245
15246         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15247         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15248                 error " expect $old_dir_flag get $new_dir_flag"
15249
15250         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15251         [ "$old_file_flag" = "$new_file_flag" ] ||
15252                 error " expect $old_file_flag get $new_file_flag"
15253
15254         local new_dir_mode=$(stat -c%f $migrate_dir)
15255         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15256                 error "expect mode $old_dir_mode get $new_dir_mode"
15257
15258         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15259         [ "$old_file_mode" = "$new_file_mode" ] ||
15260                 error "expect mode $old_file_mode get $new_file_mode"
15261
15262         diff /etc/passwd $migrate_dir/$tfile ||
15263                 error "$tfile different after migration"
15264
15265         diff /etc/passwd $other_dir/luna ||
15266                 error "luna different after migration"
15267
15268         diff /etc/passwd $migrate_dir/sofia ||
15269                 error "sofia different after migration"
15270
15271         diff /etc/passwd $migrate_dir/david ||
15272                 error "david different after migration"
15273
15274         diff /etc/passwd $other_dir/zachary ||
15275                 error "zachary different after migration"
15276
15277         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15278                 error "${tfile}_ln different after migration"
15279
15280         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15281                 error "${tfile}_ln_other different after migration"
15282
15283         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15284         [ $stripe_count = 2 ] ||
15285                 error "dir strpe_count $d != 2 after migration."
15286
15287         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15288         [ $stripe_count = 2 ] ||
15289                 error "file strpe_count $d != 2 after migration."
15290
15291         #migrate back to MDT0
15292         MDTIDX=0
15293
15294         $LFS migrate -m $MDTIDX $migrate_dir ||
15295                 error "fails on migrating remote dir to MDT0"
15296
15297         echo "migrate back to MDT0, checking.."
15298         for file in $(find $migrate_dir); do
15299                 mdt_index=$($LFS getstripe -m $file)
15300                 [ $mdt_index == $MDTIDX ] ||
15301                         error "$file is not on MDT${MDTIDX}"
15302         done
15303
15304         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15305         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15306                 error " expect $old_dir_flag get $new_dir_flag"
15307
15308         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15309         [ "$old_file_flag" = "$new_file_flag" ] ||
15310                 error " expect $old_file_flag get $new_file_flag"
15311
15312         local new_dir_mode=$(stat -c%f $migrate_dir)
15313         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15314                 error "expect mode $old_dir_mode get $new_dir_mode"
15315
15316         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15317         [ "$old_file_mode" = "$new_file_mode" ] ||
15318                 error "expect mode $old_file_mode get $new_file_mode"
15319
15320         diff /etc/passwd ${migrate_dir}/$tfile ||
15321                 error "$tfile different after migration"
15322
15323         diff /etc/passwd ${other_dir}/luna ||
15324                 error "luna different after migration"
15325
15326         diff /etc/passwd ${migrate_dir}/sofia ||
15327                 error "sofia different after migration"
15328
15329         diff /etc/passwd ${other_dir}/zachary ||
15330                 error "zachary different after migration"
15331
15332         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15333                 error "${tfile}_ln different after migration"
15334
15335         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15336                 error "${tfile}_ln_other different after migration"
15337
15338         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15339         [ $stripe_count = 2 ] ||
15340                 error "dir strpe_count $d != 2 after migration."
15341
15342         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15343         [ $stripe_count = 2 ] ||
15344                 error "file strpe_count $d != 2 after migration."
15345
15346         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15347 }
15348 run_test 230b "migrate directory"
15349
15350 test_230c() {
15351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15353         remote_mds_nodsh && skip "remote MDS with nodsh"
15354         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15355                 skip "Need MDS version at least 2.11.52"
15356
15357         local MDTIDX=1
15358         local total=3
15359         local mdt_index
15360         local file
15361         local migrate_dir=$DIR/$tdir/migrate_dir
15362
15363         #If migrating directory fails in the middle, all entries of
15364         #the directory is still accessiable.
15365         test_mkdir $DIR/$tdir
15366         test_mkdir -i0 -c1 $migrate_dir
15367         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15368         stat $migrate_dir
15369         createmany -o $migrate_dir/f $total ||
15370                 error "create files under ${migrate_dir} failed"
15371
15372         # fail after migrating top dir, and this will fail only once, so the
15373         # first sub file migration will fail (currently f3), others succeed.
15374         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15375         do_facet mds1 lctl set_param fail_loc=0x1801
15376         local t=$(ls $migrate_dir | wc -l)
15377         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15378                 error "migrate should fail"
15379         local u=$(ls $migrate_dir | wc -l)
15380         [ "$u" == "$t" ] || error "$u != $t during migration"
15381
15382         # add new dir/file should succeed
15383         mkdir $migrate_dir/dir ||
15384                 error "mkdir failed under migrating directory"
15385         touch $migrate_dir/file ||
15386                 error "create file failed under migrating directory"
15387
15388         # add file with existing name should fail
15389         for file in $migrate_dir/f*; do
15390                 stat $file > /dev/null || error "stat $file failed"
15391                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15392                         error "open(O_CREAT|O_EXCL) $file should fail"
15393                 $MULTIOP $file m && error "create $file should fail"
15394                 touch $DIR/$tdir/remote_dir/$tfile ||
15395                         error "touch $tfile failed"
15396                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15397                         error "link $file should fail"
15398                 mdt_index=$($LFS getstripe -m $file)
15399                 if [ $mdt_index == 0 ]; then
15400                         # file failed to migrate is not allowed to rename to
15401                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15402                                 error "rename to $file should fail"
15403                 else
15404                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15405                                 error "rename to $file failed"
15406                 fi
15407                 echo hello >> $file || error "write $file failed"
15408         done
15409
15410         # resume migration with different options should fail
15411         $LFS migrate -m 0 $migrate_dir &&
15412                 error "migrate -m 0 $migrate_dir should fail"
15413
15414         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15415                 error "migrate -c 2 $migrate_dir should fail"
15416
15417         # resume migration should succeed
15418         $LFS migrate -m $MDTIDX $migrate_dir ||
15419                 error "migrate $migrate_dir failed"
15420
15421         echo "Finish migration, then checking.."
15422         for file in $(find $migrate_dir); do
15423                 mdt_index=$($LFS getstripe -m $file)
15424                 [ $mdt_index == $MDTIDX ] ||
15425                         error "$file is not on MDT${MDTIDX}"
15426         done
15427
15428         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15429 }
15430 run_test 230c "check directory accessiblity if migration failed"
15431
15432 test_230d() {
15433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15434         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15435         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15436                 skip "Need MDS version at least 2.11.52"
15437         # LU-11235
15438         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15439
15440         local migrate_dir=$DIR/$tdir/migrate_dir
15441         local old_index
15442         local new_index
15443         local old_count
15444         local new_count
15445         local new_hash
15446         local mdt_index
15447         local i
15448         local j
15449
15450         old_index=$((RANDOM % MDSCOUNT))
15451         old_count=$((MDSCOUNT - old_index))
15452         new_index=$((RANDOM % MDSCOUNT))
15453         new_count=$((MDSCOUNT - new_index))
15454         new_hash="all_char"
15455
15456         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15457         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15458
15459         test_mkdir $DIR/$tdir
15460         test_mkdir -i $old_index -c $old_count $migrate_dir
15461
15462         for ((i=0; i<100; i++)); do
15463                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15464                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15465                         error "create files under remote dir failed $i"
15466         done
15467
15468         echo -n "Migrate from MDT$old_index "
15469         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15470         echo -n "to MDT$new_index"
15471         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15472         echo
15473
15474         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15475         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15476                 error "migrate remote dir error"
15477
15478         echo "Finish migration, then checking.."
15479         for file in $(find $migrate_dir); do
15480                 mdt_index=$($LFS getstripe -m $file)
15481                 if [ $mdt_index -lt $new_index ] ||
15482                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15483                         error "$file is on MDT$mdt_index"
15484                 fi
15485         done
15486
15487         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15488 }
15489 run_test 230d "check migrate big directory"
15490
15491 test_230e() {
15492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15494         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15495                 skip "Need MDS version at least 2.11.52"
15496
15497         local i
15498         local j
15499         local a_fid
15500         local b_fid
15501
15502         mkdir -p $DIR/$tdir
15503         mkdir $DIR/$tdir/migrate_dir
15504         mkdir $DIR/$tdir/other_dir
15505         touch $DIR/$tdir/migrate_dir/a
15506         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15507         ls $DIR/$tdir/other_dir
15508
15509         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15510                 error "migrate dir fails"
15511
15512         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15513         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15514
15515         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15516         [ $mdt_index == 0 ] || error "a is not on MDT0"
15517
15518         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15519                 error "migrate dir fails"
15520
15521         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15522         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15523
15524         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15525         [ $mdt_index == 1 ] || error "a is not on MDT1"
15526
15527         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15528         [ $mdt_index == 1 ] || error "b is not on MDT1"
15529
15530         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15531         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15532
15533         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15534
15535         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15536 }
15537 run_test 230e "migrate mulitple local link files"
15538
15539 test_230f() {
15540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15542         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15543                 skip "Need MDS version at least 2.11.52"
15544
15545         local a_fid
15546         local ln_fid
15547
15548         mkdir -p $DIR/$tdir
15549         mkdir $DIR/$tdir/migrate_dir
15550         $LFS mkdir -i1 $DIR/$tdir/other_dir
15551         touch $DIR/$tdir/migrate_dir/a
15552         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15553         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15554         ls $DIR/$tdir/other_dir
15555
15556         # a should be migrated to MDT1, since no other links on MDT0
15557         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15558                 error "#1 migrate dir fails"
15559         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15560         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15561         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15562         [ $mdt_index == 1 ] || error "a is not on MDT1"
15563
15564         # a should stay on MDT1, because it is a mulitple link file
15565         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15566                 error "#2 migrate dir fails"
15567         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15568         [ $mdt_index == 1 ] || error "a is not on MDT1"
15569
15570         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15571                 error "#3 migrate dir fails"
15572
15573         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15574         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15575         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15576
15577         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15578         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15579
15580         # a should be migrated to MDT0, since no other links on MDT1
15581         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15582                 error "#4 migrate dir fails"
15583         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15584         [ $mdt_index == 0 ] || error "a is not on MDT0"
15585
15586         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15587 }
15588 run_test 230f "migrate mulitple remote link files"
15589
15590 test_230g() {
15591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15592         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15593         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15594                 skip "Need MDS version at least 2.11.52"
15595
15596         mkdir -p $DIR/$tdir/migrate_dir
15597
15598         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15599                 error "migrating dir to non-exist MDT succeeds"
15600         true
15601 }
15602 run_test 230g "migrate dir to non-exist MDT"
15603
15604 test_230h() {
15605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15607         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15608                 skip "Need MDS version at least 2.11.52"
15609
15610         local mdt_index
15611
15612         mkdir -p $DIR/$tdir/migrate_dir
15613
15614         $LFS migrate -m1 $DIR &&
15615                 error "migrating mountpoint1 should fail"
15616
15617         $LFS migrate -m1 $DIR/$tdir/.. &&
15618                 error "migrating mountpoint2 should fail"
15619
15620         # same as mv
15621         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15622                 error "migrating $tdir/migrate_dir/.. should fail"
15623
15624         true
15625 }
15626 run_test 230h "migrate .. and root"
15627
15628 test_230i() {
15629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15631         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15632                 skip "Need MDS version at least 2.11.52"
15633
15634         mkdir -p $DIR/$tdir/migrate_dir
15635
15636         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15637                 error "migration fails with a tailing slash"
15638
15639         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15640                 error "migration fails with two tailing slashes"
15641 }
15642 run_test 230i "lfs migrate -m tolerates trailing slashes"
15643
15644 test_230j() {
15645         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15646         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15647                 skip "Need MDS version at least 2.11.52"
15648
15649         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15650         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15651                 error "create $tfile failed"
15652         cat /etc/passwd > $DIR/$tdir/$tfile
15653
15654         $LFS migrate -m 1 $DIR/$tdir
15655
15656         cmp /etc/passwd $DIR/$tdir/$tfile ||
15657                 error "DoM file mismatch after migration"
15658 }
15659 run_test 230j "DoM file data not changed after dir migration"
15660
15661 test_230k() {
15662         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15663         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15664                 skip "Need MDS version at least 2.11.56"
15665
15666         local total=20
15667         local files_on_starting_mdt=0
15668
15669         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15670         $LFS getdirstripe $DIR/$tdir
15671         for i in $(seq $total); do
15672                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15673                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15674                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15675         done
15676
15677         echo "$files_on_starting_mdt files on MDT0"
15678
15679         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15680         $LFS getdirstripe $DIR/$tdir
15681
15682         files_on_starting_mdt=0
15683         for i in $(seq $total); do
15684                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15685                         error "file $tfile.$i mismatch after migration"
15686                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15687                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15688         done
15689
15690         echo "$files_on_starting_mdt files on MDT1 after migration"
15691         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15692
15693         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15694         $LFS getdirstripe $DIR/$tdir
15695
15696         files_on_starting_mdt=0
15697         for i in $(seq $total); do
15698                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15699                         error "file $tfile.$i mismatch after 2nd migration"
15700                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15701                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15702         done
15703
15704         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15705         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15706
15707         true
15708 }
15709 run_test 230k "file data not changed after dir migration"
15710
15711 test_230l() {
15712         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15713         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15714                 skip "Need MDS version at least 2.11.56"
15715
15716         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15717         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15718                 error "create files under remote dir failed $i"
15719         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15720 }
15721 run_test 230l "readdir between MDTs won't crash"
15722
15723 test_231a()
15724 {
15725         # For simplicity this test assumes that max_pages_per_rpc
15726         # is the same across all OSCs
15727         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15728         local bulk_size=$((max_pages * PAGE_SIZE))
15729         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15730                                        head -n 1)
15731
15732         mkdir -p $DIR/$tdir
15733         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15734                 error "failed to set stripe with -S ${brw_size}M option"
15735
15736         # clear the OSC stats
15737         $LCTL set_param osc.*.stats=0 &>/dev/null
15738         stop_writeback
15739
15740         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15742                 oflag=direct &>/dev/null || error "dd failed"
15743
15744         sync; sleep 1; sync # just to be safe
15745         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15746         if [ x$nrpcs != "x1" ]; then
15747                 $LCTL get_param osc.*.stats
15748                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15749         fi
15750
15751         start_writeback
15752         # Drop the OSC cache, otherwise we will read from it
15753         cancel_lru_locks osc
15754
15755         # clear the OSC stats
15756         $LCTL set_param osc.*.stats=0 &>/dev/null
15757
15758         # Client reads $bulk_size.
15759         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15760                 iflag=direct &>/dev/null || error "dd failed"
15761
15762         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15763         if [ x$nrpcs != "x1" ]; then
15764                 $LCTL get_param osc.*.stats
15765                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15766         fi
15767 }
15768 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15769
15770 test_231b() {
15771         mkdir -p $DIR/$tdir
15772         local i
15773         for i in {0..1023}; do
15774                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15775                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15776                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15777         done
15778         sync
15779 }
15780 run_test 231b "must not assert on fully utilized OST request buffer"
15781
15782 test_232a() {
15783         mkdir -p $DIR/$tdir
15784         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15785
15786         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15787         do_facet ost1 $LCTL set_param fail_loc=0x31c
15788
15789         # ignore dd failure
15790         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15791
15792         do_facet ost1 $LCTL set_param fail_loc=0
15793         umount_client $MOUNT || error "umount failed"
15794         mount_client $MOUNT || error "mount failed"
15795         stop ost1 || error "cannot stop ost1"
15796         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15797 }
15798 run_test 232a "failed lock should not block umount"
15799
15800 test_232b() {
15801         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15802                 skip "Need MDS version at least 2.10.58"
15803
15804         mkdir -p $DIR/$tdir
15805         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15806         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15807         sync
15808         cancel_lru_locks osc
15809
15810         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15811         do_facet ost1 $LCTL set_param fail_loc=0x31c
15812
15813         # ignore failure
15814         $LFS data_version $DIR/$tdir/$tfile || true
15815
15816         do_facet ost1 $LCTL set_param fail_loc=0
15817         umount_client $MOUNT || error "umount failed"
15818         mount_client $MOUNT || error "mount failed"
15819         stop ost1 || error "cannot stop ost1"
15820         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15821 }
15822 run_test 232b "failed data version lock should not block umount"
15823
15824 test_233a() {
15825         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15826                 skip "Need MDS version at least 2.3.64"
15827         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15828
15829         local fid=$($LFS path2fid $MOUNT)
15830
15831         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15832                 error "cannot access $MOUNT using its FID '$fid'"
15833 }
15834 run_test 233a "checking that OBF of the FS root succeeds"
15835
15836 test_233b() {
15837         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15838                 skip "Need MDS version at least 2.5.90"
15839         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15840
15841         local fid=$($LFS path2fid $MOUNT/.lustre)
15842
15843         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15844                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15845
15846         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15847         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15848                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15849 }
15850 run_test 233b "checking that OBF of the FS .lustre succeeds"
15851
15852 test_234() {
15853         local p="$TMP/sanityN-$TESTNAME.parameters"
15854         save_lustre_params client "llite.*.xattr_cache" > $p
15855         lctl set_param llite.*.xattr_cache 1 ||
15856                 skip_env "xattr cache is not supported"
15857
15858         mkdir -p $DIR/$tdir || error "mkdir failed"
15859         touch $DIR/$tdir/$tfile || error "touch failed"
15860         # OBD_FAIL_LLITE_XATTR_ENOMEM
15861         $LCTL set_param fail_loc=0x1405
15862         getfattr -n user.attr $DIR/$tdir/$tfile &&
15863                 error "getfattr should have failed with ENOMEM"
15864         $LCTL set_param fail_loc=0x0
15865         rm -rf $DIR/$tdir
15866
15867         restore_lustre_params < $p
15868         rm -f $p
15869 }
15870 run_test 234 "xattr cache should not crash on ENOMEM"
15871
15872 test_235() {
15873         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15874                 skip "Need MDS version at least 2.4.52"
15875
15876         flock_deadlock $DIR/$tfile
15877         local RC=$?
15878         case $RC in
15879                 0)
15880                 ;;
15881                 124) error "process hangs on a deadlock"
15882                 ;;
15883                 *) error "error executing flock_deadlock $DIR/$tfile"
15884                 ;;
15885         esac
15886 }
15887 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15888
15889 #LU-2935
15890 test_236() {
15891         check_swap_layouts_support
15892
15893         local ref1=/etc/passwd
15894         local ref2=/etc/group
15895         local file1=$DIR/$tdir/f1
15896         local file2=$DIR/$tdir/f2
15897
15898         test_mkdir -c1 $DIR/$tdir
15899         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15900         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15901         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15902         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15903         local fd=$(free_fd)
15904         local cmd="exec $fd<>$file2"
15905         eval $cmd
15906         rm $file2
15907         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15908                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15909         cmd="exec $fd>&-"
15910         eval $cmd
15911         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15912
15913         #cleanup
15914         rm -rf $DIR/$tdir
15915 }
15916 run_test 236 "Layout swap on open unlinked file"
15917
15918 # LU-4659 linkea consistency
15919 test_238() {
15920         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15921                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15922                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15923                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15924
15925         touch $DIR/$tfile
15926         ln $DIR/$tfile $DIR/$tfile.lnk
15927         touch $DIR/$tfile.new
15928         mv $DIR/$tfile.new $DIR/$tfile
15929         local fid1=$($LFS path2fid $DIR/$tfile)
15930         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15931         local path1=$($LFS fid2path $FSNAME "$fid1")
15932         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15933         local path2=$($LFS fid2path $FSNAME "$fid2")
15934         [ $tfile.lnk == $path2 ] ||
15935                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15936         rm -f $DIR/$tfile*
15937 }
15938 run_test 238 "Verify linkea consistency"
15939
15940 test_239A() { # was test_239
15941         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15942                 skip "Need MDS version at least 2.5.60"
15943
15944         local list=$(comma_list $(mdts_nodes))
15945
15946         mkdir -p $DIR/$tdir
15947         createmany -o $DIR/$tdir/f- 5000
15948         unlinkmany $DIR/$tdir/f- 5000
15949         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15950                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15951         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
15952                         osp.*MDT*.sync_in_flight" | calc_sum)
15953         [ "$changes" -eq 0 ] || error "$changes not synced"
15954 }
15955 run_test 239A "osp_sync test"
15956
15957 test_239a() { #LU-5297
15958         remote_mds_nodsh && skip "remote MDS with nodsh"
15959
15960         touch $DIR/$tfile
15961         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
15962         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
15963         chgrp $RUNAS_GID $DIR/$tfile
15964         wait_delete_completed
15965 }
15966 run_test 239a "process invalid osp sync record correctly"
15967
15968 test_239b() { #LU-5297
15969         remote_mds_nodsh && skip "remote MDS with nodsh"
15970
15971         touch $DIR/$tfile1
15972         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
15973         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
15974         chgrp $RUNAS_GID $DIR/$tfile1
15975         wait_delete_completed
15976         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15977         touch $DIR/$tfile2
15978         chgrp $RUNAS_GID $DIR/$tfile2
15979         wait_delete_completed
15980 }
15981 run_test 239b "process osp sync record with ENOMEM error correctly"
15982
15983 test_240() {
15984         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15985         remote_mds_nodsh && skip "remote MDS with nodsh"
15986
15987         mkdir -p $DIR/$tdir
15988
15989         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
15990                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
15991         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
15992                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
15993
15994         umount_client $MOUNT || error "umount failed"
15995         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
15996         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
15997         mount_client $MOUNT || error "failed to mount client"
15998
15999         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16000         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16001 }
16002 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16003
16004 test_241_bio() {
16005         local count=$1
16006         local bsize=$2
16007
16008         for LOOP in $(seq $count); do
16009                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16010                 cancel_lru_locks $OSC || true
16011         done
16012 }
16013
16014 test_241_dio() {
16015         local count=$1
16016         local bsize=$2
16017
16018         for LOOP in $(seq $1); do
16019                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16020                         2>/dev/null
16021         done
16022 }
16023
16024 test_241a() { # was test_241
16025         local bsize=$PAGE_SIZE
16026
16027         (( bsize < 40960 )) && bsize=40960
16028         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16029         ls -la $DIR/$tfile
16030         cancel_lru_locks $OSC
16031         test_241_bio 1000 $bsize &
16032         PID=$!
16033         test_241_dio 1000 $bsize
16034         wait $PID
16035 }
16036 run_test 241a "bio vs dio"
16037
16038 test_241b() {
16039         local bsize=$PAGE_SIZE
16040
16041         (( bsize < 40960 )) && bsize=40960
16042         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16043         ls -la $DIR/$tfile
16044         test_241_dio 1000 $bsize &
16045         PID=$!
16046         test_241_dio 1000 $bsize
16047         wait $PID
16048 }
16049 run_test 241b "dio vs dio"
16050
16051 test_242() {
16052         remote_mds_nodsh && skip "remote MDS with nodsh"
16053
16054         mkdir -p $DIR/$tdir
16055         touch $DIR/$tdir/$tfile
16056
16057         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16058         do_facet mds1 lctl set_param fail_loc=0x105
16059         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16060
16061         do_facet mds1 lctl set_param fail_loc=0
16062         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16063 }
16064 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16065
16066 test_243()
16067 {
16068         test_mkdir $DIR/$tdir
16069         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16070 }
16071 run_test 243 "various group lock tests"
16072
16073 test_244()
16074 {
16075         test_mkdir $DIR/$tdir
16076         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16077         sendfile_grouplock $DIR/$tdir/$tfile || \
16078                 error "sendfile+grouplock failed"
16079         rm -rf $DIR/$tdir
16080 }
16081 run_test 244 "sendfile with group lock tests"
16082
16083 test_245() {
16084         local flagname="multi_mod_rpcs"
16085         local connect_data_name="max_mod_rpcs"
16086         local out
16087
16088         # check if multiple modify RPCs flag is set
16089         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16090                 grep "connect_flags:")
16091         echo "$out"
16092
16093         echo "$out" | grep -qw $flagname
16094         if [ $? -ne 0 ]; then
16095                 echo "connect flag $flagname is not set"
16096                 return
16097         fi
16098
16099         # check if multiple modify RPCs data is set
16100         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16101         echo "$out"
16102
16103         echo "$out" | grep -qw $connect_data_name ||
16104                 error "import should have connect data $connect_data_name"
16105 }
16106 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16107
16108 test_246() { # LU-7371
16109         remote_ost_nodsh && skip "remote OST with nodsh"
16110         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16111                 skip "Need OST version >= 2.7.62"
16112
16113         do_facet ost1 $LCTL set_param fail_val=4095
16114 #define OBD_FAIL_OST_READ_SIZE          0x234
16115         do_facet ost1 $LCTL set_param fail_loc=0x234
16116         $LFS setstripe $DIR/$tfile -i 0 -c 1
16117         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16118         cancel_lru_locks $FSNAME-OST0000
16119         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16120 }
16121 run_test 246 "Read file of size 4095 should return right length"
16122
16123 cleanup_247() {
16124         local submount=$1
16125
16126         trap 0
16127         umount_client $submount
16128         rmdir $submount
16129 }
16130
16131 test_247a() {
16132         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16133                 grep -q subtree ||
16134                 skip_env "Fileset feature is not supported"
16135
16136         local submount=${MOUNT}_$tdir
16137
16138         mkdir $MOUNT/$tdir
16139         mkdir -p $submount || error "mkdir $submount failed"
16140         FILESET="$FILESET/$tdir" mount_client $submount ||
16141                 error "mount $submount failed"
16142         trap "cleanup_247 $submount" EXIT
16143         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16144         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16145                 error "read $MOUNT/$tdir/$tfile failed"
16146         cleanup_247 $submount
16147 }
16148 run_test 247a "mount subdir as fileset"
16149
16150 test_247b() {
16151         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16152                 skip_env "Fileset feature is not supported"
16153
16154         local submount=${MOUNT}_$tdir
16155
16156         rm -rf $MOUNT/$tdir
16157         mkdir -p $submount || error "mkdir $submount failed"
16158         SKIP_FILESET=1
16159         FILESET="$FILESET/$tdir" mount_client $submount &&
16160                 error "mount $submount should fail"
16161         rmdir $submount
16162 }
16163 run_test 247b "mount subdir that dose not exist"
16164
16165 test_247c() {
16166         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16167                 skip_env "Fileset feature is not supported"
16168
16169         local submount=${MOUNT}_$tdir
16170
16171         mkdir -p $MOUNT/$tdir/dir1
16172         mkdir -p $submount || error "mkdir $submount failed"
16173         trap "cleanup_247 $submount" EXIT
16174         FILESET="$FILESET/$tdir" mount_client $submount ||
16175                 error "mount $submount failed"
16176         local fid=$($LFS path2fid $MOUNT/)
16177         $LFS fid2path $submount $fid && error "fid2path should fail"
16178         cleanup_247 $submount
16179 }
16180 run_test 247c "running fid2path outside root"
16181
16182 test_247d() {
16183         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16184                 skip "Fileset feature is not supported"
16185
16186         local submount=${MOUNT}_$tdir
16187
16188         mkdir -p $MOUNT/$tdir/dir1
16189         mkdir -p $submount || error "mkdir $submount failed"
16190         FILESET="$FILESET/$tdir" mount_client $submount ||
16191                 error "mount $submount failed"
16192         trap "cleanup_247 $submount" EXIT
16193         local fid=$($LFS path2fid $submount/dir1)
16194         $LFS fid2path $submount $fid || error "fid2path should succeed"
16195         cleanup_247 $submount
16196 }
16197 run_test 247d "running fid2path inside root"
16198
16199 # LU-8037
16200 test_247e() {
16201         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16202                 grep -q subtree ||
16203                 skip "Fileset feature is not supported"
16204
16205         local submount=${MOUNT}_$tdir
16206
16207         mkdir $MOUNT/$tdir
16208         mkdir -p $submount || error "mkdir $submount failed"
16209         FILESET="$FILESET/.." mount_client $submount &&
16210                 error "mount $submount should fail"
16211         rmdir $submount
16212 }
16213 run_test 247e "mount .. as fileset"
16214
16215 test_248() {
16216         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16217         [ -z "$fast_read_sav" ] && skip "no fast read support"
16218
16219         # create a large file for fast read verification
16220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16221
16222         # make sure the file is created correctly
16223         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16224                 { rm -f $DIR/$tfile; skip "file creation error"; }
16225
16226         echo "Test 1: verify that fast read is 4 times faster on cache read"
16227
16228         # small read with fast read enabled
16229         $LCTL set_param -n llite.*.fast_read=1
16230         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16231                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16232                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16233         # small read with fast read disabled
16234         $LCTL set_param -n llite.*.fast_read=0
16235         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16236                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16237                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16238
16239         # verify that fast read is 4 times faster for cache read
16240         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16241                 error_not_in_vm "fast read was not 4 times faster: " \
16242                            "$t_fast vs $t_slow"
16243
16244         echo "Test 2: verify the performance between big and small read"
16245         $LCTL set_param -n llite.*.fast_read=1
16246
16247         # 1k non-cache read
16248         cancel_lru_locks osc
16249         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16250                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16251                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16252
16253         # 1M non-cache read
16254         cancel_lru_locks osc
16255         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16256                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16257                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16258
16259         # verify that big IO is not 4 times faster than small IO
16260         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16261                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16262
16263         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16264         rm -f $DIR/$tfile
16265 }
16266 run_test 248 "fast read verification"
16267
16268 test_249() { # LU-7890
16269         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16270                 skip "Need at least version 2.8.54"
16271
16272         rm -f $DIR/$tfile
16273         $LFS setstripe -c 1 $DIR/$tfile
16274         # Offset 2T == 4k * 512M
16275         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16276                 error "dd to 2T offset failed"
16277 }
16278 run_test 249 "Write above 2T file size"
16279
16280 test_250() {
16281         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16282          && skip "no 16TB file size limit on ZFS"
16283
16284         $LFS setstripe -c 1 $DIR/$tfile
16285         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16286         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16287         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16288         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16289                 conv=notrunc,fsync && error "append succeeded"
16290         return 0
16291 }
16292 run_test 250 "Write above 16T limit"
16293
16294 test_251() {
16295         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16296
16297         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16298         #Skip once - writing the first stripe will succeed
16299         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16300         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16301                 error "short write happened"
16302
16303         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16304         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16305                 error "short read happened"
16306
16307         rm -f $DIR/$tfile
16308 }
16309 run_test 251 "Handling short read and write correctly"
16310
16311 test_252() {
16312         remote_mds_nodsh && skip "remote MDS with nodsh"
16313         remote_ost_nodsh && skip "remote OST with nodsh"
16314         if [ "$ost1_FSTYPE" != "ldiskfs" -o "$mds1_FSTYPE" != "ldiskfs" ]; then
16315                 skip_env "ldiskfs only test"
16316         fi
16317
16318         local tgt
16319         local dev
16320         local out
16321         local uuid
16322         local num
16323         local gen
16324
16325         # check lr_reader on OST0000
16326         tgt=ost1
16327         dev=$(facet_device $tgt)
16328         out=$(do_facet $tgt $LR_READER $dev)
16329         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16330         echo "$out"
16331         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16332         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16333                 error "Invalid uuid returned by $LR_READER on target $tgt"
16334         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16335
16336         # check lr_reader -c on MDT0000
16337         tgt=mds1
16338         dev=$(facet_device $tgt)
16339         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16340                 skip "$LR_READER does not support additional options"
16341         fi
16342         out=$(do_facet $tgt $LR_READER -c $dev)
16343         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16344         echo "$out"
16345         num=$(echo "$out" | grep -c "mdtlov")
16346         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16347                 error "Invalid number of mdtlov clients returned by $LR_READER"
16348         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16349
16350         # check lr_reader -cr on MDT0000
16351         out=$(do_facet $tgt $LR_READER -cr $dev)
16352         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16353         echo "$out"
16354         echo "$out" | grep -q "^reply_data:$" ||
16355                 error "$LR_READER should have returned 'reply_data' section"
16356         num=$(echo "$out" | grep -c "client_generation")
16357         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16358 }
16359 run_test 252 "check lr_reader tool"
16360
16361 test_253_fill_ost() {
16362         local size_mb #how many MB should we write to pass watermark
16363         local lwm=$3  #low watermark
16364         local free_10mb #10% of free space
16365
16366         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16367         size_mb=$((free_kb / 1024 - lwm))
16368         free_10mb=$((free_kb / 10240))
16369         #If 10% of free space cross low watermark use it
16370         if (( free_10mb > size_mb )); then
16371                 size_mb=$free_10mb
16372         else
16373                 #At least we need to store 1.1 of difference between
16374                 #free space and low watermark
16375                 size_mb=$((size_mb + size_mb / 10))
16376         fi
16377         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16378                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16379                          oflag=append conv=notrunc
16380         fi
16381
16382         sleep_maxage
16383
16384         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16385         echo "OST still has $((free_kb / 1024)) mbytes free"
16386 }
16387
16388 test_253() {
16389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16390         remote_mds_nodsh && skip "remote MDS with nodsh"
16391         remote_mgs_nodsh && skip "remote MGS with nodsh"
16392
16393         local ostidx=0
16394         local rc=0
16395
16396         local ost_name=$($LFS osts |
16397                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16398         # on the mdt's osc
16399         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16400         do_facet $SINGLEMDS $LCTL get_param -n \
16401                 osp.$mdtosc_proc1.reserved_mb_high ||
16402                 skip  "remote MDS does not support reserved_mb_high"
16403
16404         rm -rf $DIR/$tdir
16405         wait_mds_ost_sync
16406         wait_delete_completed
16407         mkdir $DIR/$tdir
16408
16409         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16410                         osp.$mdtosc_proc1.reserved_mb_high)
16411         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16412                         osp.$mdtosc_proc1.reserved_mb_low)
16413         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16414
16415         if ! combined_mgs_mds ; then
16416                 mount_mgs_client
16417         fi
16418         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16419         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16420                 error "Adding $ost_name to pool failed"
16421
16422         # Wait for client to see a OST at pool
16423         wait_update $HOSTNAME "$LCTL get_param -n
16424                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16425                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16426                 error "Client can not see the pool"
16427         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16428                 error "Setstripe failed"
16429
16430         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16431         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16432         echo "OST still has $((blocks/1024)) mbytes free"
16433
16434         local new_lwm=$((blocks/1024-10))
16435         do_facet $SINGLEMDS $LCTL set_param \
16436                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16437         do_facet $SINGLEMDS $LCTL set_param \
16438                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16439
16440         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16441
16442         #First enospc could execute orphan deletion so repeat.
16443         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16444
16445         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16446                         osp.$mdtosc_proc1.prealloc_status)
16447         echo "prealloc_status $oa_status"
16448
16449         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16450                 error "File creation should fail"
16451         #object allocation was stopped, but we still able to append files
16452         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16453                 error "Append failed"
16454         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16455
16456         wait_delete_completed
16457
16458         sleep_maxage
16459
16460         for i in $(seq 10 12); do
16461                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16462                         error "File creation failed after rm";
16463         done
16464
16465         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16466                         osp.$mdtosc_proc1.prealloc_status)
16467         echo "prealloc_status $oa_status"
16468
16469         if (( oa_status != 0 )); then
16470                 error "Object allocation still disable after rm"
16471         fi
16472         do_facet $SINGLEMDS $LCTL set_param \
16473                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16474         do_facet $SINGLEMDS $LCTL set_param \
16475                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16476
16477
16478         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16479                 error "Remove $ost_name from pool failed"
16480         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16481                 error "Pool destroy fialed"
16482
16483         if ! combined_mgs_mds ; then
16484                 umount_mgs_client
16485         fi
16486 }
16487 run_test 253 "Check object allocation limit"
16488
16489 test_254() {
16490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16491         remote_mds_nodsh && skip "remote MDS with nodsh"
16492         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16493                 skip "MDS does not support changelog_size"
16494
16495         local cl_user
16496         local MDT0=$(facet_svc $SINGLEMDS)
16497
16498         changelog_register || error "changelog_register failed"
16499
16500         changelog_clear 0 || error "changelog_clear failed"
16501
16502         local size1=$(do_facet $SINGLEMDS \
16503                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16504         echo "Changelog size $size1"
16505
16506         rm -rf $DIR/$tdir
16507         $LFS mkdir -i 0 $DIR/$tdir
16508         # change something
16509         mkdir -p $DIR/$tdir/pics/2008/zachy
16510         touch $DIR/$tdir/pics/2008/zachy/timestamp
16511         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16512         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16513         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16514         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16515         rm $DIR/$tdir/pics/desktop.jpg
16516
16517         local size2=$(do_facet $SINGLEMDS \
16518                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16519         echo "Changelog size after work $size2"
16520
16521         (( $size2 > $size1 )) ||
16522                 error "new Changelog size=$size2 less than old size=$size1"
16523 }
16524 run_test 254 "Check changelog size"
16525
16526 ladvise_no_type()
16527 {
16528         local type=$1
16529         local file=$2
16530
16531         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16532                 awk -F: '{print $2}' | grep $type > /dev/null
16533         if [ $? -ne 0 ]; then
16534                 return 0
16535         fi
16536         return 1
16537 }
16538
16539 ladvise_no_ioctl()
16540 {
16541         local file=$1
16542
16543         lfs ladvise -a willread $file > /dev/null 2>&1
16544         if [ $? -eq 0 ]; then
16545                 return 1
16546         fi
16547
16548         lfs ladvise -a willread $file 2>&1 |
16549                 grep "Inappropriate ioctl for device" > /dev/null
16550         if [ $? -eq 0 ]; then
16551                 return 0
16552         fi
16553         return 1
16554 }
16555
16556 percent() {
16557         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16558 }
16559
16560 # run a random read IO workload
16561 # usage: random_read_iops <filename> <filesize> <iosize>
16562 random_read_iops() {
16563         local file=$1
16564         local fsize=$2
16565         local iosize=${3:-4096}
16566
16567         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16568                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16569 }
16570
16571 drop_file_oss_cache() {
16572         local file="$1"
16573         local nodes="$2"
16574
16575         $LFS ladvise -a dontneed $file 2>/dev/null ||
16576                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16577 }
16578
16579 ladvise_willread_performance()
16580 {
16581         local repeat=10
16582         local average_origin=0
16583         local average_cache=0
16584         local average_ladvise=0
16585
16586         for ((i = 1; i <= $repeat; i++)); do
16587                 echo "Iter $i/$repeat: reading without willread hint"
16588                 cancel_lru_locks osc
16589                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16590                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16591                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16592                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16593
16594                 cancel_lru_locks osc
16595                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16596                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16597                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16598
16599                 cancel_lru_locks osc
16600                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16601                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16602                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16603                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16604                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16605         done
16606         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16607         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16608         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16609
16610         speedup_cache=$(percent $average_cache $average_origin)
16611         speedup_ladvise=$(percent $average_ladvise $average_origin)
16612
16613         echo "Average uncached read: $average_origin"
16614         echo "Average speedup with OSS cached read: " \
16615                 "$average_cache = +$speedup_cache%"
16616         echo "Average speedup with ladvise willread: " \
16617                 "$average_ladvise = +$speedup_ladvise%"
16618
16619         local lowest_speedup=20
16620         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16621                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16622                         "got $average_cache%. Skipping ladvise willread check."
16623                 return 0
16624         fi
16625
16626         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16627         # it is still good to run until then to exercise 'ladvise willread'
16628         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16629                 [ "$ost1_FSTYPE" = "zfs" ] &&
16630                 echo "osd-zfs does not support dontneed or drop_caches" &&
16631                 return 0
16632
16633         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16634         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16635                 error_not_in_vm "Speedup with willread is less than " \
16636                         "$lowest_speedup%, got $average_ladvise%"
16637 }
16638
16639 test_255a() {
16640         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16641                 skip "lustre < 2.8.54 does not support ladvise "
16642         remote_ost_nodsh && skip "remote OST with nodsh"
16643
16644         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16645
16646         ladvise_no_type willread $DIR/$tfile &&
16647                 skip "willread ladvise is not supported"
16648
16649         ladvise_no_ioctl $DIR/$tfile &&
16650                 skip "ladvise ioctl is not supported"
16651
16652         local size_mb=100
16653         local size=$((size_mb * 1048576))
16654         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16655                 error "dd to $DIR/$tfile failed"
16656
16657         lfs ladvise -a willread $DIR/$tfile ||
16658                 error "Ladvise failed with no range argument"
16659
16660         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16661                 error "Ladvise failed with no -l or -e argument"
16662
16663         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16664                 error "Ladvise failed with only -e argument"
16665
16666         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16667                 error "Ladvise failed with only -l argument"
16668
16669         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16670                 error "End offset should not be smaller than start offset"
16671
16672         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16673                 error "End offset should not be equal to start offset"
16674
16675         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16676                 error "Ladvise failed with overflowing -s argument"
16677
16678         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16679                 error "Ladvise failed with overflowing -e argument"
16680
16681         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16682                 error "Ladvise failed with overflowing -l argument"
16683
16684         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16685                 error "Ladvise succeeded with conflicting -l and -e arguments"
16686
16687         echo "Synchronous ladvise should wait"
16688         local delay=4
16689 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16690         do_nodes $(comma_list $(osts_nodes)) \
16691                 $LCTL set_param fail_val=$delay fail_loc=0x237
16692
16693         local start_ts=$SECONDS
16694         lfs ladvise -a willread $DIR/$tfile ||
16695                 error "Ladvise failed with no range argument"
16696         local end_ts=$SECONDS
16697         local inteval_ts=$((end_ts - start_ts))
16698
16699         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16700                 error "Synchronous advice didn't wait reply"
16701         fi
16702
16703         echo "Asynchronous ladvise shouldn't wait"
16704         local start_ts=$SECONDS
16705         lfs ladvise -a willread -b $DIR/$tfile ||
16706                 error "Ladvise failed with no range argument"
16707         local end_ts=$SECONDS
16708         local inteval_ts=$((end_ts - start_ts))
16709
16710         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16711                 error "Asynchronous advice blocked"
16712         fi
16713
16714         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16715         ladvise_willread_performance
16716 }
16717 run_test 255a "check 'lfs ladvise -a willread'"
16718
16719 facet_meminfo() {
16720         local facet=$1
16721         local info=$2
16722
16723         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16724 }
16725
16726 test_255b() {
16727         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16728                 skip "lustre < 2.8.54 does not support ladvise "
16729         remote_ost_nodsh && skip "remote OST with nodsh"
16730
16731         lfs setstripe -c 1 -i 0 $DIR/$tfile
16732
16733         ladvise_no_type dontneed $DIR/$tfile &&
16734                 skip "dontneed ladvise is not supported"
16735
16736         ladvise_no_ioctl $DIR/$tfile &&
16737                 skip "ladvise ioctl is not supported"
16738
16739         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16740                 [ "$ost1_FSTYPE" = "zfs" ] &&
16741                 skip "zfs-osd does not support 'ladvise dontneed'"
16742
16743         local size_mb=100
16744         local size=$((size_mb * 1048576))
16745         # In order to prevent disturbance of other processes, only check 3/4
16746         # of the memory usage
16747         local kibibytes=$((size_mb * 1024 * 3 / 4))
16748
16749         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16750                 error "dd to $DIR/$tfile failed"
16751
16752         #force write to complete before dropping OST cache & checking memory
16753         sync
16754
16755         local total=$(facet_meminfo ost1 MemTotal)
16756         echo "Total memory: $total KiB"
16757
16758         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16759         local before_read=$(facet_meminfo ost1 Cached)
16760         echo "Cache used before read: $before_read KiB"
16761
16762         lfs ladvise -a willread $DIR/$tfile ||
16763                 error "Ladvise willread failed"
16764         local after_read=$(facet_meminfo ost1 Cached)
16765         echo "Cache used after read: $after_read KiB"
16766
16767         lfs ladvise -a dontneed $DIR/$tfile ||
16768                 error "Ladvise dontneed again failed"
16769         local no_read=$(facet_meminfo ost1 Cached)
16770         echo "Cache used after dontneed ladvise: $no_read KiB"
16771
16772         if [ $total -lt $((before_read + kibibytes)) ]; then
16773                 echo "Memory is too small, abort checking"
16774                 return 0
16775         fi
16776
16777         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16778                 error "Ladvise willread should use more memory" \
16779                         "than $kibibytes KiB"
16780         fi
16781
16782         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16783                 error "Ladvise dontneed should release more memory" \
16784                         "than $kibibytes KiB"
16785         fi
16786 }
16787 run_test 255b "check 'lfs ladvise -a dontneed'"
16788
16789 test_255c() {
16790         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16791                 skip "lustre < 2.10.53 does not support lockahead"
16792
16793         local count
16794         local new_count
16795         local difference
16796         local i
16797         local rc
16798
16799         test_mkdir -p $DIR/$tdir
16800         $LFS setstripe -i 0 $DIR/$tdir
16801
16802         #test 10 returns only success/failure
16803         i=10
16804         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16805         rc=$?
16806         if [ $rc -eq 255 ]; then
16807                 error "Ladvise test${i} failed, ${rc}"
16808         fi
16809
16810         #test 11 counts lock enqueue requests, all others count new locks
16811         i=11
16812         count=$(do_facet ost1 \
16813                 $LCTL get_param -n ost.OSS.ost.stats)
16814         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16815
16816         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16817         rc=$?
16818         if [ $rc -eq 255 ]; then
16819                 error "Ladvise test${i} failed, ${rc}"
16820         fi
16821
16822         new_count=$(do_facet ost1 \
16823                 $LCTL get_param -n ost.OSS.ost.stats)
16824         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16825                    awk '{ print $2 }')
16826
16827         difference="$((new_count - count))"
16828         if [ $difference -ne $rc ]; then
16829                 error "Ladvise test${i}, bad enqueue count, returned " \
16830                       "${rc}, actual ${difference}"
16831         fi
16832
16833         for i in $(seq 12 21); do
16834                 # If we do not do this, we run the risk of having too many
16835                 # locks and starting lock cancellation while we are checking
16836                 # lock counts.
16837                 cancel_lru_locks osc
16838
16839                 count=$($LCTL get_param -n \
16840                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16841
16842                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16843                 rc=$?
16844                 if [ $rc -eq 255 ]; then
16845                         error "Ladvise test ${i} failed, ${rc}"
16846                 fi
16847
16848                 new_count=$($LCTL get_param -n \
16849                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16850                 difference="$((new_count - count))"
16851
16852                 # Test 15 output is divided by 100 to map down to valid return
16853                 if [ $i -eq 15 ]; then
16854                         rc="$((rc * 100))"
16855                 fi
16856
16857                 if [ $difference -ne $rc ]; then
16858                         error "Ladvise test ${i}, bad lock count, returned " \
16859                               "${rc}, actual ${difference}"
16860                 fi
16861         done
16862
16863         #test 22 returns only success/failure
16864         i=22
16865         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16866         rc=$?
16867         if [ $rc -eq 255 ]; then
16868                 error "Ladvise test${i} failed, ${rc}"
16869         fi
16870 }
16871 run_test 255c "suite of ladvise lockahead tests"
16872
16873 test_256() {
16874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16875         remote_mds_nodsh && skip "remote MDS with nodsh"
16876         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16877         changelog_users $SINGLEMDS | grep "^cl" &&
16878                 skip "active changelog user"
16879
16880         local cl_user
16881         local cat_sl
16882         local mdt_dev
16883
16884         mdt_dev=$(mdsdevname 1)
16885         echo $mdt_dev
16886
16887         changelog_register || error "changelog_register failed"
16888
16889         rm -rf $DIR/$tdir
16890         mkdir -p $DIR/$tdir
16891
16892         changelog_clear 0 || error "changelog_clear failed"
16893
16894         # change something
16895         touch $DIR/$tdir/{1..10}
16896
16897         # stop the MDT
16898         stop $SINGLEMDS || error "Fail to stop MDT"
16899
16900         # remount the MDT
16901
16902         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16903
16904         #after mount new plainllog is used
16905         touch $DIR/$tdir/{11..19}
16906         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16907         cat_sl=$(do_facet $SINGLEMDS "sync; \
16908                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16909                  llog_reader $tmpfile | grep -c type=1064553b")
16910         do_facet $SINGLEMDS llog_reader $tmpfile
16911
16912         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16913
16914         changelog_clear 0 || error "changelog_clear failed"
16915
16916         cat_sl=$(do_facet $SINGLEMDS "sync; \
16917                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16918                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16919
16920         if (( cat_sl == 2 )); then
16921                 error "Empty plain llog was not deleted from changelog catalog"
16922         elif (( cat_sl != 1 )); then
16923                 error "Active plain llog shouldn't be deleted from catalog"
16924         fi
16925 }
16926 run_test 256 "Check llog delete for empty and not full state"
16927
16928 test_257() {
16929         remote_mds_nodsh && skip "remote MDS with nodsh"
16930         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16931                 skip "Need MDS version at least 2.8.55"
16932
16933         test_mkdir $DIR/$tdir
16934
16935         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16936                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16937         stat $DIR/$tdir
16938
16939 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16940         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16941         local facet=mds$((mdtidx + 1))
16942         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16943         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16944
16945         stop $facet || error "stop MDS failed"
16946         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16947                 error "start MDS fail"
16948         wait_recovery_complete $facet
16949 }
16950 run_test 257 "xattr locks are not lost"
16951
16952 # Verify we take the i_mutex when security requires it
16953 test_258a() {
16954 #define OBD_FAIL_IMUTEX_SEC 0x141c
16955         $LCTL set_param fail_loc=0x141c
16956         touch $DIR/$tfile
16957         chmod u+s $DIR/$tfile
16958         chmod a+rwx $DIR/$tfile
16959         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16960         RC=$?
16961         if [ $RC -ne 0 ]; then
16962                 error "error, failed to take i_mutex, rc=$?"
16963         fi
16964         rm -f $DIR/$tfile
16965 }
16966 run_test 258a
16967
16968 # Verify we do NOT take the i_mutex in the normal case
16969 test_258b() {
16970 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
16971         $LCTL set_param fail_loc=0x141d
16972         touch $DIR/$tfile
16973         chmod a+rwx $DIR
16974         chmod a+rw $DIR/$tfile
16975         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16976         RC=$?
16977         if [ $RC -ne 0 ]; then
16978                 error "error, took i_mutex unnecessarily, rc=$?"
16979         fi
16980         rm -f $DIR/$tfile
16981
16982 }
16983 run_test 258b "verify i_mutex security behavior"
16984
16985 test_259() {
16986         local file=$DIR/$tfile
16987         local before
16988         local after
16989
16990         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16991
16992         stack_trap "rm -f $file" EXIT
16993
16994         wait_delete_completed
16995         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16996         echo "before: $before"
16997
16998         $LFS setstripe -i 0 -c 1 $file
16999         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17000         sync_all_data
17001         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17002         echo "after write: $after"
17003
17004 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17005         do_facet ost1 $LCTL set_param fail_loc=0x2301
17006         $TRUNCATE $file 0
17007         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17008         echo "after truncate: $after"
17009
17010         stop ost1
17011         do_facet ost1 $LCTL set_param fail_loc=0
17012         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17013         sleep 2
17014         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17015         echo "after restart: $after"
17016         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17017                 error "missing truncate?"
17018
17019         return 0
17020 }
17021 run_test 259 "crash at delayed truncate"
17022
17023 test_260() {
17024 #define OBD_FAIL_MDC_CLOSE               0x806
17025         $LCTL set_param fail_loc=0x80000806
17026         touch $DIR/$tfile
17027
17028 }
17029 run_test 260 "Check mdc_close fail"
17030
17031 ### Data-on-MDT sanity tests ###
17032 test_270a() {
17033         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17034                 skip "Need MDS version at least 2.10.55 for DoM"
17035
17036         # create DoM file
17037         local dom=$DIR/$tdir/dom_file
17038         local tmp=$DIR/$tdir/tmp_file
17039
17040         mkdir -p $DIR/$tdir
17041
17042         # basic checks for DoM component creation
17043         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17044                 error "Can set MDT layout to non-first entry"
17045
17046         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17047                 error "Can define multiple entries as MDT layout"
17048
17049         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17050
17051         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17052         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17053         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17054
17055         local mdtidx=$($LFS getstripe -m $dom)
17056         local mdtname=MDT$(printf %04x $mdtidx)
17057         local facet=mds$((mdtidx + 1))
17058         local space_check=1
17059
17060         # Skip free space checks with ZFS
17061         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17062
17063         # write
17064         sync
17065         local size_tmp=$((65536 * 3))
17066         local mdtfree1=$(do_facet $facet \
17067                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17068
17069         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17070         # check also direct IO along write
17071         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17072         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17073         sync
17074         cmp $tmp $dom || error "file data is different"
17075         [ $(stat -c%s $dom) == $size_tmp ] ||
17076                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17077         if [ $space_check == 1 ]; then
17078                 local mdtfree2=$(do_facet $facet \
17079                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17080
17081                 # increase in usage from by $size_tmp
17082                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17083                         error "MDT free space wrong after write: " \
17084                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17085         fi
17086
17087         # truncate
17088         local size_dom=10000
17089
17090         $TRUNCATE $dom $size_dom
17091         [ $(stat -c%s $dom) == $size_dom ] ||
17092                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17093         if [ $space_check == 1 ]; then
17094                 mdtfree1=$(do_facet $facet \
17095                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17096                 # decrease in usage from $size_tmp to new $size_dom
17097                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17098                   $(((size_tmp - size_dom) / 1024)) ] ||
17099                         error "MDT free space is wrong after truncate: " \
17100                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17101         fi
17102
17103         # append
17104         cat $tmp >> $dom
17105         sync
17106         size_dom=$((size_dom + size_tmp))
17107         [ $(stat -c%s $dom) == $size_dom ] ||
17108                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17109         if [ $space_check == 1 ]; then
17110                 mdtfree2=$(do_facet $facet \
17111                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17112                 # increase in usage by $size_tmp from previous
17113                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17114                         error "MDT free space is wrong after append: " \
17115                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17116         fi
17117
17118         # delete
17119         rm $dom
17120         if [ $space_check == 1 ]; then
17121                 mdtfree1=$(do_facet $facet \
17122                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17123                 # decrease in usage by $size_dom from previous
17124                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17125                         error "MDT free space is wrong after removal: " \
17126                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17127         fi
17128
17129         # combined striping
17130         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17131                 error "Can't create DoM + OST striping"
17132
17133         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17134         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17135         # check also direct IO along write
17136         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17137         sync
17138         cmp $tmp $dom || error "file data is different"
17139         [ $(stat -c%s $dom) == $size_tmp ] ||
17140                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17141         rm $dom $tmp
17142
17143         return 0
17144 }
17145 run_test 270a "DoM: basic functionality tests"
17146
17147 test_270b() {
17148         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17149                 skip "Need MDS version at least 2.10.55"
17150
17151         local dom=$DIR/$tdir/dom_file
17152         local max_size=1048576
17153
17154         mkdir -p $DIR/$tdir
17155         $LFS setstripe -E $max_size -L mdt $dom
17156
17157         # truncate over the limit
17158         $TRUNCATE $dom $(($max_size + 1)) &&
17159                 error "successful truncate over the maximum size"
17160         # write over the limit
17161         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17162                 error "successful write over the maximum size"
17163         # append over the limit
17164         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17165         echo "12345" >> $dom && error "successful append over the maximum size"
17166         rm $dom
17167
17168         return 0
17169 }
17170 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17171
17172 test_270c() {
17173         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17174                 skip "Need MDS version at least 2.10.55"
17175
17176         mkdir -p $DIR/$tdir
17177         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17178
17179         # check files inherit DoM EA
17180         touch $DIR/$tdir/first
17181         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17182                 error "bad pattern"
17183         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17184                 error "bad stripe count"
17185         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17186                 error "bad stripe size"
17187
17188         # check directory inherits DoM EA and uses it as default
17189         mkdir $DIR/$tdir/subdir
17190         touch $DIR/$tdir/subdir/second
17191         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17192                 error "bad pattern in sub-directory"
17193         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17194                 error "bad stripe count in sub-directory"
17195         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17196                 error "bad stripe size in sub-directory"
17197         return 0
17198 }
17199 run_test 270c "DoM: DoM EA inheritance tests"
17200
17201 test_270d() {
17202         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17203                 skip "Need MDS version at least 2.10.55"
17204
17205         mkdir -p $DIR/$tdir
17206         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17207
17208         # inherit default DoM striping
17209         mkdir $DIR/$tdir/subdir
17210         touch $DIR/$tdir/subdir/f1
17211
17212         # change default directory striping
17213         $LFS setstripe -c 1 $DIR/$tdir/subdir
17214         touch $DIR/$tdir/subdir/f2
17215         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17216                 error "wrong default striping in file 2"
17217         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17218                 error "bad pattern in file 2"
17219         return 0
17220 }
17221 run_test 270d "DoM: change striping from DoM to RAID0"
17222
17223 test_270e() {
17224         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17225                 skip "Need MDS version at least 2.10.55"
17226
17227         mkdir -p $DIR/$tdir/dom
17228         mkdir -p $DIR/$tdir/norm
17229         DOMFILES=20
17230         NORMFILES=10
17231         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17232         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17233
17234         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17235         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17236
17237         # find DoM files by layout
17238         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17239         [ $NUM -eq  $DOMFILES ] ||
17240                 error "lfs find -L: found $NUM, expected $DOMFILES"
17241         echo "Test 1: lfs find 20 DOM files by layout: OK"
17242
17243         # there should be 1 dir with default DOM striping
17244         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17245         [ $NUM -eq  1 ] ||
17246                 error "lfs find -L: found $NUM, expected 1 dir"
17247         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17248
17249         # find DoM files by stripe size
17250         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17251         [ $NUM -eq  $DOMFILES ] ||
17252                 error "lfs find -S: found $NUM, expected $DOMFILES"
17253         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17254
17255         # find files by stripe offset except DoM files
17256         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17257         [ $NUM -eq  $NORMFILES ] ||
17258                 error "lfs find -i: found $NUM, expected $NORMFILES"
17259         echo "Test 5: lfs find no DOM files by stripe index: OK"
17260         return 0
17261 }
17262 run_test 270e "DoM: lfs find with DoM files test"
17263
17264 test_270f() {
17265         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17266                 skip "Need MDS version at least 2.10.55"
17267
17268         local mdtname=${FSNAME}-MDT0000-mdtlov
17269         local dom=$DIR/$tdir/dom_file
17270         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17271                                                 lod.$mdtname.dom_stripesize)
17272         local dom_limit=131072
17273
17274         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17275         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17276                                                 lod.$mdtname.dom_stripesize)
17277         [ ${dom_limit} -eq ${dom_current} ] ||
17278                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17279
17280         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17281         $LFS setstripe -d $DIR/$tdir
17282         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17283                 error "Can't set directory default striping"
17284
17285         # exceed maximum stripe size
17286         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17287                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17288         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17289                 error "Able to create DoM component size more than LOD limit"
17290
17291         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17292         dom_current=$(do_facet mds1 $LCTL get_param -n \
17293                                                 lod.$mdtname.dom_stripesize)
17294         [ 0 -eq ${dom_current} ] ||
17295                 error "Can't set zero DoM stripe limit"
17296         rm $dom
17297
17298         # attempt to create DoM file on server with disabled DoM should
17299         # remove DoM entry from layout and be succeed
17300         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17301                 error "Can't create DoM file (DoM is disabled)"
17302         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17303                 error "File has DoM component while DoM is disabled"
17304         rm $dom
17305
17306         # attempt to create DoM file with only DoM stripe should return error
17307         $LFS setstripe -E $dom_limit -L mdt $dom &&
17308                 error "Able to create DoM-only file while DoM is disabled"
17309
17310         # too low values to be aligned with smallest stripe size 64K
17311         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17312         dom_current=$(do_facet mds1 $LCTL get_param -n \
17313                                                 lod.$mdtname.dom_stripesize)
17314         [ 30000 -eq ${dom_current} ] &&
17315                 error "Can set too small DoM stripe limit"
17316
17317         # 64K is a minimal stripe size in Lustre, expect limit of that size
17318         [ 65536 -eq ${dom_current} ] ||
17319                 error "Limit is not set to 64K but ${dom_current}"
17320
17321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17322         dom_current=$(do_facet mds1 $LCTL get_param -n \
17323                                                 lod.$mdtname.dom_stripesize)
17324         echo $dom_current
17325         [ 2147483648 -eq ${dom_current} ] &&
17326                 error "Can set too large DoM stripe limit"
17327
17328         do_facet mds1 $LCTL set_param -n \
17329                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17330         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17331                 error "Can't create DoM component size after limit change"
17332         do_facet mds1 $LCTL set_param -n \
17333                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17334         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17335                 error "Can't create DoM file after limit decrease"
17336         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17337                 error "Can create big DoM component after limit decrease"
17338         touch ${dom}_def ||
17339                 error "Can't create file with old default layout"
17340
17341         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17342         return 0
17343 }
17344 run_test 270f "DoM: maximum DoM stripe size checks"
17345
17346 test_271a() {
17347         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17348                 skip "Need MDS version at least 2.10.55"
17349
17350         local dom=$DIR/$tdir/dom
17351
17352         mkdir -p $DIR/$tdir
17353
17354         $LFS setstripe -E 1024K -L mdt $dom
17355
17356         lctl set_param -n mdc.*.stats=clear
17357         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17358         cat $dom > /dev/null
17359         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17360         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17361         ls $dom
17362         rm -f $dom
17363 }
17364 run_test 271a "DoM: data is cached for read after write"
17365
17366 test_271b() {
17367         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17368                 skip "Need MDS version at least 2.10.55"
17369
17370         local dom=$DIR/$tdir/dom
17371
17372         mkdir -p $DIR/$tdir
17373
17374         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17375
17376         lctl set_param -n mdc.*.stats=clear
17377         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17378         cancel_lru_locks mdc
17379         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17380         # second stat to check size is cached on client
17381         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17382         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17383         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17384         rm -f $dom
17385 }
17386 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17387
17388 test_271ba() {
17389         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17390                 skip "Need MDS version at least 2.10.55"
17391
17392         local dom=$DIR/$tdir/dom
17393
17394         mkdir -p $DIR/$tdir
17395
17396         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17397
17398         lctl set_param -n mdc.*.stats=clear
17399         lctl set_param -n osc.*.stats=clear
17400         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17401         cancel_lru_locks mdc
17402         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17403         # second stat to check size is cached on client
17404         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17405         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17406         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17407         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17408         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17409         rm -f $dom
17410 }
17411 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17412
17413
17414 get_mdc_stats() {
17415         local mdtidx=$1
17416         local param=$2
17417         local mdt=MDT$(printf %04x $mdtidx)
17418
17419         if [ -z $param ]; then
17420                 lctl get_param -n mdc.*$mdt*.stats
17421         else
17422                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17423         fi
17424 }
17425
17426 test_271c() {
17427         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17428                 skip "Need MDS version at least 2.10.55"
17429
17430         local dom=$DIR/$tdir/dom
17431
17432         mkdir -p $DIR/$tdir
17433
17434         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17435
17436         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17437         local facet=mds$((mdtidx + 1))
17438
17439         cancel_lru_locks mdc
17440         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17441         createmany -o $dom 1000
17442         lctl set_param -n mdc.*.stats=clear
17443         smalliomany -w $dom 1000 200
17444         get_mdc_stats $mdtidx
17445         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17446         # Each file has 1 open, 1 IO enqueues, total 2000
17447         # but now we have also +1 getxattr for security.capability, total 3000
17448         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17449         unlinkmany $dom 1000
17450
17451         cancel_lru_locks mdc
17452         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17453         createmany -o $dom 1000
17454         lctl set_param -n mdc.*.stats=clear
17455         smalliomany -w $dom 1000 200
17456         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17457         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17458         # for OPEN and IO lock.
17459         [ $((enq - enq_2)) -ge 1000 ] ||
17460                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17461         unlinkmany $dom 1000
17462         return 0
17463 }
17464 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17465
17466 cleanup_271def_tests() {
17467         trap 0
17468         rm -f $1
17469 }
17470
17471 test_271d() {
17472         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17473                 skip "Need MDS version at least 2.10.57"
17474
17475         local dom=$DIR/$tdir/dom
17476         local tmp=$TMP/$tfile
17477         trap "cleanup_271def_tests $tmp" EXIT
17478
17479         mkdir -p $DIR/$tdir
17480
17481         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17482
17483         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17484
17485         cancel_lru_locks mdc
17486         dd if=/dev/urandom of=$tmp bs=1000 count=1
17487         dd if=$tmp of=$dom bs=1000 count=1
17488         cancel_lru_locks mdc
17489
17490         cat /etc/hosts >> $tmp
17491         lctl set_param -n mdc.*.stats=clear
17492
17493         # append data to the same file it should update local page
17494         echo "Append to the same page"
17495         cat /etc/hosts >> $dom
17496         local num=$(get_mdc_stats $mdtidx ost_read)
17497         local ra=$(get_mdc_stats $mdtidx req_active)
17498         local rw=$(get_mdc_stats $mdtidx req_waittime)
17499
17500         [ -z $num ] || error "$num READ RPC occured"
17501         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17502         echo "... DONE"
17503
17504         # compare content
17505         cmp $tmp $dom || error "file miscompare"
17506
17507         cancel_lru_locks mdc
17508         lctl set_param -n mdc.*.stats=clear
17509
17510         echo "Open and read file"
17511         cat $dom > /dev/null
17512         local num=$(get_mdc_stats $mdtidx ost_read)
17513         local ra=$(get_mdc_stats $mdtidx req_active)
17514         local rw=$(get_mdc_stats $mdtidx req_waittime)
17515
17516         [ -z $num ] || error "$num READ RPC occured"
17517         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17518         echo "... DONE"
17519
17520         # compare content
17521         cmp $tmp $dom || error "file miscompare"
17522
17523         return 0
17524 }
17525 run_test 271d "DoM: read on open (1K file in reply buffer)"
17526
17527 test_271e() {
17528         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17529                 skip "Need MDS version at least 2.10.57"
17530
17531         local dom=$DIR/$tdir/dom
17532         local tmp=$TMP/${tfile}.data
17533         trap "cleanup_271def_tests $tmp" EXIT
17534
17535         mkdir -p $DIR/$tdir
17536
17537         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17538
17539         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17540
17541         cancel_lru_locks mdc
17542         dd if=/dev/urandom of=$tmp bs=30K count=1
17543         dd if=$tmp of=$dom bs=30K count=1
17544         cancel_lru_locks mdc
17545         cat /etc/hosts >> $tmp
17546         lctl set_param -n mdc.*.stats=clear
17547
17548         echo "Append to the same page"
17549         cat /etc/hosts >> $dom
17550
17551         local num=$(get_mdc_stats $mdtidx ost_read)
17552         local ra=$(get_mdc_stats $mdtidx req_active)
17553         local rw=$(get_mdc_stats $mdtidx req_waittime)
17554
17555         [ -z $num ] || error "$num READ RPC occured"
17556         # Reply buffer can be adjusted for larger buffer by resend
17557         echo "... DONE with $((ra - rw)) resends"
17558
17559         # compare content
17560         cmp $tmp $dom || error "file miscompare"
17561
17562         cancel_lru_locks mdc
17563         lctl set_param -n mdc.*.stats=clear
17564
17565         echo "Open and read file"
17566         cat $dom > /dev/null
17567         local num=$(get_mdc_stats $mdtidx ost_read)
17568         local ra=$(get_mdc_stats $mdtidx req_active)
17569         local rw=$(get_mdc_stats $mdtidx req_waittime)
17570
17571         [ -z $num ] || error "$num READ RPC occured"
17572         # Reply buffer can be adjusted for larger buffer by resend
17573         echo "... DONE with $((ra - rw)) resends"
17574
17575         # compare content
17576         cmp $tmp $dom || error "file miscompare"
17577
17578         return 0
17579 }
17580 run_test 271e "DoM: read on open (30K file with reply buffer adjusting)"
17581
17582 test_271f() {
17583         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17584                 skip "Need MDS version at least 2.10.57"
17585
17586         local dom=$DIR/$tdir/dom
17587         local tmp=$TMP/$tfile
17588         trap "cleanup_271def_tests $tmp" EXIT
17589
17590         mkdir -p $DIR/$tdir
17591
17592         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17593
17594         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17595
17596         cancel_lru_locks mdc
17597         dd if=/dev/urandom of=$tmp bs=200000 count=1
17598         dd if=$tmp of=$dom bs=200000 count=1
17599         cancel_lru_locks mdc
17600         cat /etc/hosts >> $tmp
17601         lctl set_param -n mdc.*.stats=clear
17602
17603         echo "Append to the same page"
17604         cat /etc/hosts >> $dom
17605         local num=$(get_mdc_stats $mdtidx ost_read)
17606         local ra=$(get_mdc_stats $mdtidx req_active)
17607         local rw=$(get_mdc_stats $mdtidx req_waittime)
17608
17609         [ -z $num ] || error "$num READ RPC occured"
17610         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17611         echo "... DONE"
17612
17613         # compare content
17614         cmp $tmp $dom || error "file miscompare"
17615
17616         cancel_lru_locks mdc
17617         lctl set_param -n mdc.*.stats=clear
17618
17619         echo "Open and read file"
17620         cat $dom > /dev/null
17621         local num=$(get_mdc_stats $mdtidx ost_read)
17622         local ra=$(get_mdc_stats $mdtidx req_active)
17623         local rw=$(get_mdc_stats $mdtidx req_waittime)
17624
17625         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17626         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17627         echo "... DONE"
17628
17629         # compare content
17630         cmp $tmp $dom || error "file miscompare"
17631
17632         return 0
17633 }
17634 run_test 271f "DoM: read on open (200K file and read tail)"
17635
17636 test_272a() {
17637         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17638                 skip "Need MDS version at least 2.11.50"
17639
17640         local dom=$DIR/$tdir/dom
17641         mkdir -p $DIR/$tdir
17642
17643         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17644         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17645                 error "failed to write data into $dom"
17646         local old_md5=$(md5sum $dom)
17647
17648         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17649                 error "failed to migrate to the same DoM component"
17650
17651         local new_md5=$(md5sum $dom)
17652
17653         [ "$old_md5" == "$new_md5" ] ||
17654                 error "md5sum differ: $old_md5, $new_md5"
17655
17656         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17657                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17658 }
17659 run_test 272a "DoM migration: new layout with the same DOM component"
17660
17661 test_272b() {
17662         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17663                 skip "Need MDS version at least 2.11.50"
17664
17665         local dom=$DIR/$tdir/dom
17666         mkdir -p $DIR/$tdir
17667         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17668
17669         local mdtidx=$($LFS getstripe -m $dom)
17670         local mdtname=MDT$(printf %04x $mdtidx)
17671         local facet=mds$((mdtidx + 1))
17672
17673         local mdtfree1=$(do_facet $facet \
17674                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17675         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17676                 error "failed to write data into $dom"
17677         local old_md5=$(md5sum $dom)
17678         cancel_lru_locks mdc
17679         local mdtfree1=$(do_facet $facet \
17680                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17681
17682         $LFS migrate -c2 $dom ||
17683                 error "failed to migrate to the new composite layout"
17684         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17685                 error "MDT stripe was not removed"
17686
17687         cancel_lru_locks mdc
17688         local new_md5=$(md5sum $dom)
17689         [ "$old_md5" != "$new_md5" ] &&
17690                 error "$old_md5 != $new_md5"
17691
17692         # Skip free space checks with ZFS
17693         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17694                 local mdtfree2=$(do_facet $facet \
17695                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17696                 [ $mdtfree2 -gt $mdtfree1 ] ||
17697                         error "MDT space is not freed after migration"
17698         fi
17699         return 0
17700 }
17701 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17702
17703 test_272c() {
17704         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17705                 skip "Need MDS version at least 2.11.50"
17706
17707         local dom=$DIR/$tdir/$tfile
17708         mkdir -p $DIR/$tdir
17709         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17710
17711         local mdtidx=$($LFS getstripe -m $dom)
17712         local mdtname=MDT$(printf %04x $mdtidx)
17713         local facet=mds$((mdtidx + 1))
17714
17715         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17716                 error "failed to write data into $dom"
17717         local old_md5=$(md5sum $dom)
17718         cancel_lru_locks mdc
17719         local mdtfree1=$(do_facet $facet \
17720                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17721
17722         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17723                 error "failed to migrate to the new composite layout"
17724         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17725                 error "MDT stripe was not removed"
17726
17727         cancel_lru_locks mdc
17728         local new_md5=$(md5sum $dom)
17729         [ "$old_md5" != "$new_md5" ] &&
17730                 error "$old_md5 != $new_md5"
17731
17732         # Skip free space checks with ZFS
17733         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17734                 local mdtfree2=$(do_facet $facet \
17735                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17736                 [ $mdtfree2 -gt $mdtfree1 ] ||
17737                         error "MDS space is not freed after migration"
17738         fi
17739         return 0
17740 }
17741 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17742
17743 test_273a() {
17744         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17745                 skip "Need MDS version at least 2.11.50"
17746
17747         # Layout swap cannot be done if either file has DOM component,
17748         # this will never be supported, migration should be used instead
17749
17750         local dom=$DIR/$tdir/$tfile
17751         mkdir -p $DIR/$tdir
17752
17753         $LFS setstripe -c2 ${dom}_plain
17754         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17755         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17756                 error "can swap layout with DoM component"
17757         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17758                 error "can swap layout with DoM component"
17759
17760         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17761         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17762                 error "can swap layout with DoM component"
17763         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17764                 error "can swap layout with DoM component"
17765         return 0
17766 }
17767 run_test 273a "DoM: layout swapping should fail with DOM"
17768
17769 test_275() {
17770         remote_ost_nodsh && skip "remote OST with nodsh"
17771         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17772                 skip "Need OST version >= 2.10.57"
17773
17774         local file=$DIR/$tfile
17775         local oss
17776
17777         oss=$(comma_list $(osts_nodes))
17778
17779         dd if=/dev/urandom of=$file bs=1M count=2 ||
17780                 error "failed to create a file"
17781         cancel_lru_locks osc
17782
17783         #lock 1
17784         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17785                 error "failed to read a file"
17786
17787 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17788         $LCTL set_param fail_loc=0x8000031f
17789
17790         cancel_lru_locks osc &
17791         sleep 1
17792
17793 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17794         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17795         #IO takes another lock, but matches the PENDING one
17796         #and places it to the IO RPC
17797         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17798                 error "failed to read a file with PENDING lock"
17799 }
17800 run_test 275 "Read on a canceled duplicate lock"
17801
17802 test_276() {
17803         remote_ost_nodsh && skip "remote OST with nodsh"
17804         local pid
17805
17806         do_facet ost1 "(while true; do \
17807                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17808                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17809         pid=$!
17810
17811         for LOOP in $(seq 20); do
17812                 stop ost1
17813                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17814         done
17815         kill -9 $pid
17816         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17817                 rm $TMP/sanity_276_pid"
17818 }
17819 run_test 276 "Race between mount and obd_statfs"
17820
17821 cleanup_test_300() {
17822         trap 0
17823         umask $SAVE_UMASK
17824 }
17825 test_striped_dir() {
17826         local mdt_index=$1
17827         local stripe_count
17828         local stripe_index
17829
17830         mkdir -p $DIR/$tdir
17831
17832         SAVE_UMASK=$(umask)
17833         trap cleanup_test_300 RETURN EXIT
17834
17835         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17836                                                 $DIR/$tdir/striped_dir ||
17837                 error "set striped dir error"
17838
17839         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17840         [ "$mode" = "755" ] || error "expect 755 got $mode"
17841
17842         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17843                 error "getdirstripe failed"
17844         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17845         if [ "$stripe_count" != "2" ]; then
17846                 error "1:stripe_count is $stripe_count, expect 2"
17847         fi
17848         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17849         if [ "$stripe_count" != "2" ]; then
17850                 error "2:stripe_count is $stripe_count, expect 2"
17851         fi
17852
17853         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17854         if [ "$stripe_index" != "$mdt_index" ]; then
17855                 error "stripe_index is $stripe_index, expect $mdt_index"
17856         fi
17857
17858         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17859                 error "nlink error after create striped dir"
17860
17861         mkdir $DIR/$tdir/striped_dir/a
17862         mkdir $DIR/$tdir/striped_dir/b
17863
17864         stat $DIR/$tdir/striped_dir/a ||
17865                 error "create dir under striped dir failed"
17866         stat $DIR/$tdir/striped_dir/b ||
17867                 error "create dir under striped dir failed"
17868
17869         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17870                 error "nlink error after mkdir"
17871
17872         rmdir $DIR/$tdir/striped_dir/a
17873         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17874                 error "nlink error after rmdir"
17875
17876         rmdir $DIR/$tdir/striped_dir/b
17877         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17878                 error "nlink error after rmdir"
17879
17880         chattr +i $DIR/$tdir/striped_dir
17881         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17882                 error "immutable flags not working under striped dir!"
17883         chattr -i $DIR/$tdir/striped_dir
17884
17885         rmdir $DIR/$tdir/striped_dir ||
17886                 error "rmdir striped dir error"
17887
17888         cleanup_test_300
17889
17890         true
17891 }
17892
17893 test_300a() {
17894         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17895                 skip "skipped for lustre < 2.7.0"
17896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17897         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17898
17899         test_striped_dir 0 || error "failed on striped dir on MDT0"
17900         test_striped_dir 1 || error "failed on striped dir on MDT0"
17901 }
17902 run_test 300a "basic striped dir sanity test"
17903
17904 test_300b() {
17905         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17906                 skip "skipped for lustre < 2.7.0"
17907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17909
17910         local i
17911         local mtime1
17912         local mtime2
17913         local mtime3
17914
17915         test_mkdir $DIR/$tdir || error "mkdir fail"
17916         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17917                 error "set striped dir error"
17918         for i in {0..9}; do
17919                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17920                 sleep 1
17921                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17922                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17923                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17924                 sleep 1
17925                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17926                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17927                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17928         done
17929         true
17930 }
17931 run_test 300b "check ctime/mtime for striped dir"
17932
17933 test_300c() {
17934         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17935                 skip "skipped for lustre < 2.7.0"
17936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17937         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17938
17939         local file_count
17940
17941         mkdir -p $DIR/$tdir
17942         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17943                 error "set striped dir error"
17944
17945         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17946                 error "chown striped dir failed"
17947
17948         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17949                 error "create 5k files failed"
17950
17951         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17952
17953         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17954
17955         rm -rf $DIR/$tdir
17956 }
17957 run_test 300c "chown && check ls under striped directory"
17958
17959 test_300d() {
17960         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17961                 skip "skipped for lustre < 2.7.0"
17962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17964
17965         local stripe_count
17966         local file
17967
17968         mkdir -p $DIR/$tdir
17969         $LFS setstripe -c 2 $DIR/$tdir
17970
17971         #local striped directory
17972         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17973                 error "set striped dir error"
17974         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17975                 error "create 10 files failed"
17976
17977         #remote striped directory
17978         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17979                 error "set striped dir error"
17980         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17981                 error "create 10 files failed"
17982
17983         for file in $(find $DIR/$tdir); do
17984                 stripe_count=$($LFS getstripe -c $file)
17985                 [ $stripe_count -eq 2 ] ||
17986                         error "wrong stripe $stripe_count for $file"
17987         done
17988
17989         rm -rf $DIR/$tdir
17990 }
17991 run_test 300d "check default stripe under striped directory"
17992
17993 test_300e() {
17994         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17995                 skip "Need MDS version at least 2.7.55"
17996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17998
17999         local stripe_count
18000         local file
18001
18002         mkdir -p $DIR/$tdir
18003
18004         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18005                 error "set striped dir error"
18006
18007         touch $DIR/$tdir/striped_dir/a
18008         touch $DIR/$tdir/striped_dir/b
18009         touch $DIR/$tdir/striped_dir/c
18010
18011         mkdir $DIR/$tdir/striped_dir/dir_a
18012         mkdir $DIR/$tdir/striped_dir/dir_b
18013         mkdir $DIR/$tdir/striped_dir/dir_c
18014
18015         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18016                 error "set striped adir under striped dir error"
18017
18018         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18019                 error "set striped bdir under striped dir error"
18020
18021         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18022                 error "set striped cdir under striped dir error"
18023
18024         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18025                 error "rename dir under striped dir fails"
18026
18027         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18028                 error "rename dir under different stripes fails"
18029
18030         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18031                 error "rename file under striped dir should succeed"
18032
18033         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18034                 error "rename dir under striped dir should succeed"
18035
18036         rm -rf $DIR/$tdir
18037 }
18038 run_test 300e "check rename under striped directory"
18039
18040 test_300f() {
18041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18043         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18044                 skip "Need MDS version at least 2.7.55"
18045
18046         local stripe_count
18047         local file
18048
18049         rm -rf $DIR/$tdir
18050         mkdir -p $DIR/$tdir
18051
18052         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18053                 error "set striped dir error"
18054
18055         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18056                 error "set striped dir error"
18057
18058         touch $DIR/$tdir/striped_dir/a
18059         mkdir $DIR/$tdir/striped_dir/dir_a
18060         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18061                 error "create striped dir under striped dir fails"
18062
18063         touch $DIR/$tdir/striped_dir1/b
18064         mkdir $DIR/$tdir/striped_dir1/dir_b
18065         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18066                 error "create striped dir under striped dir fails"
18067
18068         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18069                 error "rename dir under different striped dir should fail"
18070
18071         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18072                 error "rename striped dir under diff striped dir should fail"
18073
18074         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18075                 error "rename file under diff striped dirs fails"
18076
18077         rm -rf $DIR/$tdir
18078 }
18079 run_test 300f "check rename cross striped directory"
18080
18081 test_300_check_default_striped_dir()
18082 {
18083         local dirname=$1
18084         local default_count=$2
18085         local default_index=$3
18086         local stripe_count
18087         local stripe_index
18088         local dir_stripe_index
18089         local dir
18090
18091         echo "checking $dirname $default_count $default_index"
18092         $LFS setdirstripe -D -c $default_count -i $default_index \
18093                                 -t all_char $DIR/$tdir/$dirname ||
18094                 error "set default stripe on striped dir error"
18095         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18096         [ $stripe_count -eq $default_count ] ||
18097                 error "expect $default_count get $stripe_count for $dirname"
18098
18099         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18100         [ $stripe_index -eq $default_index ] ||
18101                 error "expect $default_index get $stripe_index for $dirname"
18102
18103         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18104                                                 error "create dirs failed"
18105
18106         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18107         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18108         for dir in $(find $DIR/$tdir/$dirname/*); do
18109                 stripe_count=$($LFS getdirstripe -c $dir)
18110                 [ $stripe_count -eq $default_count ] ||
18111                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
18112                 error "stripe count $default_count != $stripe_count for $dir"
18113
18114                 stripe_index=$($LFS getdirstripe -i $dir)
18115                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
18116                         error "$stripe_index != $default_index for $dir"
18117
18118                 #check default stripe
18119                 stripe_count=$($LFS getdirstripe -D -c $dir)
18120                 [ $stripe_count -eq $default_count ] ||
18121                 error "default count $default_count != $stripe_count for $dir"
18122
18123                 stripe_index=$($LFS getdirstripe -D -i $dir)
18124                 [ $stripe_index -eq $default_index ] ||
18125                 error "default index $default_index != $stripe_index for $dir"
18126         done
18127         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18128 }
18129
18130 test_300g() {
18131         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18132         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18133                 skip "Need MDS version at least 2.7.55"
18134
18135         local dir
18136         local stripe_count
18137         local stripe_index
18138
18139         mkdir $DIR/$tdir
18140         mkdir $DIR/$tdir/normal_dir
18141
18142         #Checking when client cache stripe index
18143         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18144         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18145                 error "create striped_dir failed"
18146
18147         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18148                 error "create dir0 fails"
18149         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18150         [ $stripe_index -eq 0 ] ||
18151                 error "dir0 expect index 0 got $stripe_index"
18152
18153         mkdir $DIR/$tdir/striped_dir/dir1 ||
18154                 error "create dir1 fails"
18155         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18156         [ $stripe_index -eq 1 ] ||
18157                 error "dir1 expect index 1 got $stripe_index"
18158
18159         #check default stripe count/stripe index
18160         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18161         test_300_check_default_striped_dir normal_dir 1 0
18162         test_300_check_default_striped_dir normal_dir 2 1
18163         test_300_check_default_striped_dir normal_dir 2 -1
18164
18165         #delete default stripe information
18166         echo "delete default stripeEA"
18167         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18168                 error "set default stripe on striped dir error"
18169
18170         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18171         for dir in $(find $DIR/$tdir/normal_dir/*); do
18172                 stripe_count=$($LFS getdirstripe -c $dir)
18173                 [ $stripe_count -eq 0 ] ||
18174                         error "expect 1 get $stripe_count for $dir"
18175                 stripe_index=$($LFS getdirstripe -i $dir)
18176                 [ $stripe_index -eq 0 ] ||
18177                         error "expect 0 get $stripe_index for $dir"
18178         done
18179 }
18180 run_test 300g "check default striped directory for normal directory"
18181
18182 test_300h() {
18183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18184         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18185                 skip "Need MDS version at least 2.7.55"
18186
18187         local dir
18188         local stripe_count
18189
18190         mkdir $DIR/$tdir
18191         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18192                 error "set striped dir error"
18193
18194         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18195         test_300_check_default_striped_dir striped_dir 1 0
18196         test_300_check_default_striped_dir striped_dir 2 1
18197         test_300_check_default_striped_dir striped_dir 2 -1
18198
18199         #delete default stripe information
18200         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18201                 error "set default stripe on striped dir error"
18202
18203         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18204         for dir in $(find $DIR/$tdir/striped_dir/*); do
18205                 stripe_count=$($LFS getdirstripe -c $dir)
18206                 [ $stripe_count -eq 0 ] ||
18207                         error "expect 1 get $stripe_count for $dir"
18208         done
18209 }
18210 run_test 300h "check default striped directory for striped directory"
18211
18212 test_300i() {
18213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18214         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18215         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18216                 skip "Need MDS version at least 2.7.55"
18217
18218         local stripe_count
18219         local file
18220
18221         mkdir $DIR/$tdir
18222
18223         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18224                 error "set striped dir error"
18225
18226         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18227                 error "create files under striped dir failed"
18228
18229         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18230                 error "set striped hashdir error"
18231
18232         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18233                 error "create dir0 under hash dir failed"
18234         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18235                 error "create dir1 under hash dir failed"
18236
18237         # unfortunately, we need to umount to clear dir layout cache for now
18238         # once we fully implement dir layout, we can drop this
18239         umount_client $MOUNT || error "umount failed"
18240         mount_client $MOUNT || error "mount failed"
18241
18242         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18243         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18244         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18245
18246         #set the stripe to be unknown hash type
18247         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18248         $LCTL set_param fail_loc=0x1901
18249         for ((i = 0; i < 10; i++)); do
18250                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18251                         error "stat f-$i failed"
18252                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18253         done
18254
18255         touch $DIR/$tdir/striped_dir/f0 &&
18256                 error "create under striped dir with unknown hash should fail"
18257
18258         $LCTL set_param fail_loc=0
18259
18260         umount_client $MOUNT || error "umount failed"
18261         mount_client $MOUNT || error "mount failed"
18262
18263         return 0
18264 }
18265 run_test 300i "client handle unknown hash type striped directory"
18266
18267 test_300j() {
18268         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18270         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18271                 skip "Need MDS version at least 2.7.55"
18272
18273         local stripe_count
18274         local file
18275
18276         mkdir $DIR/$tdir
18277
18278         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18279         $LCTL set_param fail_loc=0x1702
18280         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18281                 error "set striped dir error"
18282
18283         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18284                 error "create files under striped dir failed"
18285
18286         $LCTL set_param fail_loc=0
18287
18288         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18289
18290         return 0
18291 }
18292 run_test 300j "test large update record"
18293
18294 test_300k() {
18295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18296         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18297         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18298                 skip "Need MDS version at least 2.7.55"
18299
18300         # this test needs a huge transaction
18301         local kb
18302         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18303         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18304
18305         local stripe_count
18306         local file
18307
18308         mkdir $DIR/$tdir
18309
18310         #define OBD_FAIL_LARGE_STRIPE   0x1703
18311         $LCTL set_param fail_loc=0x1703
18312         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18313                 error "set striped dir error"
18314         $LCTL set_param fail_loc=0
18315
18316         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18317                 error "getstripeddir fails"
18318         rm -rf $DIR/$tdir/striped_dir ||
18319                 error "unlink striped dir fails"
18320
18321         return 0
18322 }
18323 run_test 300k "test large striped directory"
18324
18325 test_300l() {
18326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18328         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18329                 skip "Need MDS version at least 2.7.55"
18330
18331         local stripe_index
18332
18333         test_mkdir -p $DIR/$tdir/striped_dir
18334         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18335                         error "chown $RUNAS_ID failed"
18336         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18337                 error "set default striped dir failed"
18338
18339         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18340         $LCTL set_param fail_loc=0x80000158
18341         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18342
18343         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18344         [ $stripe_index -eq 1 ] ||
18345                 error "expect 1 get $stripe_index for $dir"
18346 }
18347 run_test 300l "non-root user to create dir under striped dir with stale layout"
18348
18349 test_300m() {
18350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18351         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18352         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18353                 skip "Need MDS version at least 2.7.55"
18354
18355         mkdir -p $DIR/$tdir/striped_dir
18356         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18357                 error "set default stripes dir error"
18358
18359         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18360
18361         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18362         [ $stripe_count -eq 0 ] ||
18363                         error "expect 0 get $stripe_count for a"
18364
18365         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18366                 error "set default stripes dir error"
18367
18368         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18369
18370         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18371         [ $stripe_count -eq 0 ] ||
18372                         error "expect 0 get $stripe_count for b"
18373
18374         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18375                 error "set default stripes dir error"
18376
18377         mkdir $DIR/$tdir/striped_dir/c &&
18378                 error "default stripe_index is invalid, mkdir c should fails"
18379
18380         rm -rf $DIR/$tdir || error "rmdir fails"
18381 }
18382 run_test 300m "setstriped directory on single MDT FS"
18383
18384 cleanup_300n() {
18385         local list=$(comma_list $(mdts_nodes))
18386
18387         trap 0
18388         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18389 }
18390
18391 test_300n() {
18392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18394         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18395                 skip "Need MDS version at least 2.7.55"
18396         remote_mds_nodsh && skip "remote MDS with nodsh"
18397
18398         local stripe_index
18399         local list=$(comma_list $(mdts_nodes))
18400
18401         trap cleanup_300n RETURN EXIT
18402         mkdir -p $DIR/$tdir
18403         chmod 777 $DIR/$tdir
18404         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18405                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18406                 error "create striped dir succeeds with gid=0"
18407
18408         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18409         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18410                 error "create striped dir fails with gid=-1"
18411
18412         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18413         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18414                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18415                 error "set default striped dir succeeds with gid=0"
18416
18417
18418         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18419         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18420                 error "set default striped dir fails with gid=-1"
18421
18422
18423         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18424         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18425                                         error "create test_dir fails"
18426         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18427                                         error "create test_dir1 fails"
18428         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18429                                         error "create test_dir2 fails"
18430         cleanup_300n
18431 }
18432 run_test 300n "non-root user to create dir under striped dir with default EA"
18433
18434 test_300o() {
18435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18437         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18438                 skip "Need MDS version at least 2.7.55"
18439
18440         local numfree1
18441         local numfree2
18442
18443         mkdir -p $DIR/$tdir
18444
18445         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18446         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18447         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
18448                 skip "not enough free inodes $numfree1 $numfree2"
18449         fi
18450
18451         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18452         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18453         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
18454                 skip "not enough free space $numfree1 $numfree2"
18455         fi
18456
18457         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18458                 error "setdirstripe fails"
18459
18460         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18461                 error "create dirs fails"
18462
18463         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18464         ls $DIR/$tdir/striped_dir > /dev/null ||
18465                 error "ls striped dir fails"
18466         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18467                 error "unlink big striped dir fails"
18468 }
18469 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18470
18471 test_300p() {
18472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18474         remote_mds_nodsh && skip "remote MDS with nodsh"
18475
18476         mkdir -p $DIR/$tdir
18477
18478         #define OBD_FAIL_OUT_ENOSPC     0x1704
18479         do_facet mds2 lctl set_param fail_loc=0x80001704
18480         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18481                  && error "create striped directory should fail"
18482
18483         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18484
18485         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18486         true
18487 }
18488 run_test 300p "create striped directory without space"
18489
18490 test_300q() {
18491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18493
18494         local fd=$(free_fd)
18495         local cmd="exec $fd<$tdir"
18496         cd $DIR
18497         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18498         eval $cmd
18499         cmd="exec $fd<&-"
18500         trap "eval $cmd" EXIT
18501         cd $tdir || error "cd $tdir fails"
18502         rmdir  ../$tdir || error "rmdir $tdir fails"
18503         mkdir local_dir && error "create dir succeeds"
18504         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18505         eval $cmd
18506         return 0
18507 }
18508 run_test 300q "create remote directory under orphan directory"
18509
18510 test_300r() {
18511         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18512                 skip "Need MDS version at least 2.7.55" && return
18513         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18514
18515         mkdir $DIR/$tdir
18516
18517         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18518                 error "set striped dir error"
18519
18520         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18521                 error "getstripeddir fails"
18522
18523         local stripe_count
18524         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18525                       awk '/lmv_stripe_count:/ { print $2 }')
18526
18527         [ $MDSCOUNT -ne $stripe_count ] &&
18528                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18529
18530         rm -rf $DIR/$tdir/striped_dir ||
18531                 error "unlink striped dir fails"
18532 }
18533 run_test 300r "test -1 striped directory"
18534
18535 prepare_remote_file() {
18536         mkdir $DIR/$tdir/src_dir ||
18537                 error "create remote source failed"
18538
18539         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18540                  error "cp to remote source failed"
18541         touch $DIR/$tdir/src_dir/a
18542
18543         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18544                 error "create remote target dir failed"
18545
18546         touch $DIR/$tdir/tgt_dir/b
18547
18548         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18549                 error "rename dir cross MDT failed!"
18550
18551         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18552                 error "src_child still exists after rename"
18553
18554         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18555                 error "missing file(a) after rename"
18556
18557         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18558                 error "diff after rename"
18559 }
18560
18561 test_310a() {
18562         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18564
18565         local remote_file=$DIR/$tdir/tgt_dir/b
18566
18567         mkdir -p $DIR/$tdir
18568
18569         prepare_remote_file || error "prepare remote file failed"
18570
18571         #open-unlink file
18572         $OPENUNLINK $remote_file $remote_file ||
18573                 error "openunlink $remote_file failed"
18574         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18575 }
18576 run_test 310a "open unlink remote file"
18577
18578 test_310b() {
18579         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18581
18582         local remote_file=$DIR/$tdir/tgt_dir/b
18583
18584         mkdir -p $DIR/$tdir
18585
18586         prepare_remote_file || error "prepare remote file failed"
18587
18588         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18589         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18590         $CHECKSTAT -t file $remote_file || error "check file failed"
18591 }
18592 run_test 310b "unlink remote file with multiple links while open"
18593
18594 test_310c() {
18595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18596         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18597
18598         local remote_file=$DIR/$tdir/tgt_dir/b
18599
18600         mkdir -p $DIR/$tdir
18601
18602         prepare_remote_file || error "prepare remote file failed"
18603
18604         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18605         multiop_bg_pause $remote_file O_uc ||
18606                         error "mulitop failed for remote file"
18607         MULTIPID=$!
18608         $MULTIOP $DIR/$tfile Ouc
18609         kill -USR1 $MULTIPID
18610         wait $MULTIPID
18611 }
18612 run_test 310c "open-unlink remote file with multiple links"
18613
18614 #LU-4825
18615 test_311() {
18616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18617         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18618         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18619                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18620         remote_mds_nodsh && skip "remote MDS with nodsh"
18621
18622         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18623         local mdts=$(comma_list $(mdts_nodes))
18624
18625         mkdir -p $DIR/$tdir
18626         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18627         createmany -o $DIR/$tdir/$tfile. 1000
18628
18629         # statfs data is not real time, let's just calculate it
18630         old_iused=$((old_iused + 1000))
18631
18632         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18633                         osp.*OST0000*MDT0000.create_count")
18634         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18635                                 osp.*OST0000*MDT0000.max_create_count")
18636         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18637
18638         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18639         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18640         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18641
18642         unlinkmany $DIR/$tdir/$tfile. 1000
18643
18644         do_nodes $mdts "$LCTL set_param -n \
18645                         osp.*OST0000*.max_create_count=$max_count"
18646         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18647                 do_nodes $mdts "$LCTL set_param -n \
18648                                 osp.*OST0000*.create_count=$count"
18649         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18650                         grep "=0" && error "create_count is zero"
18651
18652         local new_iused
18653         for i in $(seq 120); do
18654                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18655                 # system may be too busy to destroy all objs in time, use
18656                 # a somewhat small value to not fail autotest
18657                 [ $((old_iused - new_iused)) -gt 400 ] && break
18658                 sleep 1
18659         done
18660
18661         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18662         [ $((old_iused - new_iused)) -gt 400 ] ||
18663                 error "objs not destroyed after unlink"
18664 }
18665 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18666
18667 zfs_oid_to_objid()
18668 {
18669         local ost=$1
18670         local objid=$2
18671
18672         local vdevdir=$(dirname $(facet_vdevice $ost))
18673         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18674         local zfs_zapid=$(do_facet $ost $cmd |
18675                           grep -w "/O/0/d$((objid%32))" -C 5 |
18676                           awk '/Object/{getline; print $1}')
18677         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18678                           awk "/$objid = /"'{printf $3}')
18679
18680         echo $zfs_objid
18681 }
18682
18683 zfs_object_blksz() {
18684         local ost=$1
18685         local objid=$2
18686
18687         local vdevdir=$(dirname $(facet_vdevice $ost))
18688         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18689         local blksz=$(do_facet $ost $cmd $objid |
18690                       awk '/dblk/{getline; printf $4}')
18691
18692         case "${blksz: -1}" in
18693                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18694                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18695                 *) ;;
18696         esac
18697
18698         echo $blksz
18699 }
18700
18701 test_312() { # LU-4856
18702         remote_ost_nodsh && skip "remote OST with nodsh"
18703         [ "$ost1_FSTYPE" = "zfs" ] ||
18704                 skip_env "the test only applies to zfs"
18705
18706         local max_blksz=$(do_facet ost1 \
18707                           $ZFS get -p recordsize $(facet_device ost1) |
18708                           awk '!/VALUE/{print $3}')
18709
18710         # to make life a little bit easier
18711         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18712         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18713
18714         local tf=$DIR/$tdir/$tfile
18715         touch $tf
18716         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18717
18718         # Get ZFS object id
18719         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18720         # block size change by sequential overwrite
18721         local bs
18722
18723         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18724                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18725
18726                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18727                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18728         done
18729         rm -f $tf
18730
18731         # block size change by sequential append write
18732         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18733         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18734         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18735         local count
18736
18737         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18738                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18739                         oflag=sync conv=notrunc
18740
18741                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18742                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18743                         error "blksz error, actual $blksz, " \
18744                                 "expected: 2 * $count * $PAGE_SIZE"
18745         done
18746         rm -f $tf
18747
18748         # random write
18749         touch $tf
18750         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18751         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18752
18753         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18754         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18755         [ $blksz -eq $PAGE_SIZE ] ||
18756                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18757
18758         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18759         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18760         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18761
18762         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18763         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18764         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18765 }
18766 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18767
18768 test_313() {
18769         remote_ost_nodsh && skip "remote OST with nodsh"
18770
18771         local file=$DIR/$tfile
18772
18773         rm -f $file
18774         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18775
18776         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18777         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18778         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18779                 error "write should failed"
18780         do_facet ost1 "$LCTL set_param fail_loc=0"
18781         rm -f $file
18782 }
18783 run_test 313 "io should fail after last_rcvd update fail"
18784
18785 test_314() {
18786         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18787
18788         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18789         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18790         rm -f $DIR/$tfile
18791         wait_delete_completed
18792         do_facet ost1 "$LCTL set_param fail_loc=0"
18793 }
18794 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18795
18796 test_315() { # LU-618
18797         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18798
18799         local file=$DIR/$tfile
18800         rm -f $file
18801
18802         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18803                 error "multiop file write failed"
18804         $MULTIOP $file oO_RDONLY:r4063232_c &
18805         PID=$!
18806
18807         sleep 2
18808
18809         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18810         kill -USR1 $PID
18811
18812         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18813         rm -f $file
18814 }
18815 run_test 315 "read should be accounted"
18816
18817 test_316() {
18818         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18819         large_xattr_enabled || skip_env "ea_inode feature disabled"
18820
18821         rm -rf $DIR/$tdir/d
18822         mkdir -p $DIR/$tdir/d
18823         chown nobody $DIR/$tdir/d
18824         touch $DIR/$tdir/d/file
18825
18826         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18827 }
18828 run_test 316 "lfs mv"
18829
18830 test_317() {
18831         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18832                 skip "Need MDS version at least 2.11.53"
18833         local trunc_sz
18834         local grant_blk_size
18835
18836         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18837                 skip "LU-10370: no implementation for ZFS" && return
18838         fi
18839
18840         stack_trap "rm -f $DIR/$tfile" EXIT
18841         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18842                         awk '/grant_block_size:/ { print $2; exit; }')
18843         #
18844         # Create File of size 5M. Truncate it to below size's and verify
18845         # blocks count.
18846         #
18847         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18848                 error "Create file : $DIR/$tfile"
18849
18850         for trunc_sz in 2097152 4097 4000 509 0; do
18851                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18852                         error "truncate $tfile to $trunc_sz failed"
18853                 local sz=$(stat --format=%s $DIR/$tfile)
18854                 local blk=$(stat --format=%b $DIR/$tfile)
18855                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18856                                      grant_blk_size) * 8))
18857
18858                 if [[ $blk -ne $trunc_blk ]]; then
18859                         $(which stat) $DIR/$tfile
18860                         error "Expected Block $trunc_blk got $blk for $tfile"
18861                 fi
18862
18863                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18864                         error "Expected Size $trunc_sz got $sz for $tfile"
18865         done
18866
18867         #
18868         # sparse file test
18869         # Create file with a hole and write actual two blocks. Block count
18870         # must be 16.
18871         #
18872         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18873                 conv=fsync || error "Create file : $DIR/$tfile"
18874
18875         # Calculate the final truncate size.
18876         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18877
18878         #
18879         # truncate to size $trunc_sz bytes. Strip the last block
18880         # The block count must drop to 8
18881         #
18882         $TRUNCATE $DIR/$tfile $trunc_sz ||
18883                 error "truncate $tfile to $trunc_sz failed"
18884
18885         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18886         sz=$(stat --format=%s $DIR/$tfile)
18887         blk=$(stat --format=%b $DIR/$tfile)
18888
18889         if [[ $blk -ne $trunc_bsz ]]; then
18890                 $(which stat) $DIR/$tfile
18891                 error "Expected Block $trunc_bsz got $blk for $tfile"
18892         fi
18893
18894         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18895                 error "Expected Size $trunc_sz got $sz for $tfile"
18896 }
18897 run_test 317 "Verify blocks get correctly update after truncate"
18898
18899 test_319() {
18900         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18901
18902         local before=$(date +%s)
18903         local evict
18904         local mdir=$DIR/$tdir
18905         local file=$mdir/xxx
18906
18907         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18908         touch $file
18909
18910 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18911         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18912         $LFS mv -m1 $file &
18913
18914         sleep 1
18915         dd if=$file of=/dev/null
18916         wait
18917         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18918           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18919
18920         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18921 }
18922 run_test 319 "lost lease lock on migrate error"
18923
18924 test_fake_rw() {
18925         local read_write=$1
18926         if [ "$read_write" = "write" ]; then
18927                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18928         elif [ "$read_write" = "read" ]; then
18929                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18930         else
18931                 error "argument error"
18932         fi
18933
18934         # turn off debug for performance testing
18935         local saved_debug=$($LCTL get_param -n debug)
18936         $LCTL set_param debug=0
18937
18938         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18939
18940         # get ost1 size - lustre-OST0000
18941         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18942         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18943         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18944
18945         if [ "$read_write" = "read" ]; then
18946                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18947         fi
18948
18949         local start_time=$(date +%s.%N)
18950         $dd_cmd bs=1M count=$blocks oflag=sync ||
18951                 error "real dd $read_write error"
18952         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18953
18954         if [ "$read_write" = "write" ]; then
18955                 rm -f $DIR/$tfile
18956         fi
18957
18958         # define OBD_FAIL_OST_FAKE_RW           0x238
18959         do_facet ost1 $LCTL set_param fail_loc=0x238
18960
18961         local start_time=$(date +%s.%N)
18962         $dd_cmd bs=1M count=$blocks oflag=sync ||
18963                 error "fake dd $read_write error"
18964         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18965
18966         if [ "$read_write" = "write" ]; then
18967                 # verify file size
18968                 cancel_lru_locks osc
18969                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18970                         error "$tfile size not $blocks MB"
18971         fi
18972         do_facet ost1 $LCTL set_param fail_loc=0
18973
18974         echo "fake $read_write $duration_fake vs. normal $read_write" \
18975                 "$duration in seconds"
18976         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18977                 error_not_in_vm "fake write is slower"
18978
18979         $LCTL set_param -n debug="$saved_debug"
18980         rm -f $DIR/$tfile
18981 }
18982 test_399a() { # LU-7655 for OST fake write
18983         remote_ost_nodsh && skip "remote OST with nodsh"
18984
18985         test_fake_rw write
18986 }
18987 run_test 399a "fake write should not be slower than normal write"
18988
18989 test_399b() { # LU-8726 for OST fake read
18990         remote_ost_nodsh && skip "remote OST with nodsh"
18991         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18992                 skip_env "ldiskfs only test"
18993         fi
18994
18995         test_fake_rw read
18996 }
18997 run_test 399b "fake read should not be slower than normal read"
18998
18999 test_400a() { # LU-1606, was conf-sanity test_74
19000         if ! which $CC > /dev/null 2>&1; then
19001                 skip_env "$CC is not installed"
19002         fi
19003
19004         local extra_flags=''
19005         local out=$TMP/$tfile
19006         local prefix=/usr/include/lustre
19007         local prog
19008
19009         if ! [[ -d $prefix ]]; then
19010                 # Assume we're running in tree and fixup the include path.
19011                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19012                 extra_flags+=" -L$LUSTRE/utils/.lib"
19013         fi
19014
19015         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19016                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19017                         error "client api broken"
19018         done
19019         rm -f $out
19020 }
19021 run_test 400a "Lustre client api program can compile and link"
19022
19023 test_400b() { # LU-1606, LU-5011
19024         local header
19025         local out=$TMP/$tfile
19026         local prefix=/usr/include/linux/lustre
19027
19028         # We use a hard coded prefix so that this test will not fail
19029         # when run in tree. There are headers in lustre/include/lustre/
19030         # that are not packaged (like lustre_idl.h) and have more
19031         # complicated include dependencies (like config.h and lnet/types.h).
19032         # Since this test about correct packaging we just skip them when
19033         # they don't exist (see below) rather than try to fixup cppflags.
19034
19035         if ! which $CC > /dev/null 2>&1; then
19036                 skip_env "$CC is not installed"
19037         fi
19038
19039         for header in $prefix/*.h; do
19040                 if ! [[ -f "$header" ]]; then
19041                         continue
19042                 fi
19043
19044                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19045                         continue # lustre_ioctl.h is internal header
19046                 fi
19047
19048                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19049                         error "cannot compile '$header'"
19050         done
19051         rm -f $out
19052 }
19053 run_test 400b "packaged headers can be compiled"
19054
19055 test_401a() { #LU-7437
19056         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19057         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19058
19059         #count the number of parameters by "list_param -R"
19060         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19061         #count the number of parameters by listing proc files
19062         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19063         echo "proc_dirs='$proc_dirs'"
19064         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19065         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19066                       sort -u | wc -l)
19067
19068         [ $params -eq $procs ] ||
19069                 error "found $params parameters vs. $procs proc files"
19070
19071         # test the list_param -D option only returns directories
19072         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19073         #count the number of parameters by listing proc directories
19074         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19075                 sort -u | wc -l)
19076
19077         [ $params -eq $procs ] ||
19078                 error "found $params parameters vs. $procs proc files"
19079 }
19080 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19081
19082 test_401b() {
19083         local save=$($LCTL get_param -n jobid_var)
19084         local tmp=testing
19085
19086         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19087                 error "no error returned when setting bad parameters"
19088
19089         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19090         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19091
19092         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19093         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19094         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19095 }
19096 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19097
19098 test_401c() {
19099         local jobid_var_old=$($LCTL get_param -n jobid_var)
19100         local jobid_var_new
19101
19102         $LCTL set_param jobid_var= &&
19103                 error "no error returned for 'set_param a='"
19104
19105         jobid_var_new=$($LCTL get_param -n jobid_var)
19106         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19107                 error "jobid_var was changed by setting without value"
19108
19109         $LCTL set_param jobid_var &&
19110                 error "no error returned for 'set_param a'"
19111
19112         jobid_var_new=$($LCTL get_param -n jobid_var)
19113         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19114                 error "jobid_var was changed by setting without value"
19115 }
19116 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19117
19118 test_401d() {
19119         local jobid_var_old=$($LCTL get_param -n jobid_var)
19120         local jobid_var_new
19121         local new_value="foo=bar"
19122
19123         $LCTL set_param jobid_var=$new_value ||
19124                 error "'set_param a=b' did not accept a value containing '='"
19125
19126         jobid_var_new=$($LCTL get_param -n jobid_var)
19127         [[ "$jobid_var_new" == "$new_value" ]] ||
19128                 error "'set_param a=b' failed on a value containing '='"
19129
19130         # Reset the jobid_var to test the other format
19131         $LCTL set_param jobid_var=$jobid_var_old
19132         jobid_var_new=$($LCTL get_param -n jobid_var)
19133         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19134                 error "failed to reset jobid_var"
19135
19136         $LCTL set_param jobid_var $new_value ||
19137                 error "'set_param a b' did not accept a value containing '='"
19138
19139         jobid_var_new=$($LCTL get_param -n jobid_var)
19140         [[ "$jobid_var_new" == "$new_value" ]] ||
19141                 error "'set_param a b' failed on a value containing '='"
19142
19143         $LCTL set_param jobid_var $jobid_var_old
19144         jobid_var_new=$($LCTL get_param -n jobid_var)
19145         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19146                 error "failed to reset jobid_var"
19147 }
19148 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19149
19150 test_402() {
19151         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19152         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19153                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19154         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19155                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19156                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19157         remote_mds_nodsh && skip "remote MDS with nodsh"
19158
19159         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19160 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19161         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19162         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19163                 echo "Touch failed - OK"
19164 }
19165 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19166
19167 test_403() {
19168         local file1=$DIR/$tfile.1
19169         local file2=$DIR/$tfile.2
19170         local tfile=$TMP/$tfile
19171
19172         rm -f $file1 $file2 $tfile
19173
19174         touch $file1
19175         ln $file1 $file2
19176
19177         # 30 sec OBD_TIMEOUT in ll_getattr()
19178         # right before populating st_nlink
19179         $LCTL set_param fail_loc=0x80001409
19180         stat -c %h $file1 > $tfile &
19181
19182         # create an alias, drop all locks and reclaim the dentry
19183         < $file2
19184         cancel_lru_locks mdc
19185         cancel_lru_locks osc
19186         sysctl -w vm.drop_caches=2
19187
19188         wait
19189
19190         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19191
19192         rm -f $tfile $file1 $file2
19193 }
19194 run_test 403 "i_nlink should not drop to zero due to aliasing"
19195
19196 test_404() { # LU-6601
19197         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19198                 skip "Need server version newer than 2.8.52"
19199         remote_mds_nodsh && skip "remote MDS with nodsh"
19200
19201         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19202                 awk '/osp .*-osc-MDT/ { print $4}')
19203
19204         local osp
19205         for osp in $mosps; do
19206                 echo "Deactivate: " $osp
19207                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19208                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19209                         awk -vp=$osp '$4 == p { print $2 }')
19210                 [ $stat = IN ] || {
19211                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19212                         error "deactivate error"
19213                 }
19214                 echo "Activate: " $osp
19215                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19216                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19217                         awk -vp=$osp '$4 == p { print $2 }')
19218                 [ $stat = UP ] || {
19219                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19220                         error "activate error"
19221                 }
19222         done
19223 }
19224 run_test 404 "validate manual {de}activated works properly for OSPs"
19225
19226 test_405() {
19227         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19228         [ $MDS1_VERSION -lt $(version_code 2.6.92) -o \
19229         [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19230                 skip "Layout swap lock is not supported"
19231         check_swap_layouts_support
19232
19233         test_mkdir $DIR/$tdir
19234         swap_lock_test -d $DIR/$tdir ||
19235                 error "One layout swap locked test failed"
19236 }
19237 run_test 405 "Various layout swap lock tests"
19238
19239 test_406() {
19240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19241         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19242         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19244         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19245                 skip "Need MDS version at least 2.8.50"
19246
19247         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19248         local test_pool=$TESTNAME
19249
19250         if ! combined_mgs_mds ; then
19251                 mount_mgs_client
19252         fi
19253         pool_add $test_pool || error "pool_add failed"
19254         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19255                 error "pool_add_targets failed"
19256
19257         save_layout_restore_at_exit $MOUNT
19258
19259         # parent set default stripe count only, child will stripe from both
19260         # parent and fs default
19261         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19262                 error "setstripe $MOUNT failed"
19263         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19264         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19265         for i in $(seq 10); do
19266                 local f=$DIR/$tdir/$tfile.$i
19267                 touch $f || error "touch failed"
19268                 local count=$($LFS getstripe -c $f)
19269                 [ $count -eq $OSTCOUNT ] ||
19270                         error "$f stripe count $count != $OSTCOUNT"
19271                 local offset=$($LFS getstripe -i $f)
19272                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19273                 local size=$($LFS getstripe -S $f)
19274                 [ $size -eq $((def_stripe_size * 2)) ] ||
19275                         error "$f stripe size $size != $((def_stripe_size * 2))"
19276                 local pool=$($LFS getstripe -p $f)
19277                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19278         done
19279
19280         # change fs default striping, delete parent default striping, now child
19281         # will stripe from new fs default striping only
19282         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19283                 error "change $MOUNT default stripe failed"
19284         $LFS setstripe -c 0 $DIR/$tdir ||
19285                 error "delete $tdir default stripe failed"
19286         for i in $(seq 11 20); do
19287                 local f=$DIR/$tdir/$tfile.$i
19288                 touch $f || error "touch $f failed"
19289                 local count=$($LFS getstripe -c $f)
19290                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19291                 local offset=$($LFS getstripe -i $f)
19292                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19293                 local size=$($LFS getstripe -S $f)
19294                 [ $size -eq $def_stripe_size ] ||
19295                         error "$f stripe size $size != $def_stripe_size"
19296                 local pool=$($LFS getstripe -p $f)
19297                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19298         done
19299
19300         unlinkmany $DIR/$tdir/$tfile. 1 20
19301
19302         local f=$DIR/$tdir/$tfile
19303         pool_remove_all_targets $test_pool $f
19304         pool_remove $test_pool $f
19305
19306         if ! combined_mgs_mds ; then
19307                 umount_mgs_client
19308         fi
19309 }
19310 run_test 406 "DNE support fs default striping"
19311
19312 test_407() {
19313         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19314         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19315                 skip "Need MDS version at least 2.8.55"
19316         remote_mds_nodsh && skip "remote MDS with nodsh"
19317
19318         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19319                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19320         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19321                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19322         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19323
19324         #define OBD_FAIL_DT_TXN_STOP    0x2019
19325         for idx in $(seq $MDSCOUNT); do
19326                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19327         done
19328         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19329         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19330                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19331         true
19332 }
19333 run_test 407 "transaction fail should cause operation fail"
19334
19335 test_408() {
19336         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19337
19338         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19339         lctl set_param fail_loc=0x8000040a
19340         # let ll_prepare_partial_page() fail
19341         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19342
19343         rm -f $DIR/$tfile
19344
19345         # create at least 100 unused inodes so that
19346         # shrink_icache_memory(0) should not return 0
19347         touch $DIR/$tfile-{0..100}
19348         rm -f $DIR/$tfile-{0..100}
19349         sync
19350
19351         echo 2 > /proc/sys/vm/drop_caches
19352 }
19353 run_test 408 "drop_caches should not hang due to page leaks"
19354
19355 test_409()
19356 {
19357         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19358
19359         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19360         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19361         touch $DIR/$tdir/guard || error "(2) Fail to create"
19362
19363         local PREFIX=$(str_repeat 'A' 128)
19364         echo "Create 1K hard links start at $(date)"
19365         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19366                 error "(3) Fail to hard link"
19367
19368         echo "Links count should be right although linkEA overflow"
19369         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19370         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19371         [ $linkcount -eq 1001 ] ||
19372                 error "(5) Unexpected hard links count: $linkcount"
19373
19374         echo "List all links start at $(date)"
19375         ls -l $DIR/$tdir/foo > /dev/null ||
19376                 error "(6) Fail to list $DIR/$tdir/foo"
19377
19378         echo "Unlink hard links start at $(date)"
19379         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19380                 error "(7) Fail to unlink"
19381         echo "Unlink hard links finished at $(date)"
19382 }
19383 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19384
19385 test_410()
19386 {
19387         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19388                 skip "Need client version at least 2.9.59"
19389
19390         # Create a file, and stat it from the kernel
19391         local testfile=$DIR/$tfile
19392         touch $testfile
19393
19394         local run_id=$RANDOM
19395         local my_ino=$(stat --format "%i" $testfile)
19396
19397         # Try to insert the module. This will always fail as the
19398         # module is designed to not be inserted.
19399         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19400             &> /dev/null
19401
19402         # Anything but success is a test failure
19403         dmesg | grep -q \
19404             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19405             error "no inode match"
19406 }
19407 run_test 410 "Test inode number returned from kernel thread"
19408
19409 cleanup_test411_cgroup() {
19410         trap 0
19411         rmdir "$1"
19412 }
19413
19414 test_411() {
19415         local cg_basedir=/sys/fs/cgroup/memory
19416         # LU-9966
19417         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19418                 skip "no setup for cgroup"
19419
19420         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19421                 error "test file creation failed"
19422         cancel_lru_locks osc
19423
19424         # Create a very small memory cgroup to force a slab allocation error
19425         local cgdir=$cg_basedir/osc_slab_alloc
19426         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19427         trap "cleanup_test411_cgroup $cgdir" EXIT
19428         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19429         echo 1M > $cgdir/memory.limit_in_bytes
19430
19431         # Should not LBUG, just be killed by oom-killer
19432         # dd will return 0 even allocation failure in some environment.
19433         # So don't check return value
19434         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19435         cleanup_test411_cgroup $cgdir
19436
19437         return 0
19438 }
19439 run_test 411 "Slab allocation error with cgroup does not LBUG"
19440
19441 test_412() {
19442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19443         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19444                 skip "Need server version at least 2.10.55"
19445         fi
19446
19447         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19448                 error "mkdir failed"
19449         $LFS getdirstripe $DIR/$tdir
19450         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19451         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19452                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19453         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19454         [ $stripe_count -eq 2 ] ||
19455                 error "expect 2 get $stripe_count"
19456 }
19457 run_test 412 "mkdir on specific MDTs"
19458
19459 test_413() {
19460         [ $MDSCOUNT -lt 2 ] &&
19461                 skip "We need at least 2 MDTs for this test"
19462
19463         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19464                 skip "Need server version at least 2.10.55"
19465         fi
19466
19467         mkdir $DIR/$tdir || error "mkdir failed"
19468
19469         # find MDT that is the most full
19470         local max=$($LFS df | grep MDT |
19471                 awk 'BEGIN { a=0 }
19472                         { sub("%", "", $5)
19473                           if (0+$5 >= a)
19474                           {
19475                                 a = $5
19476                                 b = $6
19477                           }
19478                         }
19479                      END { split(b, c, ":")
19480                            sub("]", "", c[2])
19481                            print c[2]
19482                          }')
19483
19484         for i in $(seq $((MDSCOUNT - 1))); do
19485                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19486                         error "mkdir d$i failed"
19487                 $LFS getdirstripe $DIR/$tdir/d$i
19488                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19489                 [ $stripe_index -ne $max ] ||
19490                         error "don't expect $max"
19491         done
19492 }
19493 run_test 413 "mkdir on less full MDTs"
19494
19495 test_414() {
19496 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19497         $LCTL set_param fail_loc=0x80000521
19498         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19499         rm -f $DIR/$tfile
19500 }
19501 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19502
19503 test_415() {
19504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19505         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19506                 skip "Need server version at least 2.11.52"
19507
19508         # LU-11102
19509         local total
19510         local setattr_pid
19511         local start_time
19512         local end_time
19513         local duration
19514
19515         total=500
19516         # this test may be slow on ZFS
19517         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19518
19519         # though this test is designed for striped directory, let's test normal
19520         # directory too since lock is always saved as CoS lock.
19521         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19522         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19523
19524         (
19525                 while true; do
19526                         touch $DIR/$tdir
19527                 done
19528         ) &
19529         setattr_pid=$!
19530
19531         start_time=$(date +%s)
19532         for i in $(seq $total); do
19533                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19534                         > /dev/null
19535         done
19536         end_time=$(date +%s)
19537         duration=$((end_time - start_time))
19538
19539         kill -9 $setattr_pid
19540
19541         echo "rename $total files took $duration sec"
19542         [ $duration -lt 100 ] || error "rename took $duration sec"
19543 }
19544 run_test 415 "lock revoke is not missing"
19545
19546 test_416() {
19547         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19548                 skip "Need server version at least 2.11.55"
19549
19550         # define OBD_FAIL_OSD_TXN_START    0x19a
19551         do_facet mds1 lctl set_param fail_loc=0x19a
19552
19553         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19554
19555         true
19556 }
19557 run_test 416 "transaction start failure won't cause system hung"
19558
19559 cleanup_417() {
19560         trap 0
19561         do_nodes $(comma_list $(mdts_nodes)) \
19562                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19563         do_nodes $(comma_list $(mdts_nodes)) \
19564                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19565         do_nodes $(comma_list $(mdts_nodes)) \
19566                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19567 }
19568
19569 test_417() {
19570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19571         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19572                 skip "Need MDS version at least 2.11.56"
19573
19574         trap cleanup_417 RETURN EXIT
19575
19576         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19577         do_nodes $(comma_list $(mdts_nodes)) \
19578                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19579         $LFS migrate -m 0 $DIR/$tdir.1 &&
19580                 error "migrate dir $tdir.1 should fail"
19581
19582         do_nodes $(comma_list $(mdts_nodes)) \
19583                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19584         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19585                 error "create remote dir $tdir.2 should fail"
19586
19587         do_nodes $(comma_list $(mdts_nodes)) \
19588                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19589         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19590                 error "create striped dir $tdir.3 should fail"
19591         true
19592 }
19593 run_test 417 "disable remote dir, striped dir and dir migration"
19594
19595 # Checks that the outputs of df [-i] and lfs df [-i] match
19596 #
19597 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19598 check_lfs_df() {
19599         local dir=$2
19600         local inodes
19601         local df_out
19602         local lfs_df_out
19603         local count
19604         local passed=false
19605
19606         # blocks or inodes
19607         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19608
19609         for count in {1..100}; do
19610                 cancel_lru_locks
19611                 sync; sleep 0.2
19612
19613                 # read the lines of interest
19614                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19615                         error "df $inodes $dir | tail -n +2 failed"
19616                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19617                         error "lfs df $inodes $dir | grep summary: failed"
19618
19619                 # skip first substrings of each output as they are different
19620                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19621                 # compare the two outputs
19622                 passed=true
19623                 for i in {1..5}; do
19624                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19625                 done
19626                 $passed && break
19627         done
19628
19629         if ! $passed; then
19630                 df -P $inodes $dir
19631                 echo
19632                 lfs df $inodes $dir
19633                 error "df and lfs df $1 output mismatch: "      \
19634                       "df ${inodes}: ${df_out[*]}, "            \
19635                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19636         fi
19637 }
19638
19639 test_418() {
19640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19641
19642         local dir=$DIR/$tdir
19643         local numfiles=$((RANDOM % 4096 + 2))
19644         local numblocks=$((RANDOM % 256 + 1))
19645
19646         wait_delete_completed
19647         test_mkdir $dir
19648
19649         # check block output
19650         check_lfs_df blocks $dir
19651         # check inode output
19652         check_lfs_df inodes $dir
19653
19654         # create a single file and retest
19655         echo "Creating a single file and testing"
19656         createmany -o $dir/$tfile- 1 &>/dev/null ||
19657                 error "creating 1 file in $dir failed"
19658         check_lfs_df blocks $dir
19659         check_lfs_df inodes $dir
19660
19661         # create a random number of files
19662         echo "Creating $((numfiles - 1)) files and testing"
19663         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19664                 error "creating $((numfiles - 1)) files in $dir failed"
19665
19666         # write a random number of blocks to the first test file
19667         echo "Writing $numblocks 4K blocks and testing"
19668         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19669                 count=$numblocks &>/dev/null ||
19670                 error "dd to $dir/${tfile}-0 failed"
19671
19672         # retest
19673         check_lfs_df blocks $dir
19674         check_lfs_df inodes $dir
19675
19676         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19677                 error "unlinking $numfiles files in $dir failed"
19678 }
19679 run_test 418 "df and lfs df outputs match"
19680
19681 prep_801() {
19682         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19683         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19684                 skip "Need server version at least 2.9.55"
19685
19686         start_full_debug_logging
19687 }
19688
19689 post_801() {
19690         stop_full_debug_logging
19691 }
19692
19693 barrier_stat() {
19694         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19695                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19696                            awk '/The barrier for/ { print $7 }')
19697                 echo $st
19698         else
19699                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19700                 echo \'$st\'
19701         fi
19702 }
19703
19704 barrier_expired() {
19705         local expired
19706
19707         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19708                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19709                           awk '/will be expired/ { print $7 }')
19710         else
19711                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19712         fi
19713
19714         echo $expired
19715 }
19716
19717 test_801a() {
19718         prep_801
19719
19720         echo "Start barrier_freeze at: $(date)"
19721         #define OBD_FAIL_BARRIER_DELAY          0x2202
19722         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19723         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19724
19725         sleep 2
19726         local b_status=$(barrier_stat)
19727         echo "Got barrier status at: $(date)"
19728         [ "$b_status" = "'freezing_p1'" ] ||
19729                 error "(1) unexpected barrier status $b_status"
19730
19731         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19732         wait
19733         b_status=$(barrier_stat)
19734         [ "$b_status" = "'frozen'" ] ||
19735                 error "(2) unexpected barrier status $b_status"
19736
19737         local expired=$(barrier_expired)
19738         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19739         sleep $((expired + 3))
19740
19741         b_status=$(barrier_stat)
19742         [ "$b_status" = "'expired'" ] ||
19743                 error "(3) unexpected barrier status $b_status"
19744
19745         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19746                 error "(4) fail to freeze barrier"
19747
19748         b_status=$(barrier_stat)
19749         [ "$b_status" = "'frozen'" ] ||
19750                 error "(5) unexpected barrier status $b_status"
19751
19752         echo "Start barrier_thaw at: $(date)"
19753         #define OBD_FAIL_BARRIER_DELAY          0x2202
19754         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19755         do_facet mgs $LCTL barrier_thaw $FSNAME &
19756
19757         sleep 2
19758         b_status=$(barrier_stat)
19759         echo "Got barrier status at: $(date)"
19760         [ "$b_status" = "'thawing'" ] ||
19761                 error "(6) unexpected barrier status $b_status"
19762
19763         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19764         wait
19765         b_status=$(barrier_stat)
19766         [ "$b_status" = "'thawed'" ] ||
19767                 error "(7) unexpected barrier status $b_status"
19768
19769         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19770         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19771         do_facet mgs $LCTL barrier_freeze $FSNAME
19772
19773         b_status=$(barrier_stat)
19774         [ "$b_status" = "'failed'" ] ||
19775                 error "(8) unexpected barrier status $b_status"
19776
19777         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19778         do_facet mgs $LCTL barrier_thaw $FSNAME
19779
19780         post_801
19781 }
19782 run_test 801a "write barrier user interfaces and stat machine"
19783
19784 test_801b() {
19785         prep_801
19786
19787         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19788         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19789         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19790         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19791         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19792
19793         cancel_lru_locks mdc
19794
19795         # 180 seconds should be long enough
19796         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19797
19798         local b_status=$(barrier_stat)
19799         [ "$b_status" = "'frozen'" ] ||
19800                 error "(6) unexpected barrier status $b_status"
19801
19802         mkdir $DIR/$tdir/d0/d10 &
19803         mkdir_pid=$!
19804
19805         touch $DIR/$tdir/d1/f13 &
19806         touch_pid=$!
19807
19808         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19809         ln_pid=$!
19810
19811         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19812         mv_pid=$!
19813
19814         rm -f $DIR/$tdir/d4/f12 &
19815         rm_pid=$!
19816
19817         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19818
19819         # To guarantee taht the 'stat' is not blocked
19820         b_status=$(barrier_stat)
19821         [ "$b_status" = "'frozen'" ] ||
19822                 error "(8) unexpected barrier status $b_status"
19823
19824         # let above commands to run at background
19825         sleep 5
19826
19827         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19828         ps -p $touch_pid || error "(10) touch should be blocked"
19829         ps -p $ln_pid || error "(11) link should be blocked"
19830         ps -p $mv_pid || error "(12) rename should be blocked"
19831         ps -p $rm_pid || error "(13) unlink should be blocked"
19832
19833         b_status=$(barrier_stat)
19834         [ "$b_status" = "'frozen'" ] ||
19835                 error "(14) unexpected barrier status $b_status"
19836
19837         do_facet mgs $LCTL barrier_thaw $FSNAME
19838         b_status=$(barrier_stat)
19839         [ "$b_status" = "'thawed'" ] ||
19840                 error "(15) unexpected barrier status $b_status"
19841
19842         wait $mkdir_pid || error "(16) mkdir should succeed"
19843         wait $touch_pid || error "(17) touch should succeed"
19844         wait $ln_pid || error "(18) link should succeed"
19845         wait $mv_pid || error "(19) rename should succeed"
19846         wait $rm_pid || error "(20) unlink should succeed"
19847
19848         post_801
19849 }
19850 run_test 801b "modification will be blocked by write barrier"
19851
19852 test_801c() {
19853         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19854
19855         prep_801
19856
19857         stop mds2 || error "(1) Fail to stop mds2"
19858
19859         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19860
19861         local b_status=$(barrier_stat)
19862         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
19863                 do_facet mgs $LCTL barrier_thaw $FSNAME
19864                 error "(2) unexpected barrier status $b_status"
19865         }
19866
19867         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19868                 error "(3) Fail to rescan barrier bitmap"
19869
19870         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19871
19872         b_status=$(barrier_stat)
19873         [ "$b_status" = "'frozen'" ] ||
19874                 error "(4) unexpected barrier status $b_status"
19875
19876         do_facet mgs $LCTL barrier_thaw $FSNAME
19877         b_status=$(barrier_stat)
19878         [ "$b_status" = "'thawed'" ] ||
19879                 error "(5) unexpected barrier status $b_status"
19880
19881         local devname=$(mdsdevname 2)
19882
19883         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19884
19885         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19886                 error "(7) Fail to rescan barrier bitmap"
19887
19888         post_801
19889 }
19890 run_test 801c "rescan barrier bitmap"
19891
19892 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19893 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19894 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19895
19896 cleanup_802a() {
19897         trap 0
19898
19899         stopall
19900         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19901         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19902         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19903         setupall
19904 }
19905
19906 test_802a() {
19907
19908         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19909         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19910                 skip "Need server version at least 2.9.55"
19911
19912         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19913
19914         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19915
19916         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19917                 error "(2) Fail to copy"
19918
19919         trap cleanup_802a EXIT
19920
19921         # sync by force before remount as readonly
19922         sync; sync_all_data; sleep 3; sync_all_data
19923
19924         stopall
19925
19926         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19927         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19928         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19929
19930         echo "Mount the server as read only"
19931         setupall server_only || error "(3) Fail to start servers"
19932
19933         echo "Mount client without ro should fail"
19934         mount_client $MOUNT &&
19935                 error "(4) Mount client without 'ro' should fail"
19936
19937         echo "Mount client with ro should succeed"
19938         mount_client $MOUNT ro ||
19939                 error "(5) Mount client with 'ro' should succeed"
19940
19941         echo "Modify should be refused"
19942         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19943
19944         echo "Read should be allowed"
19945         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19946                 error "(7) Read should succeed under ro mode"
19947
19948         cleanup_802a
19949 }
19950 run_test 802a "simulate readonly device"
19951
19952 test_802b() {
19953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19954         remote_mds_nodsh && skip "remote MDS with nodsh"
19955
19956         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19957                 skip "readonly option not available"
19958
19959         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19960
19961         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19962                 error "(2) Fail to copy"
19963
19964         # write back all cached data before setting MDT to readonly
19965         cancel_lru_locks
19966         sync_all_data
19967
19968         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19969         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19970
19971         echo "Modify should be refused"
19972         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19973
19974         echo "Read should be allowed"
19975         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19976                 error "(7) Read should succeed under ro mode"
19977
19978         # disable readonly
19979         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
19980 }
19981 run_test 802b "be able to set MDTs to readonly"
19982
19983 test_803() {
19984         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19985         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19986                 skip "MDS needs to be newer than 2.10.54"
19987
19988         mkdir -p $DIR/$tdir
19989         # Create some objects on all MDTs to trigger related logs objects
19990         for idx in $(seq $MDSCOUNT); do
19991                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
19992                         $DIR/$tdir/dir${idx} ||
19993                         error "Fail to create $DIR/$tdir/dir${idx}"
19994         done
19995
19996         sync; sleep 3
19997         wait_delete_completed # ensure old test cleanups are finished
19998         echo "before create:"
19999         $LFS df -i $MOUNT
20000         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20001
20002         for i in {1..10}; do
20003                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20004                         error "Fail to create $DIR/$tdir/foo$i"
20005         done
20006
20007         sync; sleep 3
20008         echo "after create:"
20009         $LFS df -i $MOUNT
20010         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20011
20012         # allow for an llog to be cleaned up during the test
20013         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20014                 error "before ($before_used) + 10 > after ($after_used)"
20015
20016         for i in {1..10}; do
20017                 rm -rf $DIR/$tdir/foo$i ||
20018                         error "Fail to remove $DIR/$tdir/foo$i"
20019         done
20020
20021         sleep 3 # avoid MDT return cached statfs
20022         wait_delete_completed
20023         echo "after unlink:"
20024         $LFS df -i $MOUNT
20025         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20026
20027         # allow for an llog to be created during the test
20028         [ $after_used -le $((before_used + 1)) ] ||
20029                 error "after ($after_used) > before ($before_used) + 1"
20030 }
20031 run_test 803 "verify agent object for remote object"
20032
20033 test_804() {
20034         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20035         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20036                 skip "MDS needs to be newer than 2.10.54"
20037         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20038
20039         mkdir -p $DIR/$tdir
20040         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20041                 error "Fail to create $DIR/$tdir/dir0"
20042
20043         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20044         local dev=$(mdsdevname 2)
20045
20046         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20047                 grep ${fid} || error "NOT found agent entry for dir0"
20048
20049         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20050                 error "Fail to create $DIR/$tdir/dir1"
20051
20052         touch $DIR/$tdir/dir1/foo0 ||
20053                 error "Fail to create $DIR/$tdir/dir1/foo0"
20054         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20055         local rc=0
20056
20057         for idx in $(seq $MDSCOUNT); do
20058                 dev=$(mdsdevname $idx)
20059                 do_facet mds${idx} \
20060                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20061                         grep ${fid} && rc=$idx
20062         done
20063
20064         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20065                 error "Fail to rename foo0 to foo1"
20066         if [ $rc -eq 0 ]; then
20067                 for idx in $(seq $MDSCOUNT); do
20068                         dev=$(mdsdevname $idx)
20069                         do_facet mds${idx} \
20070                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20071                         grep ${fid} && rc=$idx
20072                 done
20073         fi
20074
20075         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20076                 error "Fail to rename foo1 to foo2"
20077         if [ $rc -eq 0 ]; then
20078                 for idx in $(seq $MDSCOUNT); do
20079                         dev=$(mdsdevname $idx)
20080                         do_facet mds${idx} \
20081                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20082                         grep ${fid} && rc=$idx
20083                 done
20084         fi
20085
20086         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20087
20088         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20089                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20090         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20091                 error "Fail to rename foo2 to foo0"
20092         unlink $DIR/$tdir/dir1/foo0 ||
20093                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20094         rm -rf $DIR/$tdir/dir0 ||
20095                 error "Fail to rm $DIR/$tdir/dir0"
20096
20097         for idx in $(seq $MDSCOUNT); do
20098                 dev=$(mdsdevname $idx)
20099                 rc=0
20100
20101                 stop mds${idx}
20102                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20103                         rc=$?
20104                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20105                         error "mount mds$idx failed"
20106                 df $MOUNT > /dev/null 2>&1
20107
20108                 # e2fsck should not return error
20109                 [ $rc -eq 0 ] ||
20110                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20111         done
20112 }
20113 run_test 804 "verify agent entry for remote entry"
20114
20115 cleanup_805() {
20116         do_facet $SINGLEMDS zfs set quota=$old $fsset
20117         unlinkmany $DIR/$tdir/f- 1000000
20118         trap 0
20119 }
20120
20121 test_805() {
20122         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20123         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20124         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20125                 skip "netfree not implemented before 0.7"
20126         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20127                 skip "Need MDS version at least 2.10.57"
20128
20129         local fsset
20130         local freekb
20131         local usedkb
20132         local old
20133         local quota
20134         local pref="osd-zfs.lustre-MDT0000."
20135
20136         # limit available space on MDS dataset to meet nospace issue
20137         # quickly. then ZFS 0.7.2 can use reserved space if asked
20138         # properly (using netfree flag in osd_declare_destroy()
20139         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20140         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20141                 gawk '{print $3}')
20142         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20143         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20144         let "usedkb=usedkb-freekb"
20145         let "freekb=freekb/2"
20146         if let "freekb > 5000"; then
20147                 let "freekb=5000"
20148         fi
20149         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20150         trap cleanup_805 EXIT
20151         mkdir $DIR/$tdir
20152         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20153         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20154         rm -rf $DIR/$tdir || error "not able to remove"
20155         do_facet $SINGLEMDS zfs set quota=$old $fsset
20156         trap 0
20157 }
20158 run_test 805 "ZFS can remove from full fs"
20159
20160 # Size-on-MDS test
20161 check_lsom_data()
20162 {
20163         local file=$1
20164         local size=$($LFS getsom -s $file)
20165         local expect=$(stat -c %s $file)
20166
20167         [[ $size == $expect ]] ||
20168                 error "$file expected size: $expect, got: $size"
20169
20170         local blocks=$($LFS getsom -b $file)
20171         expect=$(stat -c %b $file)
20172         [[ $blocks == $expect ]] ||
20173                 error "$file expected blocks: $expect, got: $blocks"
20174 }
20175
20176 check_lsom_size()
20177 {
20178         local size=$($LFS getsom -s $1)
20179         local expect=$2
20180
20181         [[ $size == $expect ]] ||
20182                 error "$file expected size: $expect, got: $size"
20183 }
20184
20185 test_806() {
20186         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20187                 skip "Need MDS version at least 2.11.52"
20188
20189         local bs=1048576
20190
20191         touch $DIR/$tfile || error "touch $tfile failed"
20192
20193         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20194         save_lustre_params client "llite.*.xattr_cache" > $save
20195         lctl set_param llite.*.xattr_cache=0
20196         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20197
20198         # single-threaded write
20199         echo "Test SOM for single-threaded write"
20200         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20201                 error "write $tfile failed"
20202         check_lsom_size $DIR/$tfile $bs
20203
20204         local num=32
20205         local size=$(($num * $bs))
20206         local offset=0
20207         local i
20208
20209         echo "Test SOM for single client multi-threaded($num) write"
20210         $TRUNCATE $DIR/$tfile 0
20211         for ((i = 0; i < $num; i++)); do
20212                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20213                 local pids[$i]=$!
20214                 offset=$((offset + $bs))
20215         done
20216         for (( i=0; i < $num; i++ )); do
20217                 wait ${pids[$i]}
20218         done
20219         check_lsom_size $DIR/$tfile $size
20220
20221         $TRUNCATE $DIR/$tfile 0
20222         for ((i = 0; i < $num; i++)); do
20223                 offset=$((offset - $bs))
20224                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20225                 local pids[$i]=$!
20226         done
20227         for (( i=0; i < $num; i++ )); do
20228                 wait ${pids[$i]}
20229         done
20230         check_lsom_size $DIR/$tfile $size
20231
20232         # multi-client wirtes
20233         num=$(get_node_count ${CLIENTS//,/ })
20234         size=$(($num * $bs))
20235         offset=0
20236         i=0
20237
20238         echo "Test SOM for multi-client ($num) writes"
20239         $TRUNCATE $DIR/$tfile 0
20240         for client in ${CLIENTS//,/ }; do
20241                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20242                 local pids[$i]=$!
20243                 i=$((i + 1))
20244                 offset=$((offset + $bs))
20245         done
20246         for (( i=0; i < $num; i++ )); do
20247                 wait ${pids[$i]}
20248         done
20249         check_lsom_size $DIR/$tfile $offset
20250
20251         i=0
20252         $TRUNCATE $DIR/$tfile 0
20253         for client in ${CLIENTS//,/ }; do
20254                 offset=$((offset - $bs))
20255                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20256                 local pids[$i]=$!
20257                 i=$((i + 1))
20258         done
20259         for (( i=0; i < $num; i++ )); do
20260                 wait ${pids[$i]}
20261         done
20262         check_lsom_size $DIR/$tfile $size
20263
20264         # verify truncate
20265         echo "Test SOM for truncate"
20266         $TRUNCATE $DIR/$tfile 1048576
20267         check_lsom_size $DIR/$tfile 1048576
20268         $TRUNCATE $DIR/$tfile 1234
20269         check_lsom_size $DIR/$tfile 1234
20270
20271         # verify SOM blocks count
20272         echo "Verify SOM block count"
20273         $TRUNCATE $DIR/$tfile 0
20274         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20275                 error "failed to write file $tfile"
20276         check_lsom_data $DIR/$tfile
20277 }
20278 run_test 806 "Verify Lazy Size on MDS"
20279
20280 test_807() {
20281         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20282         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20283                 skip "Need MDS version at least 2.11.52"
20284
20285         # Registration step
20286         changelog_register || error "changelog_register failed"
20287         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20288         changelog_users $SINGLEMDS | grep -q $cl_user ||
20289                 error "User $cl_user not found in changelog_users"
20290
20291         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20292         save_lustre_params client "llite.*.xattr_cache" > $save
20293         lctl set_param llite.*.xattr_cache=0
20294         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20295
20296         rm -rf $DIR/$tdir || error "rm $tdir failed"
20297         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20298         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20299         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20300         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20301                 error "truncate $tdir/trunc failed"
20302
20303         local bs=1048576
20304         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20305                 error "write $tfile failed"
20306
20307         # multi-client wirtes
20308         local num=$(get_node_count ${CLIENTS//,/ })
20309         local offset=0
20310         local i=0
20311
20312         echo "Test SOM for multi-client ($num) writes"
20313         touch $DIR/$tfile || error "touch $tfile failed"
20314         $TRUNCATE $DIR/$tfile 0
20315         for client in ${CLIENTS//,/ }; do
20316                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20317                 local pids[$i]=$!
20318                 i=$((i + 1))
20319                 offset=$((offset + $bs))
20320         done
20321         for (( i=0; i < $num; i++ )); do
20322                 wait ${pids[$i]}
20323         done
20324
20325         sleep 5
20326         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20327         check_lsom_data $DIR/$tdir/trunc
20328         check_lsom_data $DIR/$tdir/single_dd
20329         check_lsom_data $DIR/$tfile
20330
20331         rm -rf $DIR/$tdir
20332         # Deregistration step
20333         changelog_deregister || error "changelog_deregister failed"
20334 }
20335 run_test 807 "verify LSOM syncing tool"
20336
20337 check_som_nologged()
20338 {
20339         local lines=$($LFS changelog $FSNAME-MDT0000 |
20340                 grep 'x=trusted.som' | wc -l)
20341         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20342 }
20343
20344 test_808() {
20345         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20346                 skip "Need MDS version at least 2.11.55"
20347
20348         # Registration step
20349         changelog_register || error "changelog_register failed"
20350
20351         touch $DIR/$tfile || error "touch $tfile failed"
20352         check_som_nologged
20353
20354         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20355                 error "write $tfile failed"
20356         check_som_nologged
20357
20358         $TRUNCATE $DIR/$tfile 1234
20359         check_som_nologged
20360
20361         $TRUNCATE $DIR/$tfile 1048576
20362         check_som_nologged
20363
20364         # Deregistration step
20365         changelog_deregister || error "changelog_deregister failed"
20366 }
20367 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20368
20369 check_som_nodata()
20370 {
20371         $LFS getsom $1
20372         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20373 }
20374
20375 test_809() {
20376         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20377                 skip "Need MDS version at least 2.11.56"
20378
20379         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20380                 error "failed to create DoM-only file $DIR/$tfile"
20381         touch $DIR/$tfile || error "touch $tfile failed"
20382         check_som_nodata $DIR/$tfile
20383
20384         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20385                 error "write $tfile failed"
20386         check_som_nodata $DIR/$tfile
20387
20388         $TRUNCATE $DIR/$tfile 1234
20389         check_som_nodata $DIR/$tfile
20390
20391         $TRUNCATE $DIR/$tfile 4097
20392         check_som_nodata $DIR/$file
20393 }
20394 run_test 809 "Verify no SOM xattr store for DoM-only files"
20395
20396 test_810() {
20397         local ORIG
20398         local CSUM
20399
20400         # t10 seem to dislike partial pages
20401         lctl set_param osc.*.checksum_type=adler
20402         lctl set_param fail_loc=0x411
20403         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20404         ORIG=$(md5sum $DIR/$tfile)
20405         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20406         CSUM=$(md5sum $DIR/$tfile)
20407         set_checksum_type adler
20408         if [ "$ORIG" != "$CSUM" ]; then
20409                 error "$ORIG != $CSUM"
20410         fi
20411 }
20412 run_test 810 "partial page writes on ZFS (LU-11663)"
20413
20414 test_811() {
20415         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20416                 skip "Need MDS version at least 2.11.56"
20417
20418         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20419         do_facet mds1 $LCTL set_param fail_loc=0x165
20420         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20421
20422         stop mds1
20423         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20424
20425         sleep 5
20426         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20427                 error "MDD orphan cleanup thread not quit"
20428 }
20429 run_test 811 "orphan name stub can be cleaned up in startup"
20430
20431 test_812() {
20432         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20433                 skip "OST < 2.12.51 doesn't support this fail_loc"
20434
20435         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20436         # ensure ost1 is connected
20437         stat $DIR/$tfile >/dev/null || error "can't stat"
20438         wait_osc_import_state client ost1 FULL
20439         # no locks, no reqs to let the connection idle
20440         cancel_lru_locks osc
20441
20442         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20443 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20444         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20445         wait_osc_import_state client ost1 CONNECTING
20446         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20447
20448         stat $DIR/$tfile >/dev/null || error "can't stat file"
20449 }
20450 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20451
20452 test_813() {
20453         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20454         [ -z "$file_heat_sav" ] && skip "no file heat support"
20455
20456         local readsample
20457         local writesample
20458         local readbyte
20459         local writebyte
20460         local readsample1
20461         local writesample1
20462         local readbyte1
20463         local writebyte1
20464
20465         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20466         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20467
20468         $LCTL set_param -n llite.*.file_heat=1
20469         echo "Turn on file heat"
20470         echo "Period second: $period_second, Decay percentage: $decay_pct"
20471
20472         echo "QQQQ" > $DIR/$tfile
20473         echo "QQQQ" > $DIR/$tfile
20474         echo "QQQQ" > $DIR/$tfile
20475         cat $DIR/$tfile > /dev/null
20476         cat $DIR/$tfile > /dev/null
20477         cat $DIR/$tfile > /dev/null
20478         cat $DIR/$tfile > /dev/null
20479
20480         local out=$($LFS heat_get $DIR/$tfile)
20481
20482         $LFS heat_get $DIR/$tfile
20483         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20484         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20485         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20486         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20487
20488         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20489         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20490         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20491         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20492
20493         sleep $((period_second + 3))
20494         echo "Sleep $((period_second + 3)) seconds..."
20495         # The recursion formula to calculate the heat of the file f is as
20496         # follow:
20497         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20498         # Where Hi is the heat value in the period between time points i*I and
20499         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20500         # to the weight of Ci.
20501         out=$($LFS heat_get $DIR/$tfile)
20502         $LFS heat_get $DIR/$tfile
20503         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20504         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20505         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20506         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20507
20508         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20509                 error "read sample ($readsample) is wrong"
20510         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20511                 error "write sample ($writesample) is wrong"
20512         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20513                 error "read bytes ($readbyte) is wrong"
20514         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20515                 error "write bytes ($writebyte) is wrong"
20516
20517         echo "QQQQ" > $DIR/$tfile
20518         echo "QQQQ" > $DIR/$tfile
20519         echo "QQQQ" > $DIR/$tfile
20520         cat $DIR/$tfile > /dev/null
20521         cat $DIR/$tfile > /dev/null
20522         cat $DIR/$tfile > /dev/null
20523         cat $DIR/$tfile > /dev/null
20524
20525         sleep $((period_second + 3))
20526         echo "Sleep $((period_second + 3)) seconds..."
20527
20528         out=$($LFS heat_get $DIR/$tfile)
20529         $LFS heat_get $DIR/$tfile
20530         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20531         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20532         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20533         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20534
20535         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20536                 4 * $decay_pct) / 100") -eq 1 ] ||
20537                 error "read sample ($readsample1) is wrong"
20538         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20539                 3 * $decay_pct) / 100") -eq 1 ] ||
20540                 error "write sample ($writesample1) is wrong"
20541         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20542                 20 * $decay_pct) / 100") -eq 1 ] ||
20543                 error "read bytes ($readbyte1) is wrong"
20544         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20545                 15 * $decay_pct) / 100") -eq 1 ] ||
20546                 error "write bytes ($writebyte1) is wrong"
20547
20548         echo "Turn off file heat for the file $DIR/$tfile"
20549         $LFS heat_set -o $DIR/$tfile
20550
20551         echo "QQQQ" > $DIR/$tfile
20552         echo "QQQQ" > $DIR/$tfile
20553         echo "QQQQ" > $DIR/$tfile
20554         cat $DIR/$tfile > /dev/null
20555         cat $DIR/$tfile > /dev/null
20556         cat $DIR/$tfile > /dev/null
20557         cat $DIR/$tfile > /dev/null
20558
20559         out=$($LFS heat_get $DIR/$tfile)
20560         $LFS heat_get $DIR/$tfile
20561         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20562         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20563         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20564         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20565
20566         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20567         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20568         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20569         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20570
20571         echo "Trun on file heat for the file $DIR/$tfile"
20572         $LFS heat_set -O $DIR/$tfile
20573
20574         echo "QQQQ" > $DIR/$tfile
20575         echo "QQQQ" > $DIR/$tfile
20576         echo "QQQQ" > $DIR/$tfile
20577         cat $DIR/$tfile > /dev/null
20578         cat $DIR/$tfile > /dev/null
20579         cat $DIR/$tfile > /dev/null
20580         cat $DIR/$tfile > /dev/null
20581
20582         out=$($LFS heat_get $DIR/$tfile)
20583         $LFS heat_get $DIR/$tfile
20584         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20585         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20586         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20587         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20588
20589         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20590         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20591         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20592         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20593
20594         $LFS heat_set -c $DIR/$tfile
20595         $LCTL set_param -n llite.*.file_heat=0
20596         echo "Turn off file heat support for the Lustre filesystem"
20597
20598         echo "QQQQ" > $DIR/$tfile
20599         echo "QQQQ" > $DIR/$tfile
20600         echo "QQQQ" > $DIR/$tfile
20601         cat $DIR/$tfile > /dev/null
20602         cat $DIR/$tfile > /dev/null
20603         cat $DIR/$tfile > /dev/null
20604         cat $DIR/$tfile > /dev/null
20605
20606         out=$($LFS heat_get $DIR/$tfile)
20607         $LFS heat_get $DIR/$tfile
20608         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20609         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20610         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20611         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20612
20613         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20614         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20615         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20616         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20617
20618         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20619         rm -f $DIR/$tfile
20620 }
20621 run_test 813 "File heat verfication"
20622
20623 #
20624 # tests that do cleanup/setup should be run at the end
20625 #
20626
20627 test_900() {
20628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20629         local ls
20630
20631         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20632         $LCTL set_param fail_loc=0x903
20633
20634         cancel_lru_locks MGC
20635
20636         FAIL_ON_ERROR=true cleanup
20637         FAIL_ON_ERROR=true setup
20638 }
20639 run_test 900 "umount should not race with any mgc requeue thread"
20640
20641 complete $SECONDS
20642 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20643 check_and_cleanup_lustre
20644 if [ "$I_MOUNTED" != "yes" ]; then
20645         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20646 fi
20647 exit_status