Whamcloud - gitweb
LU-11403 llite: ll_fault fixes
[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_56p() {
5084         [ $RUNAS_ID -eq $UID ] &&
5085                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5086
5087         local dir=$DIR/$tdir
5088
5089         setup_56 $dir $NUMFILES $NUMDIRS
5090         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5091
5092         local expected=$NUMFILES
5093         local cmd="$LFS find -uid $RUNAS_ID $dir"
5094         local nums=$($cmd | wc -l)
5095
5096         [ $nums -eq $expected ] ||
5097                 error "'$cmd' wrong: found $nums, expected $expected"
5098
5099         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5100         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5101         nums=$($cmd | wc -l)
5102         [ $nums -eq $expected ] ||
5103                 error "'$cmd' wrong: found $nums, expected $expected"
5104 }
5105 run_test 56p "check lfs find -uid and ! -uid"
5106
5107 test_56q() {
5108         [ $RUNAS_ID -eq $UID ] &&
5109                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5110
5111         local dir=$DIR/$tdir
5112
5113         setup_56 $dir $NUMFILES $NUMDIRS
5114         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5115
5116         local expected=$NUMFILES
5117         local cmd="$LFS find -gid $RUNAS_GID $dir"
5118         local nums=$($cmd | wc -l)
5119
5120         [ $nums -eq $expected ] ||
5121                 error "'$cmd' wrong: found $nums, expected $expected"
5122
5123         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5124         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5125         nums=$($cmd | wc -l)
5126         [ $nums -eq $expected ] ||
5127                 error "'$cmd' wrong: found $nums, expected $expected"
5128 }
5129 run_test 56q "check lfs find -gid and ! -gid"
5130
5131 test_56r() {
5132         local dir=$DIR/$tdir
5133
5134         setup_56 $dir $NUMFILES $NUMDIRS
5135
5136         local expected=12
5137         local cmd="$LFS find -size 0 -type f $dir"
5138         local nums=$($cmd | wc -l)
5139
5140         [ $nums -eq $expected ] ||
5141                 error "'$cmd' wrong: found $nums, expected $expected"
5142         expected=0
5143         cmd="$LFS find ! -size 0 -type f $dir"
5144         nums=$($cmd | wc -l)
5145         [ $nums -eq $expected ] ||
5146                 error "'$cmd' wrong: found $nums, expected $expected"
5147         echo "test" > $dir/$tfile
5148         echo "test2" > $dir/$tfile.2 && sync
5149         expected=1
5150         cmd="$LFS find -size 5 -type f $dir"
5151         nums=$($cmd | wc -l)
5152         [ $nums -eq $expected ] ||
5153                 error "'$cmd' wrong: found $nums, expected $expected"
5154         expected=1
5155         cmd="$LFS find -size +5 -type f $dir"
5156         nums=$($cmd | wc -l)
5157         [ $nums -eq $expected ] ||
5158                 error "'$cmd' wrong: found $nums, expected $expected"
5159         expected=2
5160         cmd="$LFS find -size +0 -type f $dir"
5161         nums=$($cmd | wc -l)
5162         [ $nums -eq $expected ] ||
5163                 error "'$cmd' wrong: found $nums, expected $expected"
5164         expected=2
5165         cmd="$LFS find ! -size -5 -type f $dir"
5166         nums=$($cmd | wc -l)
5167         [ $nums -eq $expected ] ||
5168                 error "'$cmd' wrong: found $nums, expected $expected"
5169         expected=12
5170         cmd="$LFS find -size -5 -type f $dir"
5171         nums=$($cmd | wc -l)
5172         [ $nums -eq $expected ] ||
5173                 error "'$cmd' wrong: found $nums, expected $expected"
5174 }
5175 run_test 56r "check lfs find -size works"
5176
5177 test_56s() { # LU-611 #LU-9369
5178         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5179
5180         local dir=$DIR/$tdir
5181         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5182
5183         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5184         for i in $(seq $NUMDIRS); do
5185                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5186         done
5187
5188         local expected=$NUMDIRS
5189         local cmd="$LFS find -c $OSTCOUNT $dir"
5190         local nums=$($cmd | wc -l)
5191
5192         [ $nums -eq $expected ] || {
5193                 $LFS getstripe -R $dir
5194                 error "'$cmd' wrong: found $nums, expected $expected"
5195         }
5196
5197         expected=$((NUMDIRS + onestripe))
5198         cmd="$LFS find -stripe-count +0 -type f $dir"
5199         nums=$($cmd | wc -l)
5200         [ $nums -eq $expected ] || {
5201                 $LFS getstripe -R $dir
5202                 error "'$cmd' wrong: found $nums, expected $expected"
5203         }
5204
5205         expected=$onestripe
5206         cmd="$LFS find -stripe-count 1 -type f $dir"
5207         nums=$($cmd | wc -l)
5208         [ $nums -eq $expected ] || {
5209                 $LFS getstripe -R $dir
5210                 error "'$cmd' wrong: found $nums, expected $expected"
5211         }
5212
5213         cmd="$LFS find -stripe-count -2 -type f $dir"
5214         nums=$($cmd | wc -l)
5215         [ $nums -eq $expected ] || {
5216                 $LFS getstripe -R $dir
5217                 error "'$cmd' wrong: found $nums, expected $expected"
5218         }
5219
5220         expected=0
5221         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5222         nums=$($cmd | wc -l)
5223         [ $nums -eq $expected ] || {
5224                 $LFS getstripe -R $dir
5225                 error "'$cmd' wrong: found $nums, expected $expected"
5226         }
5227 }
5228 run_test 56s "check lfs find -stripe-count works"
5229
5230 test_56t() { # LU-611 #LU-9369
5231         local dir=$DIR/$tdir
5232
5233         setup_56 $dir 0 $NUMDIRS
5234         for i in $(seq $NUMDIRS); do
5235                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5236         done
5237
5238         local expected=$NUMDIRS
5239         local cmd="$LFS find -S 8M $dir"
5240         local nums=$($cmd | wc -l)
5241
5242         [ $nums -eq $expected ] || {
5243                 $LFS getstripe -R $dir
5244                 error "'$cmd' wrong: found $nums, expected $expected"
5245         }
5246         rm -rf $dir
5247
5248         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5249
5250         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5251
5252         expected=$(((NUMDIRS + 1) * NUMFILES))
5253         cmd="$LFS find -stripe-size 512k -type f $dir"
5254         nums=$($cmd | wc -l)
5255         [ $nums -eq $expected ] ||
5256                 error "'$cmd' wrong: found $nums, expected $expected"
5257
5258         cmd="$LFS find -stripe-size +320k -type f $dir"
5259         nums=$($cmd | wc -l)
5260         [ $nums -eq $expected ] ||
5261                 error "'$cmd' wrong: found $nums, expected $expected"
5262
5263         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5264         cmd="$LFS find -stripe-size +200k -type f $dir"
5265         nums=$($cmd | wc -l)
5266         [ $nums -eq $expected ] ||
5267                 error "'$cmd' wrong: found $nums, expected $expected"
5268
5269         cmd="$LFS find -stripe-size -640k -type f $dir"
5270         nums=$($cmd | wc -l)
5271         [ $nums -eq $expected ] ||
5272                 error "'$cmd' wrong: found $nums, expected $expected"
5273
5274         expected=4
5275         cmd="$LFS find -stripe-size 256k -type f $dir"
5276         nums=$($cmd | wc -l)
5277         [ $nums -eq $expected ] ||
5278                 error "'$cmd' wrong: found $nums, expected $expected"
5279
5280         cmd="$LFS find -stripe-size -320k -type f $dir"
5281         nums=$($cmd | wc -l)
5282         [ $nums -eq $expected ] ||
5283                 error "'$cmd' wrong: found $nums, expected $expected"
5284
5285         expected=0
5286         cmd="$LFS find -stripe-size 1024k -type f $dir"
5287         nums=$($cmd | wc -l)
5288         [ $nums -eq $expected ] ||
5289                 error "'$cmd' wrong: found $nums, expected $expected"
5290 }
5291 run_test 56t "check lfs find -stripe-size works"
5292
5293 test_56u() { # LU-611
5294         local dir=$DIR/$tdir
5295
5296         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5297
5298         if [[ $OSTCOUNT -gt 1 ]]; then
5299                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5300                 onestripe=4
5301         else
5302                 onestripe=0
5303         fi
5304
5305         local expected=$(((NUMDIRS + 1) * NUMFILES))
5306         local cmd="$LFS find -stripe-index 0 -type f $dir"
5307         local nums=$($cmd | wc -l)
5308
5309         [ $nums -eq $expected ] ||
5310                 error "'$cmd' wrong: found $nums, expected $expected"
5311
5312         expected=$onestripe
5313         cmd="$LFS find -stripe-index 1 -type f $dir"
5314         nums=$($cmd | wc -l)
5315         [ $nums -eq $expected ] ||
5316                 error "'$cmd' wrong: found $nums, expected $expected"
5317
5318         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5319         nums=$($cmd | wc -l)
5320         [ $nums -eq $expected ] ||
5321                 error "'$cmd' wrong: found $nums, expected $expected"
5322
5323         expected=0
5324         # This should produce an error and not return any files
5325         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5326         nums=$($cmd 2>/dev/null | wc -l)
5327         [ $nums -eq $expected ] ||
5328                 error "'$cmd' wrong: found $nums, expected $expected"
5329
5330         if [[ $OSTCOUNT -gt 1 ]]; then
5331                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5332                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5333                 nums=$($cmd | wc -l)
5334                 [ $nums -eq $expected ] ||
5335                         error "'$cmd' wrong: found $nums, expected $expected"
5336         fi
5337 }
5338 run_test 56u "check lfs find -stripe-index works"
5339
5340 test_56v() {
5341         local mdt_idx=0
5342         local dir=$DIR/$tdir
5343
5344         setup_56 $dir $NUMFILES $NUMDIRS
5345
5346         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5347         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5348
5349         for file in $($LFS find -m $UUID $dir); do
5350                 file_midx=$($LFS getstripe -m $file)
5351                 [ $file_midx -eq $mdt_idx ] ||
5352                         error "lfs find -m $UUID != getstripe -m $file_midx"
5353         done
5354 }
5355 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5356
5357 test_56w() {
5358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5360
5361         local dir=$DIR/$tdir
5362
5363         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5364
5365         local stripe_size=$($LFS getstripe -S -d $dir) ||
5366                 error "$LFS getstripe -S -d $dir failed"
5367         stripe_size=${stripe_size%% *}
5368
5369         local file_size=$((stripe_size * OSTCOUNT))
5370         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5371         local required_space=$((file_num * file_size))
5372         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5373                            head -n1)
5374         [[ $free_space -le $((required_space / 1024)) ]] &&
5375                 skip_env "need $required_space, have $free_space kbytes"
5376
5377         local dd_bs=65536
5378         local dd_count=$((file_size / dd_bs))
5379
5380         # write data into the files
5381         local i
5382         local j
5383         local file
5384
5385         for i in $(seq $NUMFILES); do
5386                 file=$dir/file$i
5387                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5388                         error "write data into $file failed"
5389         done
5390         for i in $(seq $NUMDIRS); do
5391                 for j in $(seq $NUMFILES); do
5392                         file=$dir/dir$i/file$j
5393                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5394                                 error "write data into $file failed"
5395                 done
5396         done
5397
5398         # $LFS_MIGRATE will fail if hard link migration is unsupported
5399         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5400                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5401                         error "creating links to $dir/dir1/file1 failed"
5402         fi
5403
5404         local expected=-1
5405
5406         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5407
5408         # lfs_migrate file
5409         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5410
5411         echo "$cmd"
5412         eval $cmd || error "$cmd failed"
5413
5414         check_stripe_count $dir/file1 $expected
5415
5416         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5417         then
5418                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5419                 # OST 1 if it is on OST 0. This file is small enough to
5420                 # be on only one stripe.
5421                 file=$dir/migr_1_ost
5422                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5423                         error "write data into $file failed"
5424                 local obdidx=$($LFS getstripe -i $file)
5425                 local oldmd5=$(md5sum $file)
5426                 local newobdidx=0
5427
5428                 [[ $obdidx -eq 0 ]] && newobdidx=1
5429                 cmd="$LFS migrate -i $newobdidx $file"
5430                 echo $cmd
5431                 eval $cmd || error "$cmd failed"
5432
5433                 local realobdix=$($LFS getstripe -i $file)
5434                 local newmd5=$(md5sum $file)
5435
5436                 [[ $newobdidx -ne $realobdix ]] &&
5437                         error "new OST is different (was=$obdidx, "\
5438                               "wanted=$newobdidx, got=$realobdix)"
5439                 [[ "$oldmd5" != "$newmd5" ]] &&
5440                         error "md5sum differ: $oldmd5, $newmd5"
5441         fi
5442
5443         # lfs_migrate dir
5444         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5445         echo "$cmd"
5446         eval $cmd || error "$cmd failed"
5447
5448         for j in $(seq $NUMFILES); do
5449                 check_stripe_count $dir/dir1/file$j $expected
5450         done
5451
5452         # lfs_migrate works with lfs find
5453         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5454              $LFS_MIGRATE -y -c $expected"
5455         echo "$cmd"
5456         eval $cmd || error "$cmd failed"
5457
5458         for i in $(seq 2 $NUMFILES); do
5459                 check_stripe_count $dir/file$i $expected
5460         done
5461         for i in $(seq 2 $NUMDIRS); do
5462                 for j in $(seq $NUMFILES); do
5463                 check_stripe_count $dir/dir$i/file$j $expected
5464                 done
5465         done
5466 }
5467 run_test 56w "check lfs_migrate -c stripe_count works"
5468
5469 test_56wb() {
5470         local file1=$DIR/$tdir/file1
5471         local create_pool=false
5472         local initial_pool=$($LFS getstripe -p $DIR)
5473         local pool_list=()
5474         local pool=""
5475
5476         echo -n "Creating test dir..."
5477         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5478         echo "done."
5479
5480         echo -n "Creating test file..."
5481         touch $file1 || error "cannot create file"
5482         echo "done."
5483
5484         echo -n "Detecting existing pools..."
5485         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5486
5487         if [ ${#pool_list[@]} -gt 0 ]; then
5488                 echo "${pool_list[@]}"
5489                 for thispool in "${pool_list[@]}"; do
5490                         if [[ -z "$initial_pool" ||
5491                               "$initial_pool" != "$thispool" ]]; then
5492                                 pool="$thispool"
5493                                 echo "Using existing pool '$pool'"
5494                                 break
5495                         fi
5496                 done
5497         else
5498                 echo "none detected."
5499         fi
5500         if [ -z "$pool" ]; then
5501                 pool=${POOL:-testpool}
5502                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5503                 echo -n "Creating pool '$pool'..."
5504                 create_pool=true
5505                 pool_add $pool &> /dev/null ||
5506                         error "pool_add failed"
5507                 echo "done."
5508
5509                 echo -n "Adding target to pool..."
5510                 pool_add_targets $pool 0 0 1 &> /dev/null ||
5511                         error "pool_add_targets failed"
5512                 echo "done."
5513         fi
5514
5515         echo -n "Setting pool using -p option..."
5516         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
5517                 error "migrate failed rc = $?"
5518         echo "done."
5519
5520         echo -n "Verifying test file is in pool after migrating..."
5521         [ "$($LFS getstripe -p $file1)" = $pool ] ||
5522                 error "file was not migrated to pool $pool"
5523         echo "done."
5524
5525         echo -n "Removing test file from pool '$pool'..."
5526         $LFS migrate $file1 &> /dev/null ||
5527                 error "cannot remove from pool"
5528         [ "$($LFS getstripe -p $file1)" ] &&
5529                 error "pool still set"
5530         echo "done."
5531
5532         echo -n "Setting pool using --pool option..."
5533         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
5534                 error "migrate failed rc = $?"
5535         echo "done."
5536
5537         # Clean up
5538         rm -f $file1
5539         if $create_pool; then
5540                 destroy_test_pools 2> /dev/null ||
5541                         error "destroy test pools failed"
5542         fi
5543 }
5544 run_test 56wb "check lfs_migrate pool support"
5545
5546 test_56wc() {
5547         local file1="$DIR/$tdir/file1"
5548
5549         echo -n "Creating test dir..."
5550         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5551         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
5552         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5553                 error "cannot set stripe"
5554         echo "done"
5555
5556         echo -n "Setting initial stripe for test file..."
5557         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
5558                 error "cannot set stripe"
5559         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5560                 error "stripe size not set"
5561         echo "done."
5562
5563         # File currently set to -S 512K -c 1
5564
5565         # Ensure -c and -S options are rejected when -R is set
5566         echo -n "Verifying incompatible options are detected..."
5567         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
5568                 error "incompatible -c and -R options not detected"
5569         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
5570                 error "incompatible -S and -R options not detected"
5571         echo "done."
5572
5573         # Ensure unrecognized options are passed through to 'lfs migrate'
5574         echo -n "Verifying -S option is passed through to lfs migrate..."
5575         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
5576                 error "migration failed"
5577         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
5578                 error "file was not restriped"
5579         echo "done."
5580
5581         # File currently set to -S 1M -c 1
5582
5583         # Ensure long options are supported
5584         echo -n "Verifying long options supported..."
5585         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
5586                 error "long option without argument not supported"
5587         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
5588                 error "long option with argument not supported"
5589         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
5590                 error "file not restriped with --stripe-size option"
5591         echo "done."
5592
5593         # File currently set to -S 512K -c 1
5594
5595         if [ "$OSTCOUNT" -gt 1 ]; then
5596                 echo -n "Verifying explicit stripe count can be set..."
5597                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
5598                         error "migrate failed"
5599                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
5600                         error "file not restriped to explicit count"
5601                 echo "done."
5602         fi
5603
5604         # File currently set to -S 512K -c 1 or -S 512K -c 2
5605
5606         # Ensure parent striping is used if -R is set, and no stripe
5607         # count or size is specified
5608         echo -n "Setting stripe for parent directory..."
5609         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
5610                 error "cannot set stripe"
5611         echo "done."
5612
5613         echo -n "Verifying restripe option uses parent stripe settings..."
5614         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
5615                 error "migrate failed"
5616         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
5617                 error "file not restriped to parent settings"
5618         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
5619                 error "file not restriped to parent settings"
5620         echo "done."
5621
5622         # File currently set to -S 1M -c 1
5623
5624         # Ensure striping is preserved if -R is not set, and no stripe
5625         # count or size is specified
5626         echo -n "Verifying striping size preserved when not specified..."
5627         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
5628         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
5629                 error "cannot set stripe on parent directory"
5630         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5631                 error "migrate failed"
5632         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
5633                 error "file was restriped"
5634         echo "done."
5635
5636         # Ensure file name properly detected when final option has no argument
5637         echo -n "Verifying file name properly detected..."
5638         $LFS_MIGRATE -y "$file1" &> /dev/null ||
5639                 error "file name interpreted as option argument"
5640         echo "done."
5641
5642         # Clean up
5643         rm -f "$file1"
5644 }
5645 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
5646
5647 test_56wd() {
5648         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5649
5650         local file1=$DIR/$tdir/file1
5651
5652         echo -n "Creating test dir..."
5653         test_mkdir $DIR/$tdir || error "cannot create dir"
5654         echo "done."
5655
5656         echo -n "Creating test file..."
5657         touch $file1
5658         echo "done."
5659
5660         # Ensure 'lfs migrate' will fail by using a non-existent option,
5661         # and make sure rsync is not called to recover
5662         echo -n "Make sure --no-rsync option works..."
5663         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
5664                 grep -q 'refusing to fall back to rsync' ||
5665                 error "rsync was called with --no-rsync set"
5666         echo "done."
5667
5668         # Ensure rsync is called without trying 'lfs migrate' first
5669         echo -n "Make sure --rsync option works..."
5670         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
5671                 grep -q 'falling back to rsync' &&
5672                 error "lfs migrate was called with --rsync set"
5673         echo "done."
5674
5675         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
5676         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
5677                 grep -q 'at the same time' ||
5678                 error "--rsync and --no-rsync accepted concurrently"
5679         echo "done."
5680
5681         # Clean up
5682         rm -f $file1
5683 }
5684 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
5685
5686 test_56x() {
5687         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5688         check_swap_layouts_support
5689
5690         local dir=$DIR/$tdir
5691         local ref1=/etc/passwd
5692         local file1=$dir/file1
5693
5694         test_mkdir $dir || error "creating dir $dir"
5695         $LFS setstripe -c 2 $file1
5696         cp $ref1 $file1
5697         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
5698         stripe=$($LFS getstripe -c $file1)
5699         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5700         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5701
5702         # clean up
5703         rm -f $file1
5704 }
5705 run_test 56x "lfs migration support"
5706
5707 test_56xa() {
5708         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5709         check_swap_layouts_support
5710
5711         local dir=$DIR/$tdir/$testnum
5712
5713         test_mkdir -p $dir
5714
5715         local ref1=/etc/passwd
5716         local file1=$dir/file1
5717
5718         $LFS setstripe -c 2 $file1
5719         cp $ref1 $file1
5720         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
5721
5722         local stripe=$($LFS getstripe -c $file1)
5723
5724         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
5725         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
5726
5727         # clean up
5728         rm -f $file1
5729 }
5730 run_test 56xa "lfs migration --block support"
5731
5732 check_migrate_links() {
5733         local dir="$1"
5734         local file1="$dir/file1"
5735         local begin="$2"
5736         local count="$3"
5737         local total_count=$(($begin + $count - 1))
5738         local symlink_count=10
5739         local uniq_count=10
5740
5741         if [ ! -f "$file1" ]; then
5742                 echo -n "creating initial file..."
5743                 $LFS setstripe -c 1 -S "512k" "$file1" ||
5744                         error "cannot setstripe initial file"
5745                 echo "done"
5746
5747                 echo -n "creating symlinks..."
5748                 for s in $(seq 1 $symlink_count); do
5749                         ln -s "$file1" "$dir/slink$s" ||
5750                                 error "cannot create symlinks"
5751                 done
5752                 echo "done"
5753
5754                 echo -n "creating nonlinked files..."
5755                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
5756                         error "cannot create nonlinked files"
5757                 echo "done"
5758         fi
5759
5760         # create hard links
5761         if [ ! -f "$dir/file$total_count" ]; then
5762                 echo -n "creating hard links $begin:$total_count..."
5763                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
5764                         /dev/null || error "cannot create hard links"
5765                 echo "done"
5766         fi
5767
5768         echo -n "checking number of hard links listed in xattrs..."
5769         local fid=$($LFS getstripe -F "$file1")
5770         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
5771
5772         echo "${#paths[*]}"
5773         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
5774                         skip "hard link list has unexpected size, skipping test"
5775         fi
5776         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
5777                         error "link names should exceed xattrs size"
5778         fi
5779
5780         echo -n "migrating files..."
5781         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
5782         local rc=$?
5783         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
5784         echo "done"
5785
5786         # make sure all links have been properly migrated
5787         echo -n "verifying files..."
5788         fid=$($LFS getstripe -F "$file1") ||
5789                 error "cannot get fid for file $file1"
5790         for i in $(seq 2 $total_count); do
5791                 local fid2=$($LFS getstripe -F $dir/file$i)
5792
5793                 [ "$fid2" == "$fid" ] ||
5794                         error "migrated hard link has mismatched FID"
5795         done
5796
5797         # make sure hard links were properly detected, and migration was
5798         # performed only once for the entire link set; nonlinked files should
5799         # also be migrated
5800         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
5801         local expected=$(($uniq_count + 1))
5802
5803         [ "$actual" -eq  "$expected" ] ||
5804                 error "hard links individually migrated ($actual != $expected)"
5805
5806         # make sure the correct number of hard links are present
5807         local hardlinks=$(stat -c '%h' "$file1")
5808
5809         [ $hardlinks -eq $total_count ] ||
5810                 error "num hard links $hardlinks != $total_count"
5811         echo "done"
5812
5813         return 0
5814 }
5815
5816 test_56xb() {
5817         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
5818                 skip "Need MDS version at least 2.10.55"
5819
5820         local dir="$DIR/$tdir"
5821
5822         test_mkdir "$dir" || error "cannot create dir $dir"
5823
5824         echo "testing lfs migrate mode when all links fit within xattrs"
5825         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
5826
5827         echo "testing rsync mode when all links fit within xattrs"
5828         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
5829
5830         echo "testing lfs migrate mode when all links do not fit within xattrs"
5831         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
5832
5833         echo "testing rsync mode when all links do not fit within xattrs"
5834         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
5835
5836
5837         # clean up
5838         rm -rf $dir
5839 }
5840 run_test 56xb "lfs migration hard link support"
5841
5842 test_56xc() {
5843         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5844
5845         local dir="$DIR/$tdir"
5846
5847         test_mkdir "$dir" || error "cannot create dir $dir"
5848
5849         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
5850         echo -n "Setting initial stripe for 20MB test file..."
5851         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
5852         echo "done"
5853         echo -n "Sizing 20MB test file..."
5854         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
5855         echo "done"
5856         echo -n "Verifying small file autostripe count is 1..."
5857         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
5858                 error "cannot migrate 20MB file"
5859         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
5860                 error "cannot get stripe for $dir/20mb"
5861         [ $stripe_count -eq 1 ] ||
5862                 error "unexpected stripe count $stripe_count for 20MB file"
5863         rm -f "$dir/20mb"
5864         echo "done"
5865
5866         # Test 2: File is small enough to fit within the available space on
5867         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
5868         # have at least an additional 1KB for each desired stripe for test 3
5869         echo -n "Setting stripe for 1GB test file..."
5870         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
5871         echo "done"
5872         echo -n "Sizing 1GB test file..."
5873         # File size is 1GB + 3KB
5874         truncate "$dir/1gb" 1073744896 &> /dev/null ||
5875                 error "cannot create 1GB test file"
5876         echo "done"
5877         echo -n "Migrating 1GB file..."
5878         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
5879                 error "cannot migrate file"
5880         echo "done"
5881         echo -n "Verifying autostripe count is sqrt(n) + 1..."
5882         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
5883                 error "cannot get stripe for $dir/1gb"
5884         [ $stripe_count -eq 2 ] ||
5885                 error "unexpected stripe count $stripe_count (expected 2)"
5886         echo "done"
5887
5888         # Test 3: File is too large to fit within the available space on
5889         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
5890         if [ $OSTCOUNT -ge 3 ]; then
5891                 # The required available space is calculated as
5892                 # file size (1GB + 3KB) / OST count (3).
5893                 local kb_per_ost=349526
5894
5895                 echo -n "Migrating 1GB file..."
5896                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
5897                         /dev/null || error "cannot migrate file"
5898                 echo "done"
5899
5900                 stripe_count=$($LFS getstripe -c "$dir/1gb")
5901                 echo -n "Verifying autostripe count with limited space..."
5902                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
5903                         error "unexpected stripe count $stripe_count (wanted 3)"
5904                 echo "done"
5905         fi
5906
5907         # clean up
5908         rm -rf $dir
5909 }
5910 run_test 56xc "lfs migration autostripe"
5911
5912 test_56y() {
5913         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
5914                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
5915
5916         local res=""
5917         local dir=$DIR/$tdir
5918         local f1=$dir/file1
5919         local f2=$dir/file2
5920
5921         test_mkdir -p $dir || error "creating dir $dir"
5922         touch $f1 || error "creating std file $f1"
5923         $MULTIOP $f2 H2c || error "creating released file $f2"
5924
5925         # a directory can be raid0, so ask only for files
5926         res=$($LFS find $dir -L raid0 -type f | wc -l)
5927         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
5928
5929         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
5930         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
5931
5932         # only files can be released, so no need to force file search
5933         res=$($LFS find $dir -L released)
5934         [[ $res == $f2 ]] || error "search released: found $res != $f2"
5935
5936         res=$($LFS find $dir -type f \! -L released)
5937         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
5938 }
5939 run_test 56y "lfs find -L raid0|released"
5940
5941 test_56z() { # LU-4824
5942         # This checks to make sure 'lfs find' continues after errors
5943         # There are two classes of errors that should be caught:
5944         # - If multiple paths are provided, all should be searched even if one
5945         #   errors out
5946         # - If errors are encountered during the search, it should not terminate
5947         #   early
5948         local dir=$DIR/$tdir
5949         local i
5950
5951         test_mkdir $dir
5952         for i in d{0..9}; do
5953                 test_mkdir $dir/$i
5954         done
5955         touch $dir/d{0..9}/$tfile
5956         $LFS find $DIR/non_existent_dir $dir &&
5957                 error "$LFS find did not return an error"
5958         # Make a directory unsearchable. This should NOT be the last entry in
5959         # directory order.  Arbitrarily pick the 6th entry
5960         chmod 700 $($LFS find $dir -type d | sed '6!d')
5961
5962         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
5963
5964         # The user should be able to see 10 directories and 9 files
5965         [ $count == 19 ] || error "$LFS find did not continue after error"
5966 }
5967 run_test 56z "lfs find should continue after an error"
5968
5969 test_56aa() { # LU-5937
5970         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
5971
5972         local dir=$DIR/$tdir
5973
5974         mkdir $dir
5975         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
5976
5977         createmany -o $dir/striped_dir/${tfile}- 1024
5978         local dirs=$($LFS find --size +8k $dir/)
5979
5980         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
5981 }
5982 run_test 56aa "lfs find --size under striped dir"
5983
5984 test_56ab() { # LU-10705
5985         test_mkdir $DIR/$tdir
5986         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
5987         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
5988         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
5989         # Flush writes to ensure valid blocks.  Need to be more thorough for
5990         # ZFS, since blocks are not allocated/returned to client immediately.
5991         sync_all_data
5992         wait_zfs_commit ost1 2
5993         cancel_lru_locks osc
5994         ls -ls $DIR/$tdir
5995
5996         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
5997
5998         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
5999
6000         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6001         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6002
6003         rm -f $DIR/$tdir/$tfile.[123]
6004 }
6005 run_test 56ab "lfs find --blocks"
6006
6007 test_56ba() {
6008         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6009                 skip "Need MDS version at least 2.10.50"
6010
6011         # Create composite files with one component
6012         local dir=$DIR/$tdir
6013
6014         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6015         # Create composite files with three components
6016         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6017         # Create non-composite files
6018         createmany -o $dir/${tfile}- 10
6019
6020         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6021
6022         [[ $nfiles == 10 ]] ||
6023                 error "lfs find -E 1M found $nfiles != 10 files"
6024
6025         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6026         [[ $nfiles == 25 ]] ||
6027                 error "lfs find ! -E 1M found $nfiles != 25 files"
6028
6029         # All files have a component that starts at 0
6030         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6031         [[ $nfiles == 35 ]] ||
6032                 error "lfs find --component-start 0 - $nfiles != 35 files"
6033
6034         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6035         [[ $nfiles == 15 ]] ||
6036                 error "lfs find --component-start 2M - $nfiles != 15 files"
6037
6038         # All files created here have a componenet that does not starts at 2M
6039         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6040         [[ $nfiles == 35 ]] ||
6041                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6042
6043         # Find files with a specified number of components
6044         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6045         [[ $nfiles == 15 ]] ||
6046                 error "lfs find --component-count 3 - $nfiles != 15 files"
6047
6048         # Remember non-composite files have a component count of zero
6049         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6050         [[ $nfiles == 10 ]] ||
6051                 error "lfs find --component-count 0 - $nfiles != 10 files"
6052
6053         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6054         [[ $nfiles == 20 ]] ||
6055                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6056
6057         # All files have a flag called "init"
6058         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6059         [[ $nfiles == 35 ]] ||
6060                 error "lfs find --component-flags init - $nfiles != 35 files"
6061
6062         # Multi-component files will have a component not initialized
6063         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6064         [[ $nfiles == 15 ]] ||
6065                 error "lfs find !--component-flags init - $nfiles != 15 files"
6066
6067         rm -rf $dir
6068
6069 }
6070 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6071
6072 test_56ca() {
6073         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6074                 skip "Need MDS version at least 2.10.57"
6075
6076         local td=$DIR/$tdir
6077         local tf=$td/$tfile
6078         local dir
6079         local nfiles
6080         local cmd
6081         local i
6082         local j
6083
6084         # create mirrored directories and mirrored files
6085         mkdir $td || error "mkdir $td failed"
6086         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6087         createmany -o $tf- 10 || error "create $tf- failed"
6088
6089         for i in $(seq 2); do
6090                 dir=$td/dir$i
6091                 mkdir $dir || error "mkdir $dir failed"
6092                 $LFS mirror create -N$((3 + i)) $dir ||
6093                         error "create mirrored dir $dir failed"
6094                 createmany -o $dir/$tfile- 10 ||
6095                         error "create $dir/$tfile- failed"
6096         done
6097
6098         # change the states of some mirrored files
6099         echo foo > $tf-6
6100         for i in $(seq 2); do
6101                 dir=$td/dir$i
6102                 for j in $(seq 4 9); do
6103                         echo foo > $dir/$tfile-$j
6104                 done
6105         done
6106
6107         # find mirrored files with specific mirror count
6108         cmd="$LFS find --mirror-count 3 --type f $td"
6109         nfiles=$($cmd | wc -l)
6110         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6111
6112         cmd="$LFS find ! --mirror-count 3 --type f $td"
6113         nfiles=$($cmd | wc -l)
6114         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6115
6116         cmd="$LFS find --mirror-count +2 --type f $td"
6117         nfiles=$($cmd | wc -l)
6118         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6119
6120         cmd="$LFS find --mirror-count -6 --type f $td"
6121         nfiles=$($cmd | wc -l)
6122         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6123
6124         # find mirrored files with specific file state
6125         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6126         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6127
6128         cmd="$LFS find --mirror-state=ro --type f $td"
6129         nfiles=$($cmd | wc -l)
6130         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6131
6132         cmd="$LFS find ! --mirror-state=ro --type f $td"
6133         nfiles=$($cmd | wc -l)
6134         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6135
6136         cmd="$LFS find --mirror-state=wp --type f $td"
6137         nfiles=$($cmd | wc -l)
6138         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6139
6140         cmd="$LFS find ! --mirror-state=sp --type f $td"
6141         nfiles=$($cmd | wc -l)
6142         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6143 }
6144 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6145
6146 test_57a() {
6147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6148         # note test will not do anything if MDS is not local
6149         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6150                 skip_env "ldiskfs only test"
6151         fi
6152         remote_mds_nodsh && skip "remote MDS with nodsh"
6153
6154         local MNTDEV="osd*.*MDT*.mntdev"
6155         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6156         [ -z "$DEV" ] && error "can't access $MNTDEV"
6157         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6158                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6159                         error "can't access $DEV"
6160                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6161                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6162                 rm $TMP/t57a.dump
6163         done
6164 }
6165 run_test 57a "verify MDS filesystem created with large inodes =="
6166
6167 test_57b() {
6168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6169         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6170                 skip_env "ldiskfs only test"
6171         fi
6172         remote_mds_nodsh && skip "remote MDS with nodsh"
6173
6174         local dir=$DIR/$tdir
6175         local filecount=100
6176         local file1=$dir/f1
6177         local fileN=$dir/f$filecount
6178
6179         rm -rf $dir || error "removing $dir"
6180         test_mkdir -c1 $dir
6181         local mdtidx=$($LFS getstripe -m $dir)
6182         local mdtname=MDT$(printf %04x $mdtidx)
6183         local facet=mds$((mdtidx + 1))
6184
6185         echo "mcreating $filecount files"
6186         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6187
6188         # verify that files do not have EAs yet
6189         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6190                 error "$file1 has an EA"
6191         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6192                 error "$fileN has an EA"
6193
6194         sync
6195         sleep 1
6196         df $dir  #make sure we get new statfs data
6197         local mdsfree=$(do_facet $facet \
6198                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6199         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6200         local file
6201
6202         echo "opening files to create objects/EAs"
6203         for file in $(seq -f $dir/f%g 1 $filecount); do
6204                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6205                         error "opening $file"
6206         done
6207
6208         # verify that files have EAs now
6209         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6210         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6211
6212         sleep 1  #make sure we get new statfs data
6213         df $dir
6214         local mdsfree2=$(do_facet $facet \
6215                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6216         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6217
6218         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6219                 if [ "$mdsfree" != "$mdsfree2" ]; then
6220                         error "MDC before $mdcfree != after $mdcfree2"
6221                 else
6222                         echo "MDC before $mdcfree != after $mdcfree2"
6223                         echo "unable to confirm if MDS has large inodes"
6224                 fi
6225         fi
6226         rm -rf $dir
6227 }
6228 run_test 57b "default LOV EAs are stored inside large inodes ==="
6229
6230 test_58() {
6231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6232         [ -z "$(which wiretest 2>/dev/null)" ] &&
6233                         skip_env "could not find wiretest"
6234
6235         wiretest
6236 }
6237 run_test 58 "verify cross-platform wire constants =============="
6238
6239 test_59() {
6240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6241
6242         echo "touch 130 files"
6243         createmany -o $DIR/f59- 130
6244         echo "rm 130 files"
6245         unlinkmany $DIR/f59- 130
6246         sync
6247         # wait for commitment of removal
6248         wait_delete_completed
6249 }
6250 run_test 59 "verify cancellation of llog records async ========="
6251
6252 TEST60_HEAD="test_60 run $RANDOM"
6253 test_60a() {
6254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6255         remote_mgs_nodsh && skip "remote MGS with nodsh"
6256         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6257                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6258                         skip_env "missing subtest run-llog.sh"
6259
6260         log "$TEST60_HEAD - from kernel mode"
6261         do_facet mgs "$LCTL dk > /dev/null"
6262         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6263         do_facet mgs $LCTL dk > $TMP/$tfile
6264
6265         # LU-6388: test llog_reader
6266         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6267         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6268         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6269                         skip_env "missing llog_reader"
6270         local fstype=$(facet_fstype mgs)
6271         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6272                 skip_env "Only for ldiskfs or zfs type mgs"
6273
6274         local mntpt=$(facet_mntpt mgs)
6275         local mgsdev=$(mgsdevname 1)
6276         local fid_list
6277         local fid
6278         local rec_list
6279         local rec
6280         local rec_type
6281         local obj_file
6282         local path
6283         local seq
6284         local oid
6285         local pass=true
6286
6287         #get fid and record list
6288         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6289                 tail -n 4))
6290         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6291                 tail -n 4))
6292         #remount mgs as ldiskfs or zfs type
6293         stop mgs || error "stop mgs failed"
6294         mount_fstype mgs || error "remount mgs failed"
6295         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6296                 fid=${fid_list[i]}
6297                 rec=${rec_list[i]}
6298                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6299                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6300                 oid=$((16#$oid))
6301
6302                 case $fstype in
6303                         ldiskfs )
6304                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6305                         zfs )
6306                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6307                 esac
6308                 echo "obj_file is $obj_file"
6309                 do_facet mgs $llog_reader $obj_file
6310
6311                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6312                         awk '{ print $3 }' | sed -e "s/^type=//g")
6313                 if [ $rec_type != $rec ]; then
6314                         echo "FAILED test_60a wrong record type $rec_type," \
6315                               "should be $rec"
6316                         pass=false
6317                         break
6318                 fi
6319
6320                 #check obj path if record type is LLOG_LOGID_MAGIC
6321                 if [ "$rec" == "1064553b" ]; then
6322                         path=$(do_facet mgs $llog_reader $obj_file |
6323                                 grep "path=" | awk '{ print $NF }' |
6324                                 sed -e "s/^path=//g")
6325                         if [ $obj_file != $mntpt/$path ]; then
6326                                 echo "FAILED test_60a wrong obj path" \
6327                                       "$montpt/$path, should be $obj_file"
6328                                 pass=false
6329                                 break
6330                         fi
6331                 fi
6332         done
6333         rm -f $TMP/$tfile
6334         #restart mgs before "error", otherwise it will block the next test
6335         stop mgs || error "stop mgs failed"
6336         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6337         $pass || error "test failed, see FAILED test_60a messages for specifics"
6338 }
6339 run_test 60a "llog_test run from kernel module and test llog_reader"
6340
6341 test_60b() { # bug 6411
6342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6343
6344         dmesg > $DIR/$tfile
6345         LLOG_COUNT=$(do_facet mgs dmesg |
6346                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6347                           /llog_[a-z]*.c:[0-9]/ {
6348                                 if (marker)
6349                                         from_marker++
6350                                 from_begin++
6351                           }
6352                           END {
6353                                 if (marker)
6354                                         print from_marker
6355                                 else
6356                                         print from_begin
6357                           }")
6358
6359         [[ $LLOG_COUNT -gt 120 ]] &&
6360                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6361 }
6362 run_test 60b "limit repeated messages from CERROR/CWARN"
6363
6364 test_60c() {
6365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6366
6367         echo "create 5000 files"
6368         createmany -o $DIR/f60c- 5000
6369 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6370         lctl set_param fail_loc=0x80000137
6371         unlinkmany $DIR/f60c- 5000
6372         lctl set_param fail_loc=0
6373 }
6374 run_test 60c "unlink file when mds full"
6375
6376 test_60d() {
6377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6378
6379         SAVEPRINTK=$(lctl get_param -n printk)
6380         # verify "lctl mark" is even working"
6381         MESSAGE="test message ID $RANDOM $$"
6382         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6383         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6384
6385         lctl set_param printk=0 || error "set lnet.printk failed"
6386         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6387         MESSAGE="new test message ID $RANDOM $$"
6388         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6389         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6390         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6391
6392         lctl set_param -n printk="$SAVEPRINTK"
6393 }
6394 run_test 60d "test printk console message masking"
6395
6396 test_60e() {
6397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6398         remote_mds_nodsh && skip "remote MDS with nodsh"
6399
6400         touch $DIR/$tfile
6401 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6402         do_facet mds1 lctl set_param fail_loc=0x15b
6403         rm $DIR/$tfile
6404 }
6405 run_test 60e "no space while new llog is being created"
6406
6407 test_60g() {
6408         local pid
6409
6410         test_mkdir -c $MDSCOUNT $DIR/$tdir
6411         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6412
6413         (
6414                 local index=0
6415                 while true; do
6416                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6417                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6418                         index=$((index + 1))
6419                 done
6420         ) &
6421
6422         pid=$!
6423
6424         for i in $(seq 100); do 
6425                 # define OBD_FAIL_OSD_TXN_START    0x19a
6426                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6427                 usleep 100
6428         done
6429
6430         kill -9 $pid
6431
6432         mkdir $DIR/$tdir/new || error "mkdir failed"
6433         rmdir $DIR/$tdir/new || error "rmdir failed"
6434 }
6435 run_test 60g "transaction abort won't cause MDT hung"
6436
6437 test_61a() {
6438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6439
6440         f="$DIR/f61"
6441         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6442         cancel_lru_locks osc
6443         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6444         sync
6445 }
6446 run_test 61a "mmap() writes don't make sync hang ================"
6447
6448 test_61b() {
6449         mmap_mknod_test $tfile || error "mmap_mknod_test failed"
6450 }
6451 run_test 61b "mmap() of unstriped file is successful"
6452
6453 # bug 2330 - insufficient obd_match error checking causes LBUG
6454 test_62() {
6455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6456
6457         f="$DIR/f62"
6458         echo foo > $f
6459         cancel_lru_locks osc
6460         lctl set_param fail_loc=0x405
6461         cat $f && error "cat succeeded, expect -EIO"
6462         lctl set_param fail_loc=0
6463 }
6464 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6465 # match every page all of the time.
6466 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6467
6468 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6469 # Though this test is irrelevant anymore, it helped to reveal some
6470 # other grant bugs (LU-4482), let's keep it.
6471 test_63a() {   # was test_63
6472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6473
6474         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
6475
6476         for i in `seq 10` ; do
6477                 dd if=/dev/zero of=$DIR/f63 bs=8k &
6478                 sleep 5
6479                 kill $!
6480                 sleep 1
6481         done
6482
6483         rm -f $DIR/f63 || true
6484 }
6485 run_test 63a "Verify oig_wait interruption does not crash ======="
6486
6487 # bug 2248 - async write errors didn't return to application on sync
6488 # bug 3677 - async write errors left page locked
6489 test_63b() {
6490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6491
6492         debugsave
6493         lctl set_param debug=-1
6494
6495         # ensure we have a grant to do async writes
6496         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
6497         rm $DIR/$tfile
6498
6499         sync    # sync lest earlier test intercept the fail_loc
6500
6501         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
6502         lctl set_param fail_loc=0x80000406
6503         $MULTIOP $DIR/$tfile Owy && \
6504                 error "sync didn't return ENOMEM"
6505         sync; sleep 2; sync     # do a real sync this time to flush page
6506         lctl get_param -n llite.*.dump_page_cache | grep locked && \
6507                 error "locked page left in cache after async error" || true
6508         debugrestore
6509 }
6510 run_test 63b "async write errors should be returned to fsync ==="
6511
6512 test_64a () {
6513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6514
6515         df $DIR
6516         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
6517 }
6518 run_test 64a "verify filter grant calculations (in kernel) ====="
6519
6520 test_64b () {
6521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6522
6523         sh oos.sh $MOUNT || error "oos.sh failed: $?"
6524 }
6525 run_test 64b "check out-of-space detection on client"
6526
6527 test_64c() {
6528         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
6529 }
6530 run_test 64c "verify grant shrink"
6531
6532 # this does exactly what osc_request.c:osc_announce_cached() does in
6533 # order to calculate max amount of grants to ask from server
6534 want_grant() {
6535         local tgt=$1
6536
6537         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
6538         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
6539
6540         ((rpc_in_flight ++));
6541         nrpages=$((nrpages * rpc_in_flight))
6542
6543         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
6544
6545         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
6546
6547         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
6548         local undirty=$((nrpages * PAGE_SIZE))
6549
6550         local max_extent_pages
6551         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
6552             grep grant_max_extent_size | awk '{print $2}')
6553         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
6554         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
6555         local grant_extent_tax
6556         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6557             grep grant_extent_tax | awk '{print $2}')
6558
6559         undirty=$((undirty + nrextents * grant_extent_tax))
6560
6561         echo $undirty
6562 }
6563
6564 # this is size of unit for grant allocation. It should be equal to
6565 # what tgt_grant.c:tgt_grant_chunk() calculates
6566 grant_chunk() {
6567         local tgt=$1
6568         local max_brw_size
6569         local grant_extent_tax
6570
6571         max_brw_size=$($LCTL get_param osc.${tgt}.import |
6572             grep max_brw_size | awk '{print $2}')
6573
6574         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
6575             grep grant_extent_tax | awk '{print $2}')
6576
6577         echo $(((max_brw_size + grant_extent_tax) * 2))
6578 }
6579
6580 test_64d() {
6581         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
6582                 skip "OST < 2.10.55 doesn't limit grants enough"
6583
6584         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
6585         local file=$DIR/$tfile
6586
6587         [[ $($LCTL get_param osc.${tgt}.import |
6588              grep "connect_flags:.*grant_param") ]] ||
6589                 skip "no grant_param connect flag"
6590
6591         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
6592
6593         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
6594
6595         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
6596         stack_trap "rm -f $file" EXIT
6597
6598         $LFS setstripe $file -i 0 -c 1
6599         dd if=/dev/zero of=$file bs=1M count=1000 &
6600         ddpid=$!
6601
6602         while true
6603         do
6604                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
6605                 if [[ $cur_grant -gt $max_cur_granted ]]
6606                 then
6607                         kill $ddpid
6608                         error "cur_grant $cur_grant > $max_cur_granted"
6609                 fi
6610                 kill -0 $ddpid
6611                 [[ $? -ne 0 ]] && break;
6612                 sleep 2
6613         done
6614
6615         rm -f $DIR/$tfile
6616         wait_delete_completed
6617         $LCTL set_param debug="$olddebug" 2> /dev/null || true
6618 }
6619 run_test 64d "check grant limit exceed"
6620
6621 # bug 1414 - set/get directories' stripe info
6622 test_65a() {
6623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6624
6625         test_mkdir $DIR/$tdir
6626         touch $DIR/$tdir/f1
6627         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
6628 }
6629 run_test 65a "directory with no stripe info"
6630
6631 test_65b() {
6632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6633
6634         test_mkdir $DIR/$tdir
6635         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6636
6637         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6638                                                 error "setstripe"
6639         touch $DIR/$tdir/f2
6640         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
6641 }
6642 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
6643
6644 test_65c() {
6645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6646         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
6647
6648         test_mkdir $DIR/$tdir
6649         local stripesize=$($LFS getstripe -S $DIR/$tdir)
6650
6651         $LFS setstripe -S $((stripesize * 4)) -i 1 \
6652                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
6653         touch $DIR/$tdir/f3
6654         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
6655 }
6656 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
6657
6658 test_65d() {
6659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6660
6661         test_mkdir $DIR/$tdir
6662         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
6663         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6664
6665         if [[ $STRIPECOUNT -le 0 ]]; then
6666                 sc=1
6667         elif [[ $STRIPECOUNT -gt 2000 ]]; then
6668 #LOV_MAX_STRIPE_COUNT is 2000
6669                 [[ $OSTCOUNT -gt 2000 ]] && sc=2000 || sc=$(($OSTCOUNT - 1))
6670         else
6671                 sc=$(($STRIPECOUNT - 1))
6672         fi
6673         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
6674         touch $DIR/$tdir/f4 $DIR/$tdir/f5
6675         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
6676                 error "lverify failed"
6677 }
6678 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
6679
6680 test_65e() {
6681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6682
6683         test_mkdir $DIR/$tdir
6684
6685         $LFS setstripe $DIR/$tdir || error "setstripe"
6686         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6687                                         error "no stripe info failed"
6688         touch $DIR/$tdir/f6
6689         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
6690 }
6691 run_test 65e "directory setstripe defaults"
6692
6693 test_65f() {
6694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6695
6696         test_mkdir $DIR/${tdir}f
6697         $RUNAS $LFS setstripe $DIR/${tdir}f &&
6698                 error "setstripe succeeded" || true
6699 }
6700 run_test 65f "dir setstripe permission (should return error) ==="
6701
6702 test_65g() {
6703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6704
6705         test_mkdir $DIR/$tdir
6706         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6707
6708         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6709                 error "setstripe -S failed"
6710         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
6711         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
6712                 error "delete default stripe failed"
6713 }
6714 run_test 65g "directory setstripe -d"
6715
6716 test_65h() {
6717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6718
6719         test_mkdir $DIR/$tdir
6720         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
6721
6722         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
6723                 error "setstripe -S failed"
6724         test_mkdir $DIR/$tdir/dd1
6725         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
6726                 error "stripe info inherit failed"
6727 }
6728 run_test 65h "directory stripe info inherit ===================="
6729
6730 test_65i() {
6731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6732
6733         save_layout_restore_at_exit $MOUNT
6734
6735         # bug6367: set non-default striping on root directory
6736         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
6737
6738         # bug12836: getstripe on -1 default directory striping
6739         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
6740
6741         # bug12836: getstripe -v on -1 default directory striping
6742         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
6743
6744         # bug12836: new find on -1 default directory striping
6745         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
6746 }
6747 run_test 65i "various tests to set root directory striping"
6748
6749 test_65j() { # bug6367
6750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6751
6752         sync; sleep 1
6753
6754         # if we aren't already remounting for each test, do so for this test
6755         if [ "$CLEANUP" = ":" -a "$I_MOUNTED" = "yes" ]; then
6756                 cleanup || error "failed to unmount"
6757                 setup
6758         fi
6759
6760         save_layout_restore_at_exit $MOUNT
6761
6762         $LFS setstripe -d $MOUNT || error "setstripe failed"
6763 }
6764 run_test 65j "set default striping on root directory (bug 6367)="
6765
6766 cleanup_65k() {
6767         rm -rf $DIR/$tdir
6768         wait_delete_completed
6769         do_facet $SINGLEMDS "lctl set_param -n \
6770                 osp.$ost*MDT0000.max_create_count=$max_count"
6771         do_facet $SINGLEMDS "lctl set_param -n \
6772                 osp.$ost*MDT0000.create_count=$count"
6773         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6774         echo $INACTIVE_OSC "is Activate"
6775
6776         wait_osc_import_state mds ost$ostnum FULL
6777 }
6778
6779 test_65k() { # bug11679
6780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6781         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6782         remote_mds_nodsh && skip "remote MDS with nodsh"
6783
6784         local disable_precreate=true
6785         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
6786                 disable_precreate=false
6787
6788         echo "Check OST status: "
6789         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
6790                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
6791
6792         for OSC in $MDS_OSCS; do
6793                 echo $OSC "is active"
6794                 do_facet $SINGLEMDS lctl --device %$OSC activate
6795         done
6796
6797         for INACTIVE_OSC in $MDS_OSCS; do
6798                 local ost=$(osc_to_ost $INACTIVE_OSC)
6799                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
6800                                lov.*md*.target_obd |
6801                                awk -F: /$ost/'{ print $1 }' | head -n 1)
6802
6803                 mkdir -p $DIR/$tdir
6804                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
6805                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
6806
6807                 echo "Deactivate: " $INACTIVE_OSC
6808                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
6809
6810                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
6811                               osp.$ost*MDT0000.create_count")
6812                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
6813                                   osp.$ost*MDT0000.max_create_count")
6814                 $disable_precreate &&
6815                         do_facet $SINGLEMDS "lctl set_param -n \
6816                                 osp.$ost*MDT0000.max_create_count=0"
6817
6818                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
6819                         [ -f $DIR/$tdir/$idx ] && continue
6820                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
6821                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
6822                                 { cleanup_65k;
6823                                   error "setstripe $idx should succeed"; }
6824                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
6825                 done
6826                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
6827                 rmdir $DIR/$tdir
6828
6829                 do_facet $SINGLEMDS "lctl set_param -n \
6830                         osp.$ost*MDT0000.max_create_count=$max_count"
6831                 do_facet $SINGLEMDS "lctl set_param -n \
6832                         osp.$ost*MDT0000.create_count=$count"
6833                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
6834                 echo $INACTIVE_OSC "is Activate"
6835
6836                 wait_osc_import_state mds ost$ostnum FULL
6837         done
6838 }
6839 run_test 65k "validate manual striping works properly with deactivated OSCs"
6840
6841 test_65l() { # bug 12836
6842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6843
6844         test_mkdir -p $DIR/$tdir/test_dir
6845         $LFS setstripe -c -1 $DIR/$tdir/test_dir
6846         $LFS find -mtime -1 $DIR/$tdir >/dev/null
6847 }
6848 run_test 65l "lfs find on -1 stripe dir ========================"
6849
6850 test_65m() {
6851         local layout=$(save_layout $MOUNT)
6852         $RUNAS $LFS setstripe -c 2 $MOUNT && {
6853                 restore_layout $MOUNT $layout
6854                 error "setstripe should fail by non-root users"
6855         }
6856         true
6857 }
6858 run_test 65m "normal user can't set filesystem default stripe"
6859
6860 test_65n() {
6861         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
6862         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
6863                 skip "Need MDS version at least 2.12.50"
6864         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
6865
6866         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
6867         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
6868         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
6869
6870         local root_layout=$(save_layout $MOUNT)
6871         stack_trap "restore_layout $MOUNT $root_layout" EXIT
6872
6873         # new subdirectory under root directory should not inherit
6874         # the default layout from root
6875         local dir1=$MOUNT/$tdir-1
6876         mkdir $dir1 || error "mkdir $dir1 failed"
6877         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
6878                 error "$dir1 shouldn't have LOV EA"
6879
6880         # delete the default layout on root directory
6881         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
6882
6883         local dir2=$MOUNT/$tdir-2
6884         mkdir $dir2 || error "mkdir $dir2 failed"
6885         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
6886                 error "$dir2 shouldn't have LOV EA"
6887
6888         # set a new striping pattern on root directory
6889         local def_stripe_size=$($LFS getstripe -S $MOUNT)
6890         local new_def_stripe_size=$((def_stripe_size * 2))
6891         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
6892                 error "set stripe size on $MOUNT failed"
6893
6894         # new file created in $dir2 should inherit the new stripe size from
6895         # the filesystem default
6896         local file2=$dir2/$tfile-2
6897         touch $file2 || error "touch $file2 failed"
6898
6899         local file2_stripe_size=$($LFS getstripe -S $file2)
6900         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
6901                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
6902
6903         local dir3=$MOUNT/$tdir-3
6904         mkdir $dir3 || error "mkdir $dir3 failed"
6905         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
6906                 error "$dir3 shouldn't have LOV EA"
6907
6908         # set OST pool on root directory
6909         local pool=$TESTNAME
6910         pool_add $pool || error "add $pool failed"
6911         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
6912                 error "add targets to $pool failed"
6913
6914         $LFS setstripe -p $pool $MOUNT ||
6915                 error "set OST pool on $MOUNT failed"
6916
6917         # new file created in $dir3 should inherit the pool from
6918         # the filesystem default
6919         local file3=$dir3/$tfile-3
6920         touch $file3 || error "touch $file3 failed"
6921
6922         local file3_pool=$($LFS getstripe -p $file3)
6923         [[ "$file3_pool" = "$pool" ]] ||
6924                 error "$file3 didn't inherit OST pool $pool"
6925
6926         local dir4=$MOUNT/$tdir-4
6927         mkdir $dir4 || error "mkdir $dir4 failed"
6928         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
6929                 error "$dir4 shouldn't have LOV EA"
6930
6931         # new file created in $dir4 should inherit the pool from
6932         # the filesystem default
6933         local file4=$dir4/$tfile-4
6934         touch $file4 || error "touch $file4 failed"
6935
6936         local file4_pool=$($LFS getstripe -p $file4)
6937         [[ "$file4_pool" = "$pool" ]] ||
6938                 error "$file4 didn't inherit OST pool $pool"
6939
6940         # new subdirectory under non-root directory should inherit
6941         # the default layout from its parent directory
6942         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
6943                 error "set directory layout on $dir4 failed"
6944
6945         local dir5=$dir4/$tdir-5
6946         mkdir $dir5 || error "mkdir $dir5 failed"
6947
6948         local dir4_layout=$(get_layout_param $dir4)
6949         local dir5_layout=$(get_layout_param $dir5)
6950         [[ "$dir4_layout" = "$dir5_layout" ]] ||
6951                 error "$dir5 should inherit the default layout from $dir4"
6952 }
6953 run_test 65n "don't inherit default layout from root for new subdirectories"
6954
6955 # bug 2543 - update blocks count on client
6956 test_66() {
6957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6958
6959         COUNT=${COUNT:-8}
6960         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
6961         sync; sync_all_data; sync; sync_all_data
6962         cancel_lru_locks osc
6963         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
6964         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
6965 }
6966 run_test 66 "update inode blocks count on client ==============="
6967
6968 meminfo() {
6969         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
6970 }
6971
6972 swap_used() {
6973         swapon -s | awk '($1 == "'$1'") { print $4 }'
6974 }
6975
6976 # bug5265, obdfilter oa2dentry return -ENOENT
6977 # #define OBD_FAIL_SRV_ENOENT 0x217
6978 test_69() {
6979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6980         remote_ost_nodsh && skip "remote OST with nodsh"
6981
6982         f="$DIR/$tfile"
6983         $LFS setstripe -c 1 -i 0 $f
6984
6985         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
6986
6987         do_facet ost1 lctl set_param fail_loc=0x217
6988         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
6989         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
6990
6991         do_facet ost1 lctl set_param fail_loc=0
6992         $DIRECTIO write $f 0 2 || error "write error"
6993
6994         cancel_lru_locks osc
6995         $DIRECTIO read $f 0 1 || error "read error"
6996
6997         do_facet ost1 lctl set_param fail_loc=0x217
6998         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
6999
7000         do_facet ost1 lctl set_param fail_loc=0
7001         rm -f $f
7002 }
7003 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7004
7005 test_71() {
7006         test_mkdir $DIR/$tdir
7007         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7008         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7009 }
7010 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7011
7012 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7014         [ "$RUNAS_ID" = "$UID" ] &&
7015                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7016         # Check that testing environment is properly set up. Skip if not
7017         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7018                 skip_env "User $RUNAS_ID does not exist - skipping"
7019
7020         touch $DIR/$tfile
7021         chmod 777 $DIR/$tfile
7022         chmod ug+s $DIR/$tfile
7023         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7024                 error "$RUNAS dd $DIR/$tfile failed"
7025         # See if we are still setuid/sgid
7026         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7027                 error "S/gid is not dropped on write"
7028         # Now test that MDS is updated too
7029         cancel_lru_locks mdc
7030         test -u $DIR/$tfile -o -g $DIR/$tfile &&
7031                 error "S/gid is not dropped on MDS"
7032         rm -f $DIR/$tfile
7033 }
7034 run_test 72a "Test that remove suid works properly (bug5695) ===="
7035
7036 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7037         local perm
7038
7039         [ "$RUNAS_ID" = "$UID" ] &&
7040                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7041         [ "$RUNAS_ID" -eq 0 ] &&
7042                 skip_env "RUNAS_ID = 0 -- skipping"
7043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7044         # Check that testing environment is properly set up. Skip if not
7045         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7046                 skip_env "User $RUNAS_ID does not exist - skipping"
7047
7048         touch $DIR/${tfile}-f{g,u}
7049         test_mkdir $DIR/${tfile}-dg
7050         test_mkdir $DIR/${tfile}-du
7051         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7052         chmod g+s $DIR/${tfile}-{f,d}g
7053         chmod u+s $DIR/${tfile}-{f,d}u
7054         for perm in 777 2777 4777; do
7055                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7056                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7057                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7058                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7059         done
7060         true
7061 }
7062 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7063
7064 # bug 3462 - multiple simultaneous MDC requests
7065 test_73() {
7066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7067
7068         test_mkdir $DIR/d73-1
7069         test_mkdir $DIR/d73-2
7070         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7071         pid1=$!
7072
7073         lctl set_param fail_loc=0x80000129
7074         $MULTIOP $DIR/d73-1/f73-2 Oc &
7075         sleep 1
7076         lctl set_param fail_loc=0
7077
7078         $MULTIOP $DIR/d73-2/f73-3 Oc &
7079         pid3=$!
7080
7081         kill -USR1 $pid1
7082         wait $pid1 || return 1
7083
7084         sleep 25
7085
7086         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7087         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7088         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7089
7090         rm -rf $DIR/d73-*
7091 }
7092 run_test 73 "multiple MDC requests (should not deadlock)"
7093
7094 test_74a() { # bug 6149, 6184
7095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7096
7097         touch $DIR/f74a
7098         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7099         #
7100         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7101         # will spin in a tight reconnection loop
7102         $LCTL set_param fail_loc=0x8000030e
7103         # get any lock that won't be difficult - lookup works.
7104         ls $DIR/f74a
7105         $LCTL set_param fail_loc=0
7106         rm -f $DIR/f74a
7107         true
7108 }
7109 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7110
7111 test_74b() { # bug 13310
7112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7113
7114         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7115         #
7116         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7117         # will spin in a tight reconnection loop
7118         $LCTL set_param fail_loc=0x8000030e
7119         # get a "difficult" lock
7120         touch $DIR/f74b
7121         $LCTL set_param fail_loc=0
7122         rm -f $DIR/f74b
7123         true
7124 }
7125 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7126
7127 test_74c() {
7128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7129
7130         #define OBD_FAIL_LDLM_NEW_LOCK
7131         $LCTL set_param fail_loc=0x319
7132         touch $DIR/$tfile && error "touch successful"
7133         $LCTL set_param fail_loc=0
7134         true
7135 }
7136 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7137
7138 num_inodes() {
7139         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7140 }
7141
7142 test_76() { # Now for bug 20433, added originally in bug 1443
7143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7144
7145         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7146
7147         cancel_lru_locks osc
7148         BEFORE_INODES=$(num_inodes)
7149         echo "before inodes: $BEFORE_INODES"
7150         local COUNT=1000
7151         [ "$SLOW" = "no" ] && COUNT=100
7152         for i in $(seq $COUNT); do
7153                 touch $DIR/$tfile
7154                 rm -f $DIR/$tfile
7155         done
7156         cancel_lru_locks osc
7157         AFTER_INODES=$(num_inodes)
7158         echo "after inodes: $AFTER_INODES"
7159         local wait=0
7160         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7161                 sleep 2
7162                 AFTER_INODES=$(num_inodes)
7163                 wait=$((wait+2))
7164                 echo "wait $wait seconds inodes: $AFTER_INODES"
7165                 if [ $wait -gt 30 ]; then
7166                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7167                 fi
7168         done
7169 }
7170 run_test 76 "confirm clients recycle inodes properly ===="
7171
7172
7173 export ORIG_CSUM=""
7174 set_checksums()
7175 {
7176         # Note: in sptlrpc modes which enable its own bulk checksum, the
7177         # original crc32_le bulk checksum will be automatically disabled,
7178         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7179         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7180         # In this case set_checksums() will not be no-op, because sptlrpc
7181         # bulk checksum will be enabled all through the test.
7182
7183         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7184         lctl set_param -n osc.*.checksums $1
7185         return 0
7186 }
7187
7188 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7189                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7190 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7191                              tr -d [] | head -n1)}
7192 set_checksum_type()
7193 {
7194         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7195         log "set checksum type to $1"
7196         return 0
7197 }
7198 F77_TMP=$TMP/f77-temp
7199 F77SZ=8
7200 setup_f77() {
7201         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7202                 error "error writing to $F77_TMP"
7203 }
7204
7205 test_77a() { # bug 10889
7206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7207         $GSS && skip_env "could not run with gss"
7208
7209         [ ! -f $F77_TMP ] && setup_f77
7210         set_checksums 1
7211         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7212         set_checksums 0
7213         rm -f $DIR/$tfile
7214 }
7215 run_test 77a "normal checksum read/write operation"
7216
7217 test_77b() { # bug 10889
7218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7219         $GSS && skip_env "could not run with gss"
7220
7221         [ ! -f $F77_TMP ] && setup_f77
7222         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7223         $LCTL set_param fail_loc=0x80000409
7224         set_checksums 1
7225
7226         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7227                 error "dd error: $?"
7228         $LCTL set_param fail_loc=0
7229
7230         for algo in $CKSUM_TYPES; do
7231                 cancel_lru_locks osc
7232                 set_checksum_type $algo
7233                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7234                 $LCTL set_param fail_loc=0x80000408
7235                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7236                 $LCTL set_param fail_loc=0
7237         done
7238         set_checksums 0
7239         set_checksum_type $ORIG_CSUM_TYPE
7240         rm -f $DIR/$tfile
7241 }
7242 run_test 77b "checksum error on client write, read"
7243
7244 cleanup_77c() {
7245         trap 0
7246         set_checksums 0
7247         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7248         $check_ost &&
7249                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7250         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7251         $check_ost && [ -n "$ost_file_prefix" ] &&
7252                 do_facet ost1 rm -f ${ost_file_prefix}\*
7253 }
7254
7255 test_77c() {
7256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7257         $GSS && skip_env "could not run with gss"
7258         remote_ost_nodsh && skip "remote OST with nodsh"
7259
7260         local bad1
7261         local osc_file_prefix
7262         local osc_file
7263         local check_ost=false
7264         local ost_file_prefix
7265         local ost_file
7266         local orig_cksum
7267         local dump_cksum
7268         local fid
7269
7270         # ensure corruption will occur on first OSS/OST
7271         $LFS setstripe -i 0 $DIR/$tfile
7272
7273         [ ! -f $F77_TMP ] && setup_f77
7274         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7275                 error "dd write error: $?"
7276         fid=$($LFS path2fid $DIR/$tfile)
7277
7278         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7279         then
7280                 check_ost=true
7281                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7282                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7283         else
7284                 echo "OSS do not support bulk pages dump upon error"
7285         fi
7286
7287         osc_file_prefix=$($LCTL get_param -n debug_path)
7288         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7289
7290         trap cleanup_77c EXIT
7291
7292         set_checksums 1
7293         # enable bulk pages dump upon error on Client
7294         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7295         # enable bulk pages dump upon error on OSS
7296         $check_ost &&
7297                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7298
7299         # flush Client cache to allow next read to reach OSS
7300         cancel_lru_locks osc
7301
7302         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7303         $LCTL set_param fail_loc=0x80000408
7304         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7305         $LCTL set_param fail_loc=0
7306
7307         rm -f $DIR/$tfile
7308
7309         # check cksum dump on Client
7310         osc_file=$(ls ${osc_file_prefix}*)
7311         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7312         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7313         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7314         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7315         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7316                      cksum)
7317         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7318         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7319                 error "dump content does not match on Client"
7320
7321         $check_ost || skip "No need to check cksum dump on OSS"
7322
7323         # check cksum dump on OSS
7324         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7325         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7326         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7327         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7328         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7329                 error "dump content does not match on OSS"
7330
7331         cleanup_77c
7332 }
7333 run_test 77c "checksum error on client read with debug"
7334
7335 test_77d() { # bug 10889
7336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7337         $GSS && skip_env "could not run with gss"
7338
7339         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7340         $LCTL set_param fail_loc=0x80000409
7341         set_checksums 1
7342         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7343                 error "direct write: rc=$?"
7344         $LCTL set_param fail_loc=0
7345         set_checksums 0
7346
7347         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7348         $LCTL set_param fail_loc=0x80000408
7349         set_checksums 1
7350         cancel_lru_locks osc
7351         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7352                 error "direct read: rc=$?"
7353         $LCTL set_param fail_loc=0
7354         set_checksums 0
7355 }
7356 run_test 77d "checksum error on OST direct write, read"
7357
7358 test_77f() { # bug 10889
7359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7360         $GSS && skip_env "could not run with gss"
7361
7362         set_checksums 1
7363         for algo in $CKSUM_TYPES; do
7364                 cancel_lru_locks osc
7365                 set_checksum_type $algo
7366                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7367                 $LCTL set_param fail_loc=0x409
7368                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7369                         error "direct write succeeded"
7370                 $LCTL set_param fail_loc=0
7371         done
7372         set_checksum_type $ORIG_CSUM_TYPE
7373         set_checksums 0
7374 }
7375 run_test 77f "repeat checksum error on write (expect error)"
7376
7377 test_77g() { # bug 10889
7378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7379         $GSS && skip_env "could not run with gss"
7380         remote_ost_nodsh && skip "remote OST with nodsh"
7381
7382         [ ! -f $F77_TMP ] && setup_f77
7383
7384         local file=$DIR/$tfile
7385         stack_trap "rm -f $file" EXIT
7386
7387         $LFS setstripe -c 1 -i 0 $file
7388         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7389         do_facet ost1 lctl set_param fail_loc=0x8000021a
7390         set_checksums 1
7391         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7392                 error "write error: rc=$?"
7393         do_facet ost1 lctl set_param fail_loc=0
7394         set_checksums 0
7395
7396         cancel_lru_locks osc
7397         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7398         do_facet ost1 lctl set_param fail_loc=0x8000021b
7399         set_checksums 1
7400         cmp $F77_TMP $file || error "file compare failed"
7401         do_facet ost1 lctl set_param fail_loc=0
7402         set_checksums 0
7403 }
7404 run_test 77g "checksum error on OST write, read"
7405
7406 test_77k() { # LU-10906
7407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7408         $GSS && skip_env "could not run with gss"
7409
7410         local cksum_param="osc.$FSNAME*.checksums"
7411         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7412         local checksum
7413         local i
7414
7415         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7416         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7417         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7418                 EXIT
7419
7420         for i in 0 1; do
7421                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7422                         error "failed to set checksum=$i on MGS"
7423                 wait_update $HOSTNAME "$get_checksum" $i
7424                 #remount
7425                 echo "remount client, checksum should be $i"
7426                 remount_client $MOUNT || "failed to remount client"
7427                 checksum=$(eval $get_checksum)
7428                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7429         done
7430         # remove persistent param to avoid races with checksum mountopt below
7431         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7432                 error "failed to delete checksum on MGS"
7433
7434         for opt in "checksum" "nochecksum"; do
7435                 #remount with mount option
7436                 echo "remount client with option $opt, checksum should be $i"
7437                 umount_client $MOUNT || "failed to umount client"
7438                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7439                         "failed to mount client with option '$opt'"
7440                 checksum=$(eval $get_checksum)
7441                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7442                 i=$((i - 1))
7443         done
7444
7445         remount_client $MOUNT || "failed to remount client"
7446 }
7447 run_test 77k "enable/disable checksum correctly"
7448
7449 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7450 rm -f $F77_TMP
7451 unset F77_TMP
7452
7453 cleanup_test_78() {
7454         trap 0
7455         rm -f $DIR/$tfile
7456 }
7457
7458 test_78() { # bug 10901
7459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7460         remote_ost || skip_env "local OST"
7461
7462         NSEQ=5
7463         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7464         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7465         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7466         echo "MemTotal: $MEMTOTAL"
7467
7468         # reserve 256MB of memory for the kernel and other running processes,
7469         # and then take 1/2 of the remaining memory for the read/write buffers.
7470         if [ $MEMTOTAL -gt 512 ] ;then
7471                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
7472         else
7473                 # for those poor memory-starved high-end clusters...
7474                 MEMTOTAL=$((MEMTOTAL / 2))
7475         fi
7476         echo "Mem to use for directio: $MEMTOTAL"
7477
7478         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
7479         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
7480         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
7481         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
7482                 head -n1)
7483         echo "Smallest OST: $SMALLESTOST"
7484         [[ $SMALLESTOST -lt 10240 ]] &&
7485                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
7486
7487         trap cleanup_test_78 EXIT
7488
7489         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
7490                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
7491
7492         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
7493         echo "File size: $F78SIZE"
7494         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
7495         for i in $(seq 1 $NSEQ); do
7496                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
7497                 echo directIO rdwr round $i of $NSEQ
7498                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
7499         done
7500
7501         cleanup_test_78
7502 }
7503 run_test 78 "handle large O_DIRECT writes correctly ============"
7504
7505 test_79() { # bug 12743
7506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7507
7508         wait_delete_completed
7509
7510         BKTOTAL=$(calc_osc_kbytes kbytestotal)
7511         BKFREE=$(calc_osc_kbytes kbytesfree)
7512         BKAVAIL=$(calc_osc_kbytes kbytesavail)
7513
7514         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
7515         DFTOTAL=`echo $STRING | cut -d, -f1`
7516         DFUSED=`echo $STRING  | cut -d, -f2`
7517         DFAVAIL=`echo $STRING | cut -d, -f3`
7518         DFFREE=$(($DFTOTAL - $DFUSED))
7519
7520         ALLOWANCE=$((64 * $OSTCOUNT))
7521
7522         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
7523            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
7524                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
7525         fi
7526         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
7527            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
7528                 error "df free($DFFREE) mismatch OST free($BKFREE)"
7529         fi
7530         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
7531            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
7532                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
7533         fi
7534 }
7535 run_test 79 "df report consistency check ======================="
7536
7537 test_80() { # bug 10718
7538         remote_ost_nodsh && skip "remote OST with nodsh"
7539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7540
7541         # relax strong synchronous semantics for slow backends like ZFS
7542         local soc="obdfilter.*.sync_on_lock_cancel"
7543         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
7544         local hosts=
7545         if [ "$soc_old" != "never" ] &&
7546                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
7547                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
7548                                 facet_active_host $host; done | sort -u)
7549                         do_nodes $hosts lctl set_param $soc=never
7550         fi
7551
7552         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
7553         sync; sleep 1; sync
7554         local BEFORE=`date +%s`
7555         cancel_lru_locks osc
7556         local AFTER=`date +%s`
7557         local DIFF=$((AFTER-BEFORE))
7558         if [ $DIFF -gt 1 ] ; then
7559                 error "elapsed for 1M@1T = $DIFF"
7560         fi
7561
7562         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
7563
7564         rm -f $DIR/$tfile
7565 }
7566 run_test 80 "Page eviction is equally fast at high offsets too  ===="
7567
7568 test_81a() { # LU-456
7569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7570         remote_ost_nodsh && skip "remote OST with nodsh"
7571
7572         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7573         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
7574         do_facet ost1 lctl set_param fail_loc=0x80000228
7575
7576         # write should trigger a retry and success
7577         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7578         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7579         RC=$?
7580         if [ $RC -ne 0 ] ; then
7581                 error "write should success, but failed for $RC"
7582         fi
7583 }
7584 run_test 81a "OST should retry write when get -ENOSPC ==============="
7585
7586 test_81b() { # LU-456
7587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7588         remote_ost_nodsh && skip "remote OST with nodsh"
7589
7590         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
7591         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
7592         do_facet ost1 lctl set_param fail_loc=0x228
7593
7594         # write should retry several times and return -ENOSPC finally
7595         $LFS setstripe -i 0 -c 1 $DIR/$tfile
7596         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
7597         RC=$?
7598         ENOSPC=28
7599         if [ $RC -ne $ENOSPC ] ; then
7600                 error "dd should fail for -ENOSPC, but succeed."
7601         fi
7602 }
7603 run_test 81b "OST should return -ENOSPC when retry still fails ======="
7604
7605 test_82() { # LU-1031
7606         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
7607         local gid1=14091995
7608         local gid2=16022000
7609
7610         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
7611         local MULTIPID1=$!
7612         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
7613         local MULTIPID2=$!
7614         kill -USR1 $MULTIPID2
7615         sleep 2
7616         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
7617                 error "First grouplock does not block second one"
7618         else
7619                 echo "Second grouplock blocks first one"
7620         fi
7621         kill -USR1 $MULTIPID1
7622         wait $MULTIPID1
7623         wait $MULTIPID2
7624 }
7625 run_test 82 "Basic grouplock test"
7626
7627 test_99() {
7628         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
7629
7630         test_mkdir $DIR/$tdir.cvsroot
7631         chown $RUNAS_ID $DIR/$tdir.cvsroot
7632
7633         cd $TMP
7634         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
7635
7636         cd /etc/init.d
7637         # some versions of cvs import exit(1) when asked to import links or
7638         # files they can't read.  ignore those files.
7639         local toignore=$(find . -type l -printf '-I %f\n' -o \
7640                          ! -perm /4 -printf '-I %f\n')
7641         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
7642                 $tdir.reposname vtag rtag
7643
7644         cd $DIR
7645         test_mkdir $DIR/$tdir.reposname
7646         chown $RUNAS_ID $DIR/$tdir.reposname
7647         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
7648
7649         cd $DIR/$tdir.reposname
7650         $RUNAS touch foo99
7651         $RUNAS cvs add -m 'addmsg' foo99
7652         $RUNAS cvs update
7653         $RUNAS cvs commit -m 'nomsg' foo99
7654         rm -fr $DIR/$tdir.cvsroot
7655 }
7656 run_test 99 "cvs strange file/directory operations"
7657
7658 test_100() {
7659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7660         [[ "$NETTYPE" =~ tcp ]] ||
7661                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
7662         remote_ost_nodsh && skip "remote OST with nodsh"
7663         remote_mds_nodsh && skip "remote MDS with nodsh"
7664         remote_servers ||
7665                 skip "useless for local single node setup"
7666
7667         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
7668                 [ "$PROT" != "tcp" ] && continue
7669                 RPORT=$(echo $REMOTE | cut -d: -f2)
7670                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
7671
7672                 rc=0
7673                 LPORT=`echo $LOCAL | cut -d: -f2`
7674                 if [ $LPORT -ge 1024 ]; then
7675                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
7676                         netstat -tna
7677                         error_exit "local: $LPORT > 1024, remote: $RPORT"
7678                 fi
7679         done
7680         [ "$rc" = 0 ] || error_exit "privileged port not found" )
7681 }
7682 run_test 100 "check local port using privileged port ==========="
7683
7684 function get_named_value()
7685 {
7686     local tag
7687
7688     tag=$1
7689     while read ;do
7690         line=$REPLY
7691         case $line in
7692         $tag*)
7693             echo $line | sed "s/^$tag[ ]*//"
7694             break
7695             ;;
7696         esac
7697     done
7698 }
7699
7700 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
7701                    awk '/^max_cached_mb/ { print $2 }')
7702
7703 cleanup_101a() {
7704         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
7705         trap 0
7706 }
7707
7708 test_101a() {
7709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7710         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
7711
7712         local s
7713         local discard
7714         local nreads=10000
7715         local cache_limit=32
7716
7717         $LCTL set_param -n osc.*-osc*.rpc_stats 0
7718         trap cleanup_101a EXIT
7719         $LCTL set_param -n llite.*.read_ahead_stats 0
7720         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
7721
7722         #
7723         # randomly read 10000 of 64K chunks from file 3x 32MB in size
7724         #
7725         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
7726         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
7727
7728         discard=0
7729         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
7730                 get_named_value 'read but discarded' | cut -d" " -f1); do
7731                         discard=$(($discard + $s))
7732         done
7733         cleanup_101a
7734
7735         if [[ $(($discard * 10)) -gt $nreads ]]; then
7736                 $LCTL get_param osc.*-osc*.rpc_stats
7737                 $LCTL get_param llite.*.read_ahead_stats
7738                 error "too many ($discard) discarded pages"
7739         fi
7740         rm -f $DIR/$tfile || true
7741 }
7742 run_test 101a "check read-ahead for random reads"
7743
7744 setup_test101bc() {
7745         test_mkdir $DIR/$tdir
7746         local ssize=$1
7747         local FILE_LENGTH=$2
7748         STRIPE_OFFSET=0
7749
7750         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
7751
7752         local list=$(comma_list $(osts_nodes))
7753         set_osd_param $list '' read_cache_enable 0
7754         set_osd_param $list '' writethrough_cache_enable 0
7755
7756         trap cleanup_test101bc EXIT
7757         # prepare the read-ahead file
7758         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
7759
7760         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
7761                                 count=$FILE_SIZE_MB 2> /dev/null
7762
7763 }
7764
7765 cleanup_test101bc() {
7766         trap 0
7767         rm -rf $DIR/$tdir
7768         rm -f $DIR/$tfile
7769
7770         local list=$(comma_list $(osts_nodes))
7771         set_osd_param $list '' read_cache_enable 1
7772         set_osd_param $list '' writethrough_cache_enable 1
7773 }
7774
7775 calc_total() {
7776         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
7777 }
7778
7779 ra_check_101() {
7780         local READ_SIZE=$1
7781         local STRIPE_SIZE=$2
7782         local FILE_LENGTH=$3
7783         local RA_INC=1048576
7784         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
7785         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
7786                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
7787         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
7788                         get_named_value 'read but discarded' |
7789                         cut -d" " -f1 | calc_total)
7790         if [[ $DISCARD -gt $discard_limit ]]; then
7791                 $LCTL get_param llite.*.read_ahead_stats
7792                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
7793         else
7794                 echo "Read-ahead success for size ${READ_SIZE}"
7795         fi
7796 }
7797
7798 test_101b() {
7799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7801
7802         local STRIPE_SIZE=1048576
7803         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
7804
7805         if [ $SLOW == "yes" ]; then
7806                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
7807         else
7808                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
7809         fi
7810
7811         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
7812
7813         # prepare the read-ahead file
7814         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7815         cancel_lru_locks osc
7816         for BIDX in 2 4 8 16 32 64 128 256
7817         do
7818                 local BSIZE=$((BIDX*4096))
7819                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
7820                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
7821                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
7822                 $LCTL set_param -n llite.*.read_ahead_stats 0
7823                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
7824                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
7825                 cancel_lru_locks osc
7826                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
7827         done
7828         cleanup_test101bc
7829         true
7830 }
7831 run_test 101b "check stride-io mode read-ahead ================="
7832
7833 test_101c() {
7834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7835
7836         local STRIPE_SIZE=1048576
7837         local FILE_LENGTH=$((STRIPE_SIZE*100))
7838         local nreads=10000
7839         local rsize=65536
7840         local osc_rpc_stats
7841
7842         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
7843
7844         cancel_lru_locks osc
7845         $LCTL set_param osc.*.rpc_stats 0
7846         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
7847         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
7848                 local stats=$($LCTL get_param -n $osc_rpc_stats)
7849                 local lines=$(echo "$stats" | awk 'END {print NR;}')
7850                 local size
7851
7852                 if [ $lines -le 20 ]; then
7853                         continue
7854                 fi
7855                 for size in 1 2 4 8; do
7856                         local rpc=$(echo "$stats" |
7857                                     awk '($1 == "'$size':") {print $2; exit; }')
7858                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
7859                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
7860                 done
7861                 echo "$osc_rpc_stats check passed!"
7862         done
7863         cleanup_test101bc
7864         true
7865 }
7866 run_test 101c "check stripe_size aligned read-ahead ================="
7867
7868 set_read_ahead() {
7869         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
7870         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
7871 }
7872
7873 test_101d() {
7874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7875
7876         local file=$DIR/$tfile
7877         local sz_MB=${FILESIZE_101d:-500}
7878         local ra_MB=${READAHEAD_MB:-40}
7879
7880         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
7881         [ $free_MB -lt $sz_MB ] &&
7882                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
7883
7884         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
7885         $LFS setstripe -c -1 $file || error "setstripe failed"
7886
7887         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
7888         echo Cancel LRU locks on lustre client to flush the client cache
7889         cancel_lru_locks osc
7890
7891         echo Disable read-ahead
7892         local old_READAHEAD=$(set_read_ahead 0)
7893
7894         echo Reading the test file $file with read-ahead disabled
7895         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7896
7897         echo Cancel LRU locks on lustre client to flush the client cache
7898         cancel_lru_locks osc
7899         echo Enable read-ahead with ${ra_MB}MB
7900         set_read_ahead $ra_MB
7901
7902         echo Reading the test file $file with read-ahead enabled
7903         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
7904
7905         echo "read-ahead disabled time read $raOFF"
7906         echo "read-ahead enabled  time read $raON"
7907
7908         set_read_ahead $old_READAHEAD
7909         rm -f $file
7910         wait_delete_completed
7911
7912         [ $raOFF -le 1 -o $raON -lt $raOFF ] ||
7913                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
7914 }
7915 run_test 101d "file read with and without read-ahead enabled"
7916
7917 test_101e() {
7918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7919
7920         local file=$DIR/$tfile
7921         local size_KB=500  #KB
7922         local count=100
7923         local bsize=1024
7924
7925         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
7926         local need_KB=$((count * size_KB))
7927         [[ $free_KB -le $need_KB ]] &&
7928                 skip_env "Need free space $need_KB, have $free_KB"
7929
7930         echo "Creating $count ${size_KB}K test files"
7931         for ((i = 0; i < $count; i++)); do
7932                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
7933         done
7934
7935         echo "Cancel LRU locks on lustre client to flush the client cache"
7936         cancel_lru_locks $OSC
7937
7938         echo "Reset readahead stats"
7939         $LCTL set_param -n llite.*.read_ahead_stats 0
7940
7941         for ((i = 0; i < $count; i++)); do
7942                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
7943         done
7944
7945         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7946                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
7947
7948         for ((i = 0; i < $count; i++)); do
7949                 rm -rf $file.$i 2>/dev/null
7950         done
7951
7952         #10000 means 20% reads are missing in readahead
7953         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
7954 }
7955 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
7956
7957 test_101f() {
7958         which iozone || skip_env "no iozone installed"
7959
7960         local old_debug=$($LCTL get_param debug)
7961         old_debug=${old_debug#*=}
7962         $LCTL set_param debug="reada mmap"
7963
7964         # create a test file
7965         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
7966
7967         echo Cancel LRU locks on lustre client to flush the client cache
7968         cancel_lru_locks osc
7969
7970         echo Reset readahead stats
7971         $LCTL set_param -n llite.*.read_ahead_stats 0
7972
7973         echo mmap read the file with small block size
7974         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
7975                 > /dev/null 2>&1
7976
7977         echo checking missing pages
7978         $LCTL get_param llite.*.read_ahead_stats
7979         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
7980                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
7981
7982         $LCTL set_param debug="$old_debug"
7983         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
7984         rm -f $DIR/$tfile
7985 }
7986 run_test 101f "check mmap read performance"
7987
7988 test_101g_brw_size_test() {
7989         local mb=$1
7990         local pages=$((mb * 1048576 / PAGE_SIZE))
7991         local file=$DIR/$tfile
7992
7993         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
7994                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
7995         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
7996                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
7997                         return 2
7998         done
7999
8000         stack_trap "rm -f $file" EXIT
8001         $LCTL set_param -n osc.*.rpc_stats=0
8002
8003         # 10 RPCs should be enough for the test
8004         local count=10
8005         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8006                 { error "dd write ${mb} MB blocks failed"; return 3; }
8007         cancel_lru_locks osc
8008         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8009                 { error "dd write ${mb} MB blocks failed"; return 4; }
8010
8011         # calculate number of full-sized read and write RPCs
8012         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8013                 sed -n '/pages per rpc/,/^$/p' |
8014                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8015                 END { print reads,writes }'))
8016         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8017                 return 5
8018         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8019                 return 6
8020
8021         return 0
8022 }
8023
8024 test_101g() {
8025         remote_ost_nodsh && skip "remote OST with nodsh"
8026
8027         local rpcs
8028         local osts=$(get_facets OST)
8029         local list=$(comma_list $(osts_nodes))
8030         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8031         local brw_size="obdfilter.*.brw_size"
8032
8033         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8034
8035         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8036         if [ $OST1_VERSION -ge $(version_code 2.8.52) -o \
8037              \( $OST1_VERSION -ge $(version_code 2.7.17) -a \
8038                 $OST1_VERSION -lt $(version_code 2.7.50) \) ] &&
8039            [ $CLIENT_VERSION -ge $(version_code 2.8.52) -o \
8040              \( $CLIENT_VERSION -ge $(version_code 2.7.17) -a \
8041                 $CLIENT_VERSION -lt $(version_code 2.7.50) \) ]; then
8042                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] && suffix="M"
8043                 if [[ $orig_mb -lt 16 ]]; then
8044                         save_lustre_params $osts "$brw_size" > $p
8045                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8046                                 error "set 16MB RPC size failed"
8047
8048                         echo "remount client to enable new RPC size"
8049                         remount_client $MOUNT || error "remount_client failed"
8050                 fi
8051
8052                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8053                 # should be able to set brw_size=12, but no rpc_stats for that
8054                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8055         fi
8056
8057         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8058
8059         if [[ $orig_mb -lt 16 ]]; then
8060                 restore_lustre_params < $p
8061                 remount_client $MOUNT || error "remount_client restore failed"
8062         fi
8063
8064         rm -f $p $DIR/$tfile
8065 }
8066 run_test 101g "Big bulk(4/16 MiB) readahead"
8067
8068 setup_test102() {
8069         test_mkdir $DIR/$tdir
8070         chown $RUNAS_ID $DIR/$tdir
8071         STRIPE_SIZE=65536
8072         STRIPE_OFFSET=1
8073         STRIPE_COUNT=$OSTCOUNT
8074         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8075
8076         trap cleanup_test102 EXIT
8077         cd $DIR
8078         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8079         cd $DIR/$tdir
8080         for num in 1 2 3 4; do
8081                 for count in $(seq 1 $STRIPE_COUNT); do
8082                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8083                                 local size=`expr $STRIPE_SIZE \* $num`
8084                                 local file=file"$num-$idx-$count"
8085                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8086                         done
8087                 done
8088         done
8089
8090         cd $DIR
8091         $1 tar cf $TMP/f102.tar $tdir --xattrs
8092 }
8093
8094 cleanup_test102() {
8095         trap 0
8096         rm -f $TMP/f102.tar
8097         rm -rf $DIR/d0.sanity/d102
8098 }
8099
8100 test_102a() {
8101         [ "$UID" != 0 ] && skip "must run as root"
8102         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8103                 skip_env "must have user_xattr"
8104
8105         [ -z "$(which setfattr 2>/dev/null)" ] &&
8106                 skip_env "could not find setfattr"
8107
8108         local testfile=$DIR/$tfile
8109
8110         touch $testfile
8111         echo "set/get xattr..."
8112         setfattr -n trusted.name1 -v value1 $testfile ||
8113                 error "setfattr -n trusted.name1=value1 $testfile failed"
8114         getfattr -n trusted.name1 $testfile 2> /dev/null |
8115           grep "trusted.name1=.value1" ||
8116                 error "$testfile missing trusted.name1=value1"
8117
8118         setfattr -n user.author1 -v author1 $testfile ||
8119                 error "setfattr -n user.author1=author1 $testfile failed"
8120         getfattr -n user.author1 $testfile 2> /dev/null |
8121           grep "user.author1=.author1" ||
8122                 error "$testfile missing trusted.author1=author1"
8123
8124         echo "listxattr..."
8125         setfattr -n trusted.name2 -v value2 $testfile ||
8126                 error "$testfile unable to set trusted.name2"
8127         setfattr -n trusted.name3 -v value3 $testfile ||
8128                 error "$testfile unable to set trusted.name3"
8129         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8130             grep "trusted.name" | wc -l) -eq 3 ] ||
8131                 error "$testfile missing 3 trusted.name xattrs"
8132
8133         setfattr -n user.author2 -v author2 $testfile ||
8134                 error "$testfile unable to set user.author2"
8135         setfattr -n user.author3 -v author3 $testfile ||
8136                 error "$testfile unable to set user.author3"
8137         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8138             grep "user.author" | wc -l) -eq 3 ] ||
8139                 error "$testfile missing 3 user.author xattrs"
8140
8141         echo "remove xattr..."
8142         setfattr -x trusted.name1 $testfile ||
8143                 error "$testfile error deleting trusted.name1"
8144         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8145                 error "$testfile did not delete trusted.name1 xattr"
8146
8147         setfattr -x user.author1 $testfile ||
8148                 error "$testfile error deleting user.author1"
8149         echo "set lustre special xattr ..."
8150         $LFS setstripe -c1 $testfile
8151         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8152                 awk -F "=" '/trusted.lov/ { print $2 }' )
8153         setfattr -n "trusted.lov" -v $lovea $testfile ||
8154                 error "$testfile doesn't ignore setting trusted.lov again"
8155         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8156                 error "$testfile allow setting invalid trusted.lov"
8157         rm -f $testfile
8158 }
8159 run_test 102a "user xattr test =================================="
8160
8161 test_102b() {
8162         [ -z "$(which setfattr 2>/dev/null)" ] &&
8163                 skip_env "could not find setfattr"
8164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8165
8166         # b10930: get/set/list trusted.lov xattr
8167         echo "get/set/list trusted.lov xattr ..."
8168         local testfile=$DIR/$tfile
8169         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8170                 error "setstripe failed"
8171         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8172                 error "getstripe failed"
8173         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8174                 error "can't get trusted.lov from $testfile"
8175
8176         local testfile2=${testfile}2
8177         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8178                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8179
8180         $MCREATE $testfile2
8181         setfattr -n trusted.lov -v $value $testfile2
8182         local stripe_size=$($LFS getstripe -S $testfile2)
8183         local stripe_count=$($LFS getstripe -c $testfile2)
8184         [[ $stripe_size -eq 65536 ]] ||
8185                 error "stripe size $stripe_size != 65536"
8186         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8187                 error "stripe count $stripe_count != $STRIPECOUNT"
8188         rm -f $DIR/$tfile
8189 }
8190 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8191
8192 test_102c() {
8193         [ -z "$(which setfattr 2>/dev/null)" ] &&
8194                 skip_env "could not find setfattr"
8195         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8196
8197         # b10930: get/set/list lustre.lov xattr
8198         echo "get/set/list lustre.lov xattr ..."
8199         test_mkdir $DIR/$tdir
8200         chown $RUNAS_ID $DIR/$tdir
8201         local testfile=$DIR/$tdir/$tfile
8202         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8203                 error "setstripe failed"
8204         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8205                 error "getstripe failed"
8206         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8207         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8208
8209         local testfile2=${testfile}2
8210         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8211                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8212
8213         $RUNAS $MCREATE $testfile2
8214         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8215         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8216         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8217         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8218         [ $stripe_count -eq $STRIPECOUNT ] ||
8219                 error "stripe count $stripe_count != $STRIPECOUNT"
8220 }
8221 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8222
8223 compare_stripe_info1() {
8224         local stripe_index_all_zero=true
8225
8226         for num in 1 2 3 4; do
8227                 for count in $(seq 1 $STRIPE_COUNT); do
8228                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8229                                 local size=$((STRIPE_SIZE * num))
8230                                 local file=file"$num-$offset-$count"
8231                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8232                                 [[ $stripe_size -ne $size ]] &&
8233                                     error "$file: size $stripe_size != $size"
8234                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8235                                 # allow fewer stripes to be created, ORI-601
8236                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8237                                     error "$file: count $stripe_count != $count"
8238                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8239                                 [[ $stripe_index -ne 0 ]] &&
8240                                         stripe_index_all_zero=false
8241                         done
8242                 done
8243         done
8244         $stripe_index_all_zero &&
8245                 error "all files are being extracted starting from OST index 0"
8246         return 0
8247 }
8248
8249 have_xattrs_include() {
8250         tar --help | grep -q xattrs-include &&
8251                 echo --xattrs-include="lustre.*"
8252 }
8253
8254 test_102d() {
8255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8257
8258         XINC=$(have_xattrs_include)
8259         setup_test102
8260         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8261         cd $DIR/$tdir/$tdir
8262         compare_stripe_info1
8263 }
8264 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8265
8266 test_102f() {
8267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8268         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8269
8270         XINC=$(have_xattrs_include)
8271         setup_test102
8272         test_mkdir $DIR/$tdir.restore
8273         cd $DIR
8274         tar cf - --xattrs $tdir | tar xf - \
8275                 -C $DIR/$tdir.restore --xattrs $XINC
8276         cd $DIR/$tdir.restore/$tdir
8277         compare_stripe_info1
8278 }
8279 run_test 102f "tar copy files, not keep osts"
8280
8281 grow_xattr() {
8282         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8283                 skip "must have user_xattr"
8284         [ -z "$(which setfattr 2>/dev/null)" ] &&
8285                 skip_env "could not find setfattr"
8286         [ -z "$(which getfattr 2>/dev/null)" ] &&
8287                 skip_env "could not find getfattr"
8288
8289         local xsize=${1:-1024}  # in bytes
8290         local file=$DIR/$tfile
8291         local value="$(generate_string $xsize)"
8292         local xbig=trusted.big
8293
8294         touch $file
8295         log "save $xbig on $file"
8296         setfattr -n $xbig -v $value $file ||
8297                 error "saving $xbig on $file failed"
8298
8299         local orig=$(get_xattr_value $xbig $file)
8300         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8301
8302         local xsml=trusted.sml
8303         log "save $xsml on $file"
8304         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8305
8306         local new=$(get_xattr_value $xbig $file)
8307         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8308
8309         log "grow $xsml on $file"
8310         setfattr -n $xsml -v "$value" $file ||
8311                 error "growing $xsml on $file failed"
8312
8313         new=$(get_xattr_value $xbig $file)
8314         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8315         log "$xbig still valid after growing $xsml"
8316
8317         rm -f $file
8318 }
8319
8320 test_102h() { # bug 15777
8321         grow_xattr 1024
8322 }
8323 run_test 102h "grow xattr from inside inode to external block"
8324
8325 test_102ha() {
8326         large_xattr_enabled || skip_env "ea_inode feature disabled"
8327
8328         grow_xattr $(max_xattr_size)
8329 }
8330 run_test 102ha "grow xattr from inside inode to external inode"
8331
8332 test_102i() { # bug 17038
8333         [ -z "$(which getfattr 2>/dev/null)" ] &&
8334                 skip "could not find getfattr"
8335
8336         touch $DIR/$tfile
8337         ln -s $DIR/$tfile $DIR/${tfile}link
8338         getfattr -n trusted.lov $DIR/$tfile ||
8339                 error "lgetxattr on $DIR/$tfile failed"
8340         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8341                 grep -i "no such attr" ||
8342                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8343         rm -f $DIR/$tfile $DIR/${tfile}link
8344 }
8345 run_test 102i "lgetxattr test on symbolic link ============"
8346
8347 test_102j() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8350
8351         XINC=$(have_xattrs_include)
8352         setup_test102 "$RUNAS"
8353         chown $RUNAS_ID $DIR/$tdir
8354         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8355         cd $DIR/$tdir/$tdir
8356         compare_stripe_info1 "$RUNAS"
8357 }
8358 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8359
8360 test_102k() {
8361         [ -z "$(which setfattr 2>/dev/null)" ] &&
8362                 skip "could not find setfattr"
8363
8364         touch $DIR/$tfile
8365         # b22187 just check that does not crash for regular file.
8366         setfattr -n trusted.lov $DIR/$tfile
8367         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8368         local test_kdir=$DIR/$tdir
8369         test_mkdir $test_kdir
8370         local default_size=$($LFS getstripe -S $test_kdir)
8371         local default_count=$($LFS getstripe -c $test_kdir)
8372         local default_offset=$($LFS getstripe -i $test_kdir)
8373         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8374                 error 'dir setstripe failed'
8375         setfattr -n trusted.lov $test_kdir
8376         local stripe_size=$($LFS getstripe -S $test_kdir)
8377         local stripe_count=$($LFS getstripe -c $test_kdir)
8378         local stripe_offset=$($LFS getstripe -i $test_kdir)
8379         [ $stripe_size -eq $default_size ] ||
8380                 error "stripe size $stripe_size != $default_size"
8381         [ $stripe_count -eq $default_count ] ||
8382                 error "stripe count $stripe_count != $default_count"
8383         [ $stripe_offset -eq $default_offset ] ||
8384                 error "stripe offset $stripe_offset != $default_offset"
8385         rm -rf $DIR/$tfile $test_kdir
8386 }
8387 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8388
8389 test_102l() {
8390         [ -z "$(which getfattr 2>/dev/null)" ] &&
8391                 skip "could not find getfattr"
8392
8393         # LU-532 trusted. xattr is invisible to non-root
8394         local testfile=$DIR/$tfile
8395
8396         touch $testfile
8397
8398         echo "listxattr as user..."
8399         chown $RUNAS_ID $testfile
8400         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8401             grep -q "trusted" &&
8402                 error "$testfile trusted xattrs are user visible"
8403
8404         return 0;
8405 }
8406 run_test 102l "listxattr size test =================================="
8407
8408 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8409         local path=$DIR/$tfile
8410         touch $path
8411
8412         listxattr_size_check $path || error "listattr_size_check $path failed"
8413 }
8414 run_test 102m "Ensure listxattr fails on small bufffer ========"
8415
8416 cleanup_test102
8417
8418 getxattr() { # getxattr path name
8419         # Return the base64 encoding of the value of xattr name on path.
8420         local path=$1
8421         local name=$2
8422
8423         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8424         # file: $path
8425         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8426         #
8427         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8428
8429         getfattr --absolute-names --encoding=base64 --name=$name $path |
8430                 awk -F= -v name=$name '$1 == name {
8431                         print substr($0, index($0, "=") + 1);
8432         }'
8433 }
8434
8435 test_102n() { # LU-4101 mdt: protect internal xattrs
8436         [ -z "$(which setfattr 2>/dev/null)" ] &&
8437                 skip "could not find setfattr"
8438         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8439         then
8440                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8441         fi
8442
8443         local file0=$DIR/$tfile.0
8444         local file1=$DIR/$tfile.1
8445         local xattr0=$TMP/$tfile.0
8446         local xattr1=$TMP/$tfile.1
8447         local namelist="lov lma lmv link fid version som hsm"
8448         local name
8449         local value
8450
8451         rm -rf $file0 $file1 $xattr0 $xattr1
8452         touch $file0 $file1
8453
8454         # Get 'before' xattrs of $file1.
8455         getfattr --absolute-names --dump --match=- $file1 > $xattr0
8456
8457         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
8458                 namelist+=" lfsck_namespace"
8459         for name in $namelist; do
8460                 # Try to copy xattr from $file0 to $file1.
8461                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8462
8463                 setfattr --name=trusted.$name --value="$value" $file1 ||
8464                         error "setxattr 'trusted.$name' failed"
8465
8466                 # Try to set a garbage xattr.
8467                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8468
8469                 if [[ x$name == "xlov" ]]; then
8470                         setfattr --name=trusted.lov --value="$value" $file1 &&
8471                         error "setxattr invalid 'trusted.lov' success"
8472                 else
8473                         setfattr --name=trusted.$name --value="$value" $file1 ||
8474                                 error "setxattr invalid 'trusted.$name' failed"
8475                 fi
8476
8477                 # Try to remove the xattr from $file1. We don't care if this
8478                 # appears to succeed or fail, we just don't want there to be
8479                 # any changes or crashes.
8480                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8481         done
8482
8483         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
8484         then
8485                 name="lfsck_ns"
8486                 # Try to copy xattr from $file0 to $file1.
8487                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
8488
8489                 setfattr --name=trusted.$name --value="$value" $file1 ||
8490                         error "setxattr 'trusted.$name' failed"
8491
8492                 # Try to set a garbage xattr.
8493                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
8494
8495                 setfattr --name=trusted.$name --value="$value" $file1 ||
8496                         error "setxattr 'trusted.$name' failed"
8497
8498                 # Try to remove the xattr from $file1. We don't care if this
8499                 # appears to succeed or fail, we just don't want there to be
8500                 # any changes or crashes.
8501                 setfattr --remove=$trusted.$name $file1 2> /dev/null
8502         fi
8503
8504         # Get 'after' xattrs of file1.
8505         getfattr --absolute-names --dump --match=- $file1 > $xattr1
8506
8507         if ! diff $xattr0 $xattr1; then
8508                 error "before and after xattrs of '$file1' differ"
8509         fi
8510
8511         rm -rf $file0 $file1 $xattr0 $xattr1
8512
8513         return 0
8514 }
8515 run_test 102n "silently ignore setxattr on internal trusted xattrs"
8516
8517 test_102p() { # LU-4703 setxattr did not check ownership
8518         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
8519                 skip "MDS needs to be at least 2.5.56"
8520
8521         local testfile=$DIR/$tfile
8522
8523         touch $testfile
8524
8525         echo "setfacl as user..."
8526         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
8527         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
8528
8529         echo "setfattr as user..."
8530         setfacl -m "u:$RUNAS_ID:---" $testfile
8531         $RUNAS setfattr -x system.posix_acl_access $testfile
8532         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
8533 }
8534 run_test 102p "check setxattr(2) correctly fails without permission"
8535
8536 test_102q() {
8537         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
8538                 skip "MDS needs to be at least 2.6.92"
8539
8540         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
8541 }
8542 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
8543
8544 test_102r() {
8545         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
8546                 skip "MDS needs to be at least 2.6.93"
8547
8548         touch $DIR/$tfile || error "touch"
8549         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
8550         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
8551         rm $DIR/$tfile || error "rm"
8552
8553         #normal directory
8554         mkdir -p $DIR/$tdir || error "mkdir"
8555         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8556         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8557         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8558                 error "$testfile error deleting user.author1"
8559         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8560                 grep "user.$(basename $tdir)" &&
8561                 error "$tdir did not delete user.$(basename $tdir)"
8562         rmdir $DIR/$tdir || error "rmdir"
8563
8564         #striped directory
8565         test_mkdir $DIR/$tdir
8566         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
8567         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
8568         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
8569                 error "$testfile error deleting user.author1"
8570         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
8571                 grep "user.$(basename $tdir)" &&
8572                 error "$tdir did not delete user.$(basename $tdir)"
8573         rmdir $DIR/$tdir || error "rm striped dir"
8574 }
8575 run_test 102r "set EAs with empty values"
8576
8577 test_102s() {
8578         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8579                 skip "MDS needs to be at least 2.11.52"
8580
8581         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8582
8583         save_lustre_params client "llite.*.xattr_cache" > $save
8584
8585         for cache in 0 1; do
8586                 lctl set_param llite.*.xattr_cache=$cache
8587
8588                 rm -f $DIR/$tfile
8589                 touch $DIR/$tfile || error "touch"
8590                 for prefix in lustre security system trusted user; do
8591                         # Note getxattr() may fail with 'Operation not
8592                         # supported' or 'No such attribute' depending
8593                         # on prefix and cache.
8594                         getfattr -n $prefix.n102s $DIR/$tfile &&
8595                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
8596                 done
8597         done
8598
8599         restore_lustre_params < $save
8600 }
8601 run_test 102s "getting nonexistent xattrs should fail"
8602
8603 test_102t() {
8604         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
8605                 skip "MDS needs to be at least 2.11.52"
8606
8607         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
8608
8609         save_lustre_params client "llite.*.xattr_cache" > $save
8610
8611         for cache in 0 1; do
8612                 lctl set_param llite.*.xattr_cache=$cache
8613
8614                 for buf_size in 0 256; do
8615                         rm -f $DIR/$tfile
8616                         touch $DIR/$tfile || error "touch"
8617                         setfattr -n user.multiop $DIR/$tfile
8618                         $MULTIOP $DIR/$tfile oa$buf_size ||
8619                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
8620                 done
8621         done
8622
8623         restore_lustre_params < $save
8624 }
8625 run_test 102t "zero length xattr values handled correctly"
8626
8627 run_acl_subtest()
8628 {
8629     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
8630     return $?
8631 }
8632
8633 test_103a() {
8634         [ "$UID" != 0 ] && skip "must run as root"
8635         $GSS && skip_env "could not run under gss"
8636         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
8637                 skip_env "must have acl enabled"
8638         [ -z "$(which setfacl 2>/dev/null)" ] &&
8639                 skip_env "could not find setfacl"
8640         remote_mds_nodsh && skip "remote MDS with nodsh"
8641
8642         gpasswd -a daemon bin                           # LU-5641
8643         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
8644
8645         declare -a identity_old
8646
8647         for num in $(seq $MDSCOUNT); do
8648                 switch_identity $num true || identity_old[$num]=$?
8649         done
8650
8651         SAVE_UMASK=$(umask)
8652         umask 0022
8653         mkdir -p $DIR/$tdir
8654         cd $DIR/$tdir
8655
8656         echo "performing cp ..."
8657         run_acl_subtest cp || error "run_acl_subtest cp failed"
8658         echo "performing getfacl-noacl..."
8659         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
8660         echo "performing misc..."
8661         run_acl_subtest misc || error  "misc test failed"
8662         echo "performing permissions..."
8663         run_acl_subtest permissions || error "permissions failed"
8664         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
8665         if [ $MDS1_VERSION -gt $(version_code 2.8.55) -o \
8666              \( $MDS1_VERSION -lt $(version_code 2.6) -a \
8667              $MDS1_VERSION -ge $(version_code 2.5.29) \) ]
8668         then
8669                 echo "performing permissions xattr..."
8670                 run_acl_subtest permissions_xattr ||
8671                         error "permissions_xattr failed"
8672         fi
8673         echo "performing setfacl..."
8674         run_acl_subtest setfacl || error  "setfacl test failed"
8675
8676         # inheritance test got from HP
8677         echo "performing inheritance..."
8678         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
8679         chmod +x make-tree || error "chmod +x failed"
8680         run_acl_subtest inheritance || error "inheritance test failed"
8681         rm -f make-tree
8682
8683         echo "LU-974 ignore umask when acl is enabled..."
8684         run_acl_subtest 974 || error "LU-974 umask test failed"
8685         if [ $MDSCOUNT -ge 2 ]; then
8686                 run_acl_subtest 974_remote ||
8687                         error "LU-974 umask test failed under remote dir"
8688         fi
8689
8690         echo "LU-2561 newly created file is same size as directory..."
8691         if [ "$mds1_FSTYPE" != "zfs" ]; then
8692                 run_acl_subtest 2561 || error "LU-2561 test failed"
8693         else
8694                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
8695         fi
8696
8697         run_acl_subtest 4924 || error "LU-4924 test failed"
8698
8699         cd $SAVE_PWD
8700         umask $SAVE_UMASK
8701
8702         for num in $(seq $MDSCOUNT); do
8703                 if [ "${identity_old[$num]}" = 1 ]; then
8704                         switch_identity $num false || identity_old[$num]=$?
8705                 fi
8706         done
8707 }
8708 run_test 103a "acl test"
8709
8710 test_103b() {
8711         declare -a pids
8712         local U
8713
8714         for U in {0..511}; do
8715                 {
8716                 local O=$(printf "%04o" $U)
8717
8718                 umask $(printf "%04o" $((511 ^ $O)))
8719                 $LFS setstripe -c 1 $DIR/$tfile.s$O
8720                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
8721
8722                 (( $S == ($O & 0666) )) ||
8723                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
8724
8725                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
8726                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
8727                 (( $S == ($O & 0666) )) ||
8728                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
8729
8730                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
8731                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
8732                 (( $S == ($O & 0666) )) ||
8733                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
8734                 rm -f $DIR/$tfile.[smp]$0
8735                 } &
8736                 local pid=$!
8737
8738                 # limit the concurrently running threads to 64. LU-11878
8739                 local idx=$((U % 64))
8740                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
8741                 pids[idx]=$pid
8742         done
8743         wait
8744 }
8745 run_test 103b "umask lfs setstripe"
8746
8747 test_103c() {
8748         mkdir -p $DIR/$tdir
8749         cp -rp $DIR/$tdir $DIR/$tdir.bak
8750
8751         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
8752                 error "$DIR/$tdir shouldn't contain default ACL"
8753         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
8754                 error "$DIR/$tdir.bak shouldn't contain default ACL"
8755         true
8756 }
8757 run_test 103c "'cp -rp' won't set empty acl"
8758
8759 test_104a() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761
8762         touch $DIR/$tfile
8763         lfs df || error "lfs df failed"
8764         lfs df -ih || error "lfs df -ih failed"
8765         lfs df -h $DIR || error "lfs df -h $DIR failed"
8766         lfs df -i $DIR || error "lfs df -i $DIR failed"
8767         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
8768         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
8769
8770         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
8771         lctl --device %$OSC deactivate
8772         lfs df || error "lfs df with deactivated OSC failed"
8773         lctl --device %$OSC activate
8774         # wait the osc back to normal
8775         wait_osc_import_ready client ost
8776
8777         lfs df || error "lfs df with reactivated OSC failed"
8778         rm -f $DIR/$tfile
8779 }
8780 run_test 104a "lfs df [-ih] [path] test ========================="
8781
8782 test_104b() {
8783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8784         [ $RUNAS_ID -eq $UID ] &&
8785                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8786
8787         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
8788                         grep "Permission denied" | wc -l)))
8789         if [ $denied_cnt -ne 0 ]; then
8790                 error "lfs check servers test failed"
8791         fi
8792 }
8793 run_test 104b "$RUNAS lfs check servers test ===================="
8794
8795 test_105a() {
8796         # doesn't work on 2.4 kernels
8797         touch $DIR/$tfile
8798         if $(flock_is_enabled); then
8799                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
8800         else
8801                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
8802         fi
8803         rm -f $DIR/$tfile
8804 }
8805 run_test 105a "flock when mounted without -o flock test ========"
8806
8807 test_105b() {
8808         touch $DIR/$tfile
8809         if $(flock_is_enabled); then
8810                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
8811         else
8812                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
8813         fi
8814         rm -f $DIR/$tfile
8815 }
8816 run_test 105b "fcntl when mounted without -o flock test ========"
8817
8818 test_105c() {
8819         touch $DIR/$tfile
8820         if $(flock_is_enabled); then
8821                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
8822         else
8823                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
8824         fi
8825         rm -f $DIR/$tfile
8826 }
8827 run_test 105c "lockf when mounted without -o flock test"
8828
8829 test_105d() { # bug 15924
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831
8832         test_mkdir $DIR/$tdir
8833         flock_is_enabled || skip_env "mount w/o flock enabled"
8834         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
8835         $LCTL set_param fail_loc=0x80000315
8836         flocks_test 2 $DIR/$tdir
8837 }
8838 run_test 105d "flock race (should not freeze) ========"
8839
8840 test_105e() { # bug 22660 && 22040
8841         flock_is_enabled || skip_env "mount w/o flock enabled"
8842
8843         touch $DIR/$tfile
8844         flocks_test 3 $DIR/$tfile
8845 }
8846 run_test 105e "Two conflicting flocks from same process"
8847
8848 test_106() { #bug 10921
8849         test_mkdir $DIR/$tdir
8850         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
8851         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
8852 }
8853 run_test 106 "attempt exec of dir followed by chown of that dir"
8854
8855 test_107() {
8856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8857
8858         CDIR=`pwd`
8859         local file=core
8860
8861         cd $DIR
8862         rm -f $file
8863
8864         local save_pattern=$(sysctl -n kernel.core_pattern)
8865         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
8866         sysctl -w kernel.core_pattern=$file
8867         sysctl -w kernel.core_uses_pid=0
8868
8869         ulimit -c unlimited
8870         sleep 60 &
8871         SLEEPPID=$!
8872
8873         sleep 1
8874
8875         kill -s 11 $SLEEPPID
8876         wait $SLEEPPID
8877         if [ -e $file ]; then
8878                 size=`stat -c%s $file`
8879                 [ $size -eq 0 ] && error "Fail to create core file $file"
8880         else
8881                 error "Fail to create core file $file"
8882         fi
8883         rm -f $file
8884         sysctl -w kernel.core_pattern=$save_pattern
8885         sysctl -w kernel.core_uses_pid=$save_uses_pid
8886         cd $CDIR
8887 }
8888 run_test 107 "Coredump on SIG"
8889
8890 test_110() {
8891         test_mkdir $DIR/$tdir
8892         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
8893         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
8894                 error "mkdir with 256 char should fail, but did not"
8895         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
8896                 error "create with 255 char failed"
8897         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
8898                 error "create with 256 char should fail, but did not"
8899
8900         ls -l $DIR/$tdir
8901         rm -rf $DIR/$tdir
8902 }
8903 run_test 110 "filename length checking"
8904
8905 #
8906 # Purpose: To verify dynamic thread (OSS) creation.
8907 #
8908 test_115() {
8909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8910         remote_ost_nodsh && skip "remote OST with nodsh"
8911
8912         # Lustre does not stop service threads once they are started.
8913         # Reset number of running threads to default.
8914         stopall
8915         setupall
8916
8917         local OSTIO_pre
8918         local save_params="$TMP/sanity-$TESTNAME.parameters"
8919
8920         # Get ll_ost_io count before I/O
8921         OSTIO_pre=$(do_facet ost1 \
8922                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
8923         # Exit if lustre is not running (ll_ost_io not running).
8924         [ -z "$OSTIO_pre" ] && error "no OSS threads"
8925
8926         echo "Starting with $OSTIO_pre threads"
8927         local thread_max=$((OSTIO_pre * 2))
8928         local rpc_in_flight=$((thread_max * 2))
8929         # Number of I/O Process proposed to be started.
8930         local nfiles
8931         local facets=$(get_facets OST)
8932
8933         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
8934         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
8935
8936         # Set in_flight to $rpc_in_flight
8937         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
8938                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
8939         nfiles=${rpc_in_flight}
8940         # Set ost thread_max to $thread_max
8941         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
8942
8943         # 5 Minutes should be sufficient for max number of OSS
8944         # threads(thread_max) to be created.
8945         local timeout=300
8946
8947         # Start I/O.
8948         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
8949         test_mkdir $DIR/$tdir
8950         for i in $(seq $nfiles); do
8951                 local file=$DIR/$tdir/${tfile}-$i
8952                 $LFS setstripe -c -1 -i 0 $file
8953                 ($WTL $file $timeout)&
8954         done
8955
8956         # I/O Started - Wait for thread_started to reach thread_max or report
8957         # error if thread_started is more than thread_max.
8958         echo "Waiting for thread_started to reach thread_max"
8959         local thread_started=0
8960         local end_time=$((SECONDS + timeout))
8961
8962         while [ $SECONDS -le $end_time ] ; do
8963                 echo -n "."
8964                 # Get ost i/o thread_started count.
8965                 thread_started=$(do_facet ost1 \
8966                         "$LCTL get_param \
8967                         ost.OSS.ost_io.threads_started | cut -d= -f2")
8968                 # Break out if thread_started is equal/greater than thread_max
8969                 if [[ $thread_started -ge $thread_max ]]; then
8970                         echo ll_ost_io thread_started $thread_started, \
8971                                 equal/greater than thread_max $thread_max
8972                         break
8973                 fi
8974                 sleep 1
8975         done
8976
8977         # Cleanup - We have the numbers, Kill i/o jobs if running.
8978         jobcount=($(jobs -p))
8979         for i in $(seq 0 $((${#jobcount[@]}-1)))
8980         do
8981                 kill -9 ${jobcount[$i]}
8982                 if [ $? -ne 0 ] ; then
8983                         echo Warning: \
8984                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
8985                 fi
8986         done
8987
8988         # Cleanup files left by WTL binary.
8989         for i in $(seq $nfiles); do
8990                 local file=$DIR/$tdir/${tfile}-$i
8991                 rm -rf $file
8992                 if [ $? -ne 0 ] ; then
8993                         echo "Warning: Failed to delete file $file"
8994                 fi
8995         done
8996
8997         restore_lustre_params <$save_params
8998         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
8999
9000         # Error out if no new thread has started or Thread started is greater
9001         # than thread max.
9002         if [[ $thread_started -le $OSTIO_pre ||
9003                         $thread_started -gt $thread_max ]]; then
9004                 error "ll_ost_io: thread_started $thread_started" \
9005                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9006                       "No new thread started or thread started greater " \
9007                       "than thread_max."
9008         fi
9009 }
9010 run_test 115 "verify dynamic thread creation===================="
9011
9012 free_min_max () {
9013         wait_delete_completed
9014         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9015         echo "OST kbytes available: ${AVAIL[@]}"
9016         MAXV=${AVAIL[0]}
9017         MAXI=0
9018         MINV=${AVAIL[0]}
9019         MINI=0
9020         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9021                 #echo OST $i: ${AVAIL[i]}kb
9022                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9023                         MAXV=${AVAIL[i]}
9024                         MAXI=$i
9025                 fi
9026                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9027                         MINV=${AVAIL[i]}
9028                         MINI=$i
9029                 fi
9030         done
9031         echo "Min free space: OST $MINI: $MINV"
9032         echo "Max free space: OST $MAXI: $MAXV"
9033 }
9034
9035 test_116a() { # was previously test_116()
9036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9037         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9038         remote_mds_nodsh && skip "remote MDS with nodsh"
9039
9040         echo -n "Free space priority "
9041         do_facet $SINGLEMDS lctl get_param -n lo*.*-mdtlov.qos_prio_free |
9042                 head -n1
9043         declare -a AVAIL
9044         free_min_max
9045
9046         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9047         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9048         trap simple_cleanup_common EXIT
9049
9050         # Check if we need to generate uneven OSTs
9051         test_mkdir -p $DIR/$tdir/OST${MINI}
9052         local FILL=$((MINV / 4))
9053         local DIFF=$((MAXV - MINV))
9054         local DIFF2=$((DIFF * 100 / MINV))
9055
9056         local threshold=$(do_facet $SINGLEMDS \
9057                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9058         threshold=${threshold%%%}
9059         echo -n "Check for uneven OSTs: "
9060         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9061
9062         if [[ $DIFF2 -gt $threshold ]]; then
9063                 echo "ok"
9064                 echo "Don't need to fill OST$MINI"
9065         else
9066                 # generate uneven OSTs. Write 2% over the QOS threshold value
9067                 echo "no"
9068                 DIFF=$((threshold - DIFF2 + 2))
9069                 DIFF2=$((MINV * DIFF / 100))
9070                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9071                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9072                         error "setstripe failed"
9073                 DIFF=$((DIFF2 / 2048))
9074                 i=0
9075                 while [ $i -lt $DIFF ]; do
9076                         i=$((i + 1))
9077                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9078                                 bs=2M count=1 2>/dev/null
9079                         echo -n .
9080                 done
9081                 echo .
9082                 sync
9083                 sleep_maxage
9084                 free_min_max
9085         fi
9086
9087         DIFF=$((MAXV - MINV))
9088         DIFF2=$((DIFF * 100 / MINV))
9089         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9090         if [ $DIFF2 -gt $threshold ]; then
9091                 echo "ok"
9092         else
9093                 echo "failed - QOS mode won't be used"
9094                 simple_cleanup_common
9095                 skip "QOS imbalance criteria not met"
9096         fi
9097
9098         MINI1=$MINI
9099         MINV1=$MINV
9100         MAXI1=$MAXI
9101         MAXV1=$MAXV
9102
9103         # now fill using QOS
9104         $LFS setstripe -c 1 $DIR/$tdir
9105         FILL=$((FILL / 200))
9106         if [ $FILL -gt 600 ]; then
9107                 FILL=600
9108         fi
9109         echo "writing $FILL files to QOS-assigned OSTs"
9110         i=0
9111         while [ $i -lt $FILL ]; do
9112                 i=$((i + 1))
9113                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9114                         count=1 2>/dev/null
9115                 echo -n .
9116         done
9117         echo "wrote $i 200k files"
9118         sync
9119         sleep_maxage
9120
9121         echo "Note: free space may not be updated, so measurements might be off"
9122         free_min_max
9123         DIFF2=$((MAXV - MINV))
9124         echo "free space delta: orig $DIFF final $DIFF2"
9125         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9126         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9127         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9128         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9129         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9130         if [[ $DIFF -gt 0 ]]; then
9131                 FILL=$((DIFF2 * 100 / DIFF - 100))
9132                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9133         fi
9134
9135         # Figure out which files were written where
9136         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9137                awk '/'$MINI1': / {print $2; exit}')
9138         echo $UUID
9139         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9140         echo "$MINC files created on smaller OST $MINI1"
9141         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9142                awk '/'$MAXI1': / {print $2; exit}')
9143         echo $UUID
9144         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9145         echo "$MAXC files created on larger OST $MAXI1"
9146         if [[ $MINC -gt 0 ]]; then
9147                 FILL=$((MAXC * 100 / MINC - 100))
9148                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9149         fi
9150         [[ $MAXC -gt $MINC ]] ||
9151                 error_ignore LU-9 "stripe QOS didn't balance free space"
9152         simple_cleanup_common
9153 }
9154 run_test 116a "stripe QOS: free space balance ==================="
9155
9156 test_116b() { # LU-2093
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158         remote_mds_nodsh && skip "remote MDS with nodsh"
9159
9160 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9161         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9162                        lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9163         [ -z "$old_rr" ] && skip "no QOS"
9164         do_facet $SINGLEMDS lctl set_param \
9165                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9166         mkdir -p $DIR/$tdir
9167         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9168         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9169         do_facet $SINGLEMDS lctl set_param fail_loc=0
9170         rm -rf $DIR/$tdir
9171         do_facet $SINGLEMDS lctl set_param \
9172                 lo*.$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9173 }
9174 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9175
9176 test_117() # bug 10891
9177 {
9178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9179
9180         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9181         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9182         lctl set_param fail_loc=0x21e
9183         > $DIR/$tfile || error "truncate failed"
9184         lctl set_param fail_loc=0
9185         echo "Truncate succeeded."
9186         rm -f $DIR/$tfile
9187 }
9188 run_test 117 "verify osd extend =========="
9189
9190 NO_SLOW_RESENDCOUNT=4
9191 export OLD_RESENDCOUNT=""
9192 set_resend_count () {
9193         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9194         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9195         lctl set_param -n $PROC_RESENDCOUNT $1
9196         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9197 }
9198
9199 # for reduce test_118* time (b=14842)
9200 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9201
9202 # Reset async IO behavior after error case
9203 reset_async() {
9204         FILE=$DIR/reset_async
9205
9206         # Ensure all OSCs are cleared
9207         $LFS setstripe -c -1 $FILE
9208         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9209         sync
9210         rm $FILE
9211 }
9212
9213 test_118a() #bug 11710
9214 {
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216
9217         reset_async
9218
9219         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9220         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9221         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9222
9223         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9224                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9225                 return 1;
9226         fi
9227         rm -f $DIR/$tfile
9228 }
9229 run_test 118a "verify O_SYNC works =========="
9230
9231 test_118b()
9232 {
9233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9234         remote_ost_nodsh && skip "remote OST with nodsh"
9235
9236         reset_async
9237
9238         #define OBD_FAIL_SRV_ENOENT 0x217
9239         set_nodes_failloc "$(osts_nodes)" 0x217
9240         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9241         RC=$?
9242         set_nodes_failloc "$(osts_nodes)" 0
9243         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9244         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9245                     grep -c writeback)
9246
9247         if [[ $RC -eq 0 ]]; then
9248                 error "Must return error due to dropped pages, rc=$RC"
9249                 return 1;
9250         fi
9251
9252         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9253                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9254                 return 1;
9255         fi
9256
9257         echo "Dirty pages not leaked on ENOENT"
9258
9259         # Due to the above error the OSC will issue all RPCs syncronously
9260         # until a subsequent RPC completes successfully without error.
9261         $MULTIOP $DIR/$tfile Ow4096yc
9262         rm -f $DIR/$tfile
9263
9264         return 0
9265 }
9266 run_test 118b "Reclaim dirty pages on fatal error =========="
9267
9268 test_118c()
9269 {
9270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9271
9272         # for 118c, restore the original resend count, LU-1940
9273         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9274                                 set_resend_count $OLD_RESENDCOUNT
9275         remote_ost_nodsh && skip "remote OST with nodsh"
9276
9277         reset_async
9278
9279         #define OBD_FAIL_OST_EROFS               0x216
9280         set_nodes_failloc "$(osts_nodes)" 0x216
9281
9282         # multiop should block due to fsync until pages are written
9283         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9284         MULTIPID=$!
9285         sleep 1
9286
9287         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9288                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9289         fi
9290
9291         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9292                     grep -c writeback)
9293         if [[ $WRITEBACK -eq 0 ]]; then
9294                 error "No page in writeback, writeback=$WRITEBACK"
9295         fi
9296
9297         set_nodes_failloc "$(osts_nodes)" 0
9298         wait $MULTIPID
9299         RC=$?
9300         if [[ $RC -ne 0 ]]; then
9301                 error "Multiop fsync failed, rc=$RC"
9302         fi
9303
9304         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9305         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9306                     grep -c writeback)
9307         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9308                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9309         fi
9310
9311         rm -f $DIR/$tfile
9312         echo "Dirty pages flushed via fsync on EROFS"
9313         return 0
9314 }
9315 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9316
9317 # continue to use small resend count to reduce test_118* time (b=14842)
9318 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9319
9320 test_118d()
9321 {
9322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9323         remote_ost_nodsh && skip "remote OST with nodsh"
9324
9325         reset_async
9326
9327         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9328         set_nodes_failloc "$(osts_nodes)" 0x214
9329         # multiop should block due to fsync until pages are written
9330         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9331         MULTIPID=$!
9332         sleep 1
9333
9334         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9335                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9336         fi
9337
9338         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9339                     grep -c writeback)
9340         if [[ $WRITEBACK -eq 0 ]]; then
9341                 error "No page in writeback, writeback=$WRITEBACK"
9342         fi
9343
9344         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9345         set_nodes_failloc "$(osts_nodes)" 0
9346
9347         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9348         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9349                     grep -c writeback)
9350         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9351                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9352         fi
9353
9354         rm -f $DIR/$tfile
9355         echo "Dirty pages gaurenteed flushed via fsync"
9356         return 0
9357 }
9358 run_test 118d "Fsync validation inject a delay of the bulk =========="
9359
9360 test_118f() {
9361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9362
9363         reset_async
9364
9365         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9366         lctl set_param fail_loc=0x8000040a
9367
9368         # Should simulate EINVAL error which is fatal
9369         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9370         RC=$?
9371         if [[ $RC -eq 0 ]]; then
9372                 error "Must return error due to dropped pages, rc=$RC"
9373         fi
9374
9375         lctl set_param fail_loc=0x0
9376
9377         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9378         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9379         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9380                     grep -c writeback)
9381         if [[ $LOCKED -ne 0 ]]; then
9382                 error "Locked pages remain in cache, locked=$LOCKED"
9383         fi
9384
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 "No pages locked after fsync"
9391
9392         reset_async
9393         return 0
9394 }
9395 run_test 118f "Simulate unrecoverable OSC side error =========="
9396
9397 test_118g() {
9398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9399
9400         reset_async
9401
9402         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9403         lctl set_param fail_loc=0x406
9404
9405         # simulate local -ENOMEM
9406         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9407         RC=$?
9408
9409         lctl set_param fail_loc=0
9410         if [[ $RC -eq 0 ]]; then
9411                 error "Must return error due to dropped pages, rc=$RC"
9412         fi
9413
9414         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9415         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9416         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9417                         grep -c writeback)
9418         if [[ $LOCKED -ne 0 ]]; then
9419                 error "Locked pages remain in cache, locked=$LOCKED"
9420         fi
9421
9422         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9423                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9424         fi
9425
9426         rm -f $DIR/$tfile
9427         echo "No pages locked after fsync"
9428
9429         reset_async
9430         return 0
9431 }
9432 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9433
9434 test_118h() {
9435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9436         remote_ost_nodsh && skip "remote OST with nodsh"
9437
9438         reset_async
9439
9440         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9441         set_nodes_failloc "$(osts_nodes)" 0x20e
9442         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9443         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9444         RC=$?
9445
9446         set_nodes_failloc "$(osts_nodes)" 0
9447         if [[ $RC -eq 0 ]]; then
9448                 error "Must return error due to dropped pages, rc=$RC"
9449         fi
9450
9451         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9452         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9453         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9454                     grep -c writeback)
9455         if [[ $LOCKED -ne 0 ]]; then
9456                 error "Locked pages remain in cache, locked=$LOCKED"
9457         fi
9458
9459         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9460                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9461         fi
9462
9463         rm -f $DIR/$tfile
9464         echo "No pages locked after fsync"
9465
9466         return 0
9467 }
9468 run_test 118h "Verify timeout in handling recoverables errors  =========="
9469
9470 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9471
9472 test_118i() {
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         remote_ost_nodsh && skip "remote OST with nodsh"
9475
9476         reset_async
9477
9478         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9479         set_nodes_failloc "$(osts_nodes)" 0x20e
9480
9481         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9482         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9483         PID=$!
9484         sleep 5
9485         set_nodes_failloc "$(osts_nodes)" 0
9486
9487         wait $PID
9488         RC=$?
9489         if [[ $RC -ne 0 ]]; then
9490                 error "got error, but should be not, rc=$RC"
9491         fi
9492
9493         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9494         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9495         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9496         if [[ $LOCKED -ne 0 ]]; then
9497                 error "Locked pages remain in cache, locked=$LOCKED"
9498         fi
9499
9500         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9501                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9502         fi
9503
9504         rm -f $DIR/$tfile
9505         echo "No pages locked after fsync"
9506
9507         return 0
9508 }
9509 run_test 118i "Fix error before timeout in recoverable error  =========="
9510
9511 [ "$SLOW" = "no" ] && set_resend_count 4
9512
9513 test_118j() {
9514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9515         remote_ost_nodsh && skip "remote OST with nodsh"
9516
9517         reset_async
9518
9519         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
9520         set_nodes_failloc "$(osts_nodes)" 0x220
9521
9522         # return -EIO from OST
9523         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9524         RC=$?
9525         set_nodes_failloc "$(osts_nodes)" 0x0
9526         if [[ $RC -eq 0 ]]; then
9527                 error "Must return error due to dropped pages, rc=$RC"
9528         fi
9529
9530         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9531         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9532         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9533         if [[ $LOCKED -ne 0 ]]; then
9534                 error "Locked pages remain in cache, locked=$LOCKED"
9535         fi
9536
9537         # in recoverable error on OST we want resend and stay until it finished
9538         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9539                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9540         fi
9541
9542         rm -f $DIR/$tfile
9543         echo "No pages locked after fsync"
9544
9545         return 0
9546 }
9547 run_test 118j "Simulate unrecoverable OST side error =========="
9548
9549 test_118k()
9550 {
9551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9552         remote_ost_nodsh && skip "remote OSTs with nodsh"
9553
9554         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9555         set_nodes_failloc "$(osts_nodes)" 0x20e
9556         test_mkdir $DIR/$tdir
9557
9558         for ((i=0;i<10;i++)); do
9559                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
9560                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
9561                 SLEEPPID=$!
9562                 sleep 0.500s
9563                 kill $SLEEPPID
9564                 wait $SLEEPPID
9565         done
9566
9567         set_nodes_failloc "$(osts_nodes)" 0
9568         rm -rf $DIR/$tdir
9569 }
9570 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
9571
9572 test_118l() # LU-646
9573 {
9574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9575
9576         test_mkdir $DIR/$tdir
9577         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
9578         rm -rf $DIR/$tdir
9579 }
9580 run_test 118l "fsync dir"
9581
9582 test_118m() # LU-3066
9583 {
9584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9585
9586         test_mkdir $DIR/$tdir
9587         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
9588         rm -rf $DIR/$tdir
9589 }
9590 run_test 118m "fdatasync dir ========="
9591
9592 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
9593
9594 test_118n()
9595 {
9596         local begin
9597         local end
9598
9599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9600         remote_ost_nodsh && skip "remote OSTs with nodsh"
9601
9602         # Sleep to avoid a cached response.
9603         #define OBD_STATFS_CACHE_SECONDS 1
9604         sleep 2
9605
9606         # Inject a 10 second delay in the OST_STATFS handler.
9607         #define OBD_FAIL_OST_STATFS_DELAY 0x242
9608         set_nodes_failloc "$(osts_nodes)" 0x242
9609
9610         begin=$SECONDS
9611         stat --file-system $MOUNT > /dev/null
9612         end=$SECONDS
9613
9614         set_nodes_failloc "$(osts_nodes)" 0
9615
9616         if ((end - begin > 20)); then
9617             error "statfs took $((end - begin)) seconds, expected 10"
9618         fi
9619 }
9620 run_test 118n "statfs() sends OST_STATFS requests in parallel"
9621
9622 test_119a() # bug 11737
9623 {
9624         BSIZE=$((512 * 1024))
9625         directio write $DIR/$tfile 0 1 $BSIZE
9626         # We ask to read two blocks, which is more than a file size.
9627         # directio will indicate an error when requested and actual
9628         # sizes aren't equeal (a normal situation in this case) and
9629         # print actual read amount.
9630         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
9631         if [ "$NOB" != "$BSIZE" ]; then
9632                 error "read $NOB bytes instead of $BSIZE"
9633         fi
9634         rm -f $DIR/$tfile
9635 }
9636 run_test 119a "Short directIO read must return actual read amount"
9637
9638 test_119b() # bug 11737
9639 {
9640         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9641
9642         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
9643         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
9644         sync
9645         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
9646                 error "direct read failed"
9647         rm -f $DIR/$tfile
9648 }
9649 run_test 119b "Sparse directIO read must return actual read amount"
9650
9651 test_119c() # bug 13099
9652 {
9653         BSIZE=1048576
9654         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
9655         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
9656         rm -f $DIR/$tfile
9657 }
9658 run_test 119c "Testing for direct read hitting hole"
9659
9660 test_119d() # bug 15950
9661 {
9662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9663
9664         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
9665         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
9666         BSIZE=1048576
9667         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
9668         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
9669         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
9670         lctl set_param fail_loc=0x40d
9671         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
9672         pid_dio=$!
9673         sleep 1
9674         cat $DIR/$tfile > /dev/null &
9675         lctl set_param fail_loc=0
9676         pid_reads=$!
9677         wait $pid_dio
9678         log "the DIO writes have completed, now wait for the reads (should not block very long)"
9679         sleep 2
9680         [ -n "`ps h -p $pid_reads -o comm`" ] && \
9681         error "the read rpcs have not completed in 2s"
9682         rm -f $DIR/$tfile
9683         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
9684 }
9685 run_test 119d "The DIO path should try to send a new rpc once one is completed"
9686
9687 test_120a() {
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689         remote_mds_nodsh && skip "remote MDS with nodsh"
9690         test_mkdir -i0 -c1 $DIR/$tdir
9691         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9692                 skip_env "no early lock cancel on server"
9693
9694         lru_resize_disable mdc
9695         lru_resize_disable osc
9696         cancel_lru_locks mdc
9697         # asynchronous object destroy at MDT could cause bl ast to client
9698         cancel_lru_locks osc
9699
9700         stat $DIR/$tdir > /dev/null
9701         can1=$(do_facet mds1 \
9702                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9703                awk '/ldlm_cancel/ {print $2}')
9704         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9705                awk '/ldlm_bl_callback/ {print $2}')
9706         test_mkdir -i0 -c1 $DIR/$tdir/d1
9707         can2=$(do_facet mds1 \
9708                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9709                awk '/ldlm_cancel/ {print $2}')
9710         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9711                awk '/ldlm_bl_callback/ {print $2}')
9712         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9713         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9714         lru_resize_enable mdc
9715         lru_resize_enable osc
9716 }
9717 run_test 120a "Early Lock Cancel: mkdir test"
9718
9719 test_120b() {
9720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9721         remote_mds_nodsh && skip "remote MDS with nodsh"
9722         test_mkdir $DIR/$tdir
9723         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9724                 skip_env "no early lock cancel on server"
9725
9726         lru_resize_disable mdc
9727         lru_resize_disable osc
9728         cancel_lru_locks mdc
9729         stat $DIR/$tdir > /dev/null
9730         can1=$(do_facet $SINGLEMDS \
9731                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9732                awk '/ldlm_cancel/ {print $2}')
9733         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9734                awk '/ldlm_bl_callback/ {print $2}')
9735         touch $DIR/$tdir/f1
9736         can2=$(do_facet $SINGLEMDS \
9737                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9738                awk '/ldlm_cancel/ {print $2}')
9739         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9740                awk '/ldlm_bl_callback/ {print $2}')
9741         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9742         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9743         lru_resize_enable mdc
9744         lru_resize_enable osc
9745 }
9746 run_test 120b "Early Lock Cancel: create test"
9747
9748 test_120c() {
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         remote_mds_nodsh && skip "remote MDS with nodsh"
9751         test_mkdir -i0 -c1 $DIR/$tdir
9752         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9753                 skip "no early lock cancel on server"
9754
9755         lru_resize_disable mdc
9756         lru_resize_disable osc
9757         test_mkdir -i0 -c1 $DIR/$tdir/d1
9758         test_mkdir -i0 -c1 $DIR/$tdir/d2
9759         touch $DIR/$tdir/d1/f1
9760         cancel_lru_locks mdc
9761         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
9762         can1=$(do_facet mds1 \
9763                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9764                awk '/ldlm_cancel/ {print $2}')
9765         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9766                awk '/ldlm_bl_callback/ {print $2}')
9767         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9768         can2=$(do_facet mds1 \
9769                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9770                awk '/ldlm_cancel/ {print $2}')
9771         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9772                awk '/ldlm_bl_callback/ {print $2}')
9773         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9774         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9775         lru_resize_enable mdc
9776         lru_resize_enable osc
9777 }
9778 run_test 120c "Early Lock Cancel: link test"
9779
9780 test_120d() {
9781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9782         remote_mds_nodsh && skip "remote MDS with nodsh"
9783         test_mkdir -i0 -c1 $DIR/$tdir
9784         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9785                 skip_env "no early lock cancel on server"
9786
9787         lru_resize_disable mdc
9788         lru_resize_disable osc
9789         touch $DIR/$tdir
9790         cancel_lru_locks mdc
9791         stat $DIR/$tdir > /dev/null
9792         can1=$(do_facet mds1 \
9793                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9794                awk '/ldlm_cancel/ {print $2}')
9795         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9796                awk '/ldlm_bl_callback/ {print $2}')
9797         chmod a+x $DIR/$tdir
9798         can2=$(do_facet mds1 \
9799                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9800                awk '/ldlm_cancel/ {print $2}')
9801         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9802                awk '/ldlm_bl_callback/ {print $2}')
9803         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9804         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9805         lru_resize_enable mdc
9806         lru_resize_enable osc
9807 }
9808 run_test 120d "Early Lock Cancel: setattr test"
9809
9810 test_120e() {
9811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9812         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9813                 skip_env "no early lock cancel on server"
9814         remote_mds_nodsh && skip "remote MDS with nodsh"
9815
9816         local dlmtrace_set=false
9817
9818         test_mkdir -i0 -c1 $DIR/$tdir
9819         lru_resize_disable mdc
9820         lru_resize_disable osc
9821         ! $LCTL get_param debug | grep -q dlmtrace &&
9822                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
9823         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
9824         cancel_lru_locks mdc
9825         cancel_lru_locks osc
9826         dd if=$DIR/$tdir/f1 of=/dev/null
9827         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
9828         # XXX client can not do early lock cancel of OST lock
9829         # during unlink (LU-4206), so cancel osc lock now.
9830         sleep 2
9831         cancel_lru_locks osc
9832         can1=$(do_facet mds1 \
9833                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9834                awk '/ldlm_cancel/ {print $2}')
9835         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9836                awk '/ldlm_bl_callback/ {print $2}')
9837         unlink $DIR/$tdir/f1
9838         sleep 5
9839         can2=$(do_facet mds1 \
9840                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9841                awk '/ldlm_cancel/ {print $2}')
9842         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9843                awk '/ldlm_bl_callback/ {print $2}')
9844         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
9845                 $LCTL dk $TMP/cancel.debug.txt
9846         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
9847                 $LCTL dk $TMP/blocking.debug.txt
9848         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
9849         lru_resize_enable mdc
9850         lru_resize_enable osc
9851 }
9852 run_test 120e "Early Lock Cancel: unlink test"
9853
9854 test_120f() {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9857                 skip_env "no early lock cancel on server"
9858         remote_mds_nodsh && skip "remote MDS with nodsh"
9859
9860         test_mkdir -i0 -c1 $DIR/$tdir
9861         lru_resize_disable mdc
9862         lru_resize_disable osc
9863         test_mkdir -i0 -c1 $DIR/$tdir/d1
9864         test_mkdir -i0 -c1 $DIR/$tdir/d2
9865         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
9866         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
9867         cancel_lru_locks mdc
9868         cancel_lru_locks osc
9869         dd if=$DIR/$tdir/d1/f1 of=/dev/null
9870         dd if=$DIR/$tdir/d2/f2 of=/dev/null
9871         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
9872         # XXX client can not do early lock cancel of OST lock
9873         # during rename (LU-4206), so cancel osc lock now.
9874         sleep 2
9875         cancel_lru_locks osc
9876         can1=$(do_facet mds1 \
9877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9878                awk '/ldlm_cancel/ {print $2}')
9879         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9880                awk '/ldlm_bl_callback/ {print $2}')
9881         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
9882         sleep 5
9883         can2=$(do_facet mds1 \
9884                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9885                awk '/ldlm_cancel/ {print $2}')
9886         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9887                awk '/ldlm_bl_callback/ {print $2}')
9888         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
9889         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
9890         lru_resize_enable mdc
9891         lru_resize_enable osc
9892 }
9893 run_test 120f "Early Lock Cancel: rename test"
9894
9895 test_120g() {
9896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9897         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
9898                 skip_env "no early lock cancel on server"
9899         remote_mds_nodsh && skip "remote MDS with nodsh"
9900
9901         lru_resize_disable mdc
9902         lru_resize_disable osc
9903         count=10000
9904         echo create $count files
9905         test_mkdir $DIR/$tdir
9906         cancel_lru_locks mdc
9907         cancel_lru_locks osc
9908         t0=$(date +%s)
9909
9910         can0=$(do_facet $SINGLEMDS \
9911                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9912                awk '/ldlm_cancel/ {print $2}')
9913         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9914                awk '/ldlm_bl_callback/ {print $2}')
9915         createmany -o $DIR/$tdir/f $count
9916         sync
9917         can1=$(do_facet $SINGLEMDS \
9918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9919                awk '/ldlm_cancel/ {print $2}')
9920         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9921                awk '/ldlm_bl_callback/ {print $2}')
9922         t1=$(date +%s)
9923         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
9924         echo rm $count files
9925         rm -r $DIR/$tdir
9926         sync
9927         can2=$(do_facet $SINGLEMDS \
9928                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
9929                awk '/ldlm_cancel/ {print $2}')
9930         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
9931                awk '/ldlm_bl_callback/ {print $2}')
9932         t2=$(date +%s)
9933         echo total: $count removes in $((t2-t1))
9934         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
9935         sleep 2
9936         # wait for commitment of removal
9937         lru_resize_enable mdc
9938         lru_resize_enable osc
9939 }
9940 run_test 120g "Early Lock Cancel: performance test"
9941
9942 test_121() { #bug #10589
9943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9944
9945         rm -rf $DIR/$tfile
9946         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
9947 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
9948         lctl set_param fail_loc=0x310
9949         cancel_lru_locks osc > /dev/null
9950         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
9951         lctl set_param fail_loc=0
9952         [[ $reads -eq $writes ]] ||
9953                 error "read $reads blocks, must be $writes blocks"
9954 }
9955 run_test 121 "read cancel race ========="
9956
9957 test_123a() { # was test 123, statahead(bug 11401)
9958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9959
9960         SLOWOK=0
9961         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
9962                 log "testing UP system. Performance may be lower than expected."
9963                 SLOWOK=1
9964         fi
9965
9966         rm -rf $DIR/$tdir
9967         test_mkdir $DIR/$tdir
9968         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
9969         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
9970         MULT=10
9971         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
9972                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
9973
9974                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
9975                 lctl set_param -n llite.*.statahead_max 0
9976                 lctl get_param llite.*.statahead_max
9977                 cancel_lru_locks mdc
9978                 cancel_lru_locks osc
9979                 stime=`date +%s`
9980                 time ls -l $DIR/$tdir | wc -l
9981                 etime=`date +%s`
9982                 delta=$((etime - stime))
9983                 log "ls $i files without statahead: $delta sec"
9984                 lctl set_param llite.*.statahead_max=$max
9985
9986                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9987                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
9988                 cancel_lru_locks mdc
9989                 cancel_lru_locks osc
9990                 stime=`date +%s`
9991                 time ls -l $DIR/$tdir | wc -l
9992                 etime=`date +%s`
9993                 delta_sa=$((etime - stime))
9994                 log "ls $i files with statahead: $delta_sa sec"
9995                 lctl get_param -n llite.*.statahead_stats
9996                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
9997
9998                 [[ $swrong -lt $ewrong ]] &&
9999                         log "statahead was stopped, maybe too many locks held!"
10000                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10001
10002                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10003                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10004                     lctl set_param -n llite.*.statahead_max 0
10005                     lctl get_param llite.*.statahead_max
10006                     cancel_lru_locks mdc
10007                     cancel_lru_locks osc
10008                     stime=`date +%s`
10009                     time ls -l $DIR/$tdir | wc -l
10010                     etime=`date +%s`
10011                     delta=$((etime - stime))
10012                     log "ls $i files again without statahead: $delta sec"
10013                     lctl set_param llite.*.statahead_max=$max
10014                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10015                         if [  $SLOWOK -eq 0 ]; then
10016                                 error "ls $i files is slower with statahead!"
10017                         else
10018                                 log "ls $i files is slower with statahead!"
10019                         fi
10020                         break
10021                     fi
10022                 fi
10023
10024                 [ $delta -gt 20 ] && break
10025                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10026                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10027         done
10028         log "ls done"
10029
10030         stime=`date +%s`
10031         rm -r $DIR/$tdir
10032         sync
10033         etime=`date +%s`
10034         delta=$((etime - stime))
10035         log "rm -r $DIR/$tdir/: $delta seconds"
10036         log "rm done"
10037         lctl get_param -n llite.*.statahead_stats
10038 }
10039 run_test 123a "verify statahead work"
10040
10041 test_123b () { # statahead(bug 15027)
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         test_mkdir $DIR/$tdir
10045         createmany -o $DIR/$tdir/$tfile-%d 1000
10046
10047         cancel_lru_locks mdc
10048         cancel_lru_locks osc
10049
10050 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10051         lctl set_param fail_loc=0x80000803
10052         ls -lR $DIR/$tdir > /dev/null
10053         log "ls done"
10054         lctl set_param fail_loc=0x0
10055         lctl get_param -n llite.*.statahead_stats
10056         rm -r $DIR/$tdir
10057         sync
10058
10059 }
10060 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10061
10062 test_124a() {
10063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10064         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10065                 skip_env "no lru resize on server"
10066
10067         local NR=2000
10068
10069         test_mkdir $DIR/$tdir
10070
10071         log "create $NR files at $DIR/$tdir"
10072         createmany -o $DIR/$tdir/f $NR ||
10073                 error "failed to create $NR files in $DIR/$tdir"
10074
10075         cancel_lru_locks mdc
10076         ls -l $DIR/$tdir > /dev/null
10077
10078         local NSDIR=""
10079         local LRU_SIZE=0
10080         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10081                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10082                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10083                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10084                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10085                         log "NSDIR=$NSDIR"
10086                         log "NS=$(basename $NSDIR)"
10087                         break
10088                 fi
10089         done
10090
10091         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10092                 skip "Not enough cached locks created!"
10093         fi
10094         log "LRU=$LRU_SIZE"
10095
10096         local SLEEP=30
10097
10098         # We know that lru resize allows one client to hold $LIMIT locks
10099         # for 10h. After that locks begin to be killed by client.
10100         local MAX_HRS=10
10101         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10102         log "LIMIT=$LIMIT"
10103         if [ $LIMIT -lt $LRU_SIZE ]; then
10104                 skip "Limit is too small $LIMIT"
10105         fi
10106
10107         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10108         # killing locks. Some time was spent for creating locks. This means
10109         # that up to the moment of sleep finish we must have killed some of
10110         # them (10-100 locks). This depends on how fast ther were created.
10111         # Many of them were touched in almost the same moment and thus will
10112         # be killed in groups.
10113         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10114
10115         # Use $LRU_SIZE_B here to take into account real number of locks
10116         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10117         local LRU_SIZE_B=$LRU_SIZE
10118         log "LVF=$LVF"
10119         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10120         log "OLD_LVF=$OLD_LVF"
10121         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10122
10123         # Let's make sure that we really have some margin. Client checks
10124         # cached locks every 10 sec.
10125         SLEEP=$((SLEEP+20))
10126         log "Sleep ${SLEEP} sec"
10127         local SEC=0
10128         while ((SEC<$SLEEP)); do
10129                 echo -n "..."
10130                 sleep 5
10131                 SEC=$((SEC+5))
10132                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10133                 echo -n "$LRU_SIZE"
10134         done
10135         echo ""
10136         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10137         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10138
10139         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10140                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10141                 unlinkmany $DIR/$tdir/f $NR
10142                 return
10143         }
10144
10145         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10146         log "unlink $NR files at $DIR/$tdir"
10147         unlinkmany $DIR/$tdir/f $NR
10148 }
10149 run_test 124a "lru resize ======================================="
10150
10151 get_max_pool_limit()
10152 {
10153         local limit=$($LCTL get_param \
10154                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10155         local max=0
10156         for l in $limit; do
10157                 if [[ $l -gt $max ]]; then
10158                         max=$l
10159                 fi
10160         done
10161         echo $max
10162 }
10163
10164 test_124b() {
10165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10166         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10167                 skip_env "no lru resize on server"
10168
10169         LIMIT=$(get_max_pool_limit)
10170
10171         NR=$(($(default_lru_size)*20))
10172         if [[ $NR -gt $LIMIT ]]; then
10173                 log "Limit lock number by $LIMIT locks"
10174                 NR=$LIMIT
10175         fi
10176
10177         IFree=$(mdsrate_inodes_available)
10178         if [ $IFree -lt $NR ]; then
10179                 log "Limit lock number by $IFree inodes"
10180                 NR=$IFree
10181         fi
10182
10183         lru_resize_disable mdc
10184         test_mkdir -p $DIR/$tdir/disable_lru_resize
10185
10186         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10187         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10188         cancel_lru_locks mdc
10189         stime=`date +%s`
10190         PID=""
10191         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10192         PID="$PID $!"
10193         sleep 2
10194         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10195         PID="$PID $!"
10196         sleep 2
10197         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10198         PID="$PID $!"
10199         wait $PID
10200         etime=`date +%s`
10201         nolruresize_delta=$((etime-stime))
10202         log "ls -la time: $nolruresize_delta seconds"
10203         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10204         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10205
10206         lru_resize_enable mdc
10207         test_mkdir -p $DIR/$tdir/enable_lru_resize
10208
10209         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10210         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10211         cancel_lru_locks mdc
10212         stime=`date +%s`
10213         PID=""
10214         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10215         PID="$PID $!"
10216         sleep 2
10217         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10218         PID="$PID $!"
10219         sleep 2
10220         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10221         PID="$PID $!"
10222         wait $PID
10223         etime=`date +%s`
10224         lruresize_delta=$((etime-stime))
10225         log "ls -la time: $lruresize_delta seconds"
10226         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10227
10228         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10229                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10230         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10231                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10232         else
10233                 log "lru resize performs the same with no lru resize"
10234         fi
10235         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10236 }
10237 run_test 124b "lru resize (performance test) ======================="
10238
10239 test_124c() {
10240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10241         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10242                 skip_env "no lru resize on server"
10243
10244         # cache ununsed locks on client
10245         local nr=100
10246         cancel_lru_locks mdc
10247         test_mkdir $DIR/$tdir
10248         createmany -o $DIR/$tdir/f $nr ||
10249                 error "failed to create $nr files in $DIR/$tdir"
10250         ls -l $DIR/$tdir > /dev/null
10251
10252         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10253         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10254         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10255         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10256         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10257
10258         # set lru_max_age to 1 sec
10259         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10260         echo "sleep $((recalc_p * 2)) seconds..."
10261         sleep $((recalc_p * 2))
10262
10263         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10264         # restore lru_max_age
10265         $LCTL set_param -n $nsdir.lru_max_age $max_age
10266         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10267         unlinkmany $DIR/$tdir/f $nr
10268 }
10269 run_test 124c "LRUR cancel very aged locks"
10270
10271 test_125() { # 13358
10272         $LCTL get_param -n llite.*.client_type | grep -q local ||
10273                 skip "must run as local client"
10274         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10275                 skip_env "must have acl enabled"
10276         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10277
10278         test_mkdir $DIR/$tdir
10279         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10280         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10281         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10282 }
10283 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10284
10285 test_126() { # bug 12829/13455
10286         $GSS && skip_env "must run as gss disabled"
10287         $LCTL get_param -n llite.*.client_type | grep -q local ||
10288                 skip "must run as local client"
10289         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10290
10291         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10292         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10293         rm -f $DIR/$tfile
10294         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10295 }
10296 run_test 126 "check that the fsgid provided by the client is taken into account"
10297
10298 test_127a() { # bug 15521
10299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10300
10301         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10302         $LCTL set_param osc.*.stats=0
10303         FSIZE=$((2048 * 1024))
10304         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10305         cancel_lru_locks osc
10306         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10307
10308         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10309         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10310                 echo "got $COUNT $NAME"
10311                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10312                 eval $NAME=$COUNT || error "Wrong proc format"
10313
10314                 case $NAME in
10315                         read_bytes|write_bytes)
10316                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10317                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10318                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10319                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10320                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10321                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10322                                 error "sumsquare is too small: $SUMSQ"
10323                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10324                                 error "sumsquare is too big: $SUMSQ"
10325                         ;;
10326                         *) ;;
10327                 esac
10328         done < $DIR/${tfile}.tmp
10329
10330         #check that we actually got some stats
10331         [ "$read_bytes" ] || error "Missing read_bytes stats"
10332         [ "$write_bytes" ] || error "Missing write_bytes stats"
10333         [ "$read_bytes" != 0 ] || error "no read done"
10334         [ "$write_bytes" != 0 ] || error "no write done"
10335 }
10336 run_test 127a "verify the client stats are sane"
10337
10338 test_127b() { # bug LU-333
10339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10340         local name count samp unit min max sum sumsq
10341
10342         $LCTL set_param llite.*.stats=0
10343
10344         # perform 2 reads and writes so MAX is different from SUM.
10345         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10346         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10347         cancel_lru_locks osc
10348         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10349         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10350
10351         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10352         while read name count samp unit min max sum sumsq; do
10353                 echo "got $count $name"
10354                 eval $name=$count || error "Wrong proc format"
10355
10356                 case $name in
10357                 read_bytes)
10358                         [ $count -ne 2 ] && error "count is not 2: $count"
10359                         [ $min -ne $PAGE_SIZE ] &&
10360                                 error "min is not $PAGE_SIZE: $min"
10361                         [ $max -ne $PAGE_SIZE ] &&
10362                                 error "max is incorrect: $max"
10363                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10364                                 error "sum is wrong: $sum"
10365                         ;;
10366                 write_bytes)
10367                         [ $count -ne 2 ] && error "count is not 2: $count"
10368                         [ $min -ne $PAGE_SIZE ] &&
10369                                 error "min is not $PAGE_SIZE: $min"
10370                         [ $max -ne $PAGE_SIZE ] &&
10371                                 error "max is incorrect: $max"
10372                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10373                                 error "sum is wrong: $sum"
10374                         ;;
10375                 *) ;;
10376                 esac
10377         done < $TMP/$tfile.tmp
10378
10379         #check that we actually got some stats
10380         [ "$read_bytes" ] || error "Missing read_bytes stats"
10381         [ "$write_bytes" ] || error "Missing write_bytes stats"
10382         [ "$read_bytes" != 0 ] || error "no read done"
10383         [ "$write_bytes" != 0 ] || error "no write done"
10384
10385         rm -f $TMP/${tfile}.tmp
10386 }
10387 run_test 127b "verify the llite client stats are sane"
10388
10389 test_128() { # bug 15212
10390         touch $DIR/$tfile
10391         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10392                 find $DIR/$tfile
10393                 find $DIR/$tfile
10394         EOF
10395
10396         result=$(grep error $TMP/$tfile.log)
10397         rm -f $DIR/$tfile $TMP/$tfile.log
10398         [ -z "$result" ] ||
10399                 error "consecutive find's under interactive lfs failed"
10400 }
10401 run_test 128 "interactive lfs for 2 consecutive find's"
10402
10403 set_dir_limits () {
10404         local mntdev
10405         local canondev
10406         local node
10407
10408         local ldproc=/proc/fs/ldiskfs
10409         local facets=$(get_facets MDS)
10410
10411         for facet in ${facets//,/ }; do
10412                 canondev=$(ldiskfs_canon \
10413                            *.$(convert_facet2label $facet).mntdev $facet)
10414                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10415                         ldproc=/sys/fs/ldiskfs
10416                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10417                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10418         done
10419 }
10420
10421 check_mds_dmesg() {
10422         local facets=$(get_facets MDS)
10423         for facet in ${facets//,/ }; do
10424                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10425         done
10426         return 1
10427 }
10428
10429 test_129() {
10430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10431         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10432                 skip "Need MDS version with at least 2.5.56"
10433         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10434                 skip_env "ldiskfs only test"
10435         fi
10436         remote_mds_nodsh && skip "remote MDS with nodsh"
10437
10438         local ENOSPC=28
10439         local EFBIG=27
10440         local has_warning=false
10441
10442         rm -rf $DIR/$tdir
10443         mkdir -p $DIR/$tdir
10444
10445         # block size of mds1
10446         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10447         set_dir_limits $maxsize $maxsize
10448         local dirsize=$(stat -c%s "$DIR/$tdir")
10449         local nfiles=0
10450         while [[ $dirsize -le $maxsize ]]; do
10451                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10452                 rc=$?
10453                 if ! $has_warning; then
10454                         check_mds_dmesg '"is approaching"' && has_warning=true
10455                 fi
10456                 # check two errors:
10457                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
10458                 # EFBIG for previous versions included in ldiskfs series
10459                 if [ $rc -eq $EFBIG -o $rc -eq $ENOSPC ]; then
10460                         set_dir_limits 0 0
10461                         echo "return code $rc received as expected"
10462
10463                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
10464                                 error_exit "create failed w/o dir size limit"
10465
10466                         check_mds_dmesg '"has reached"' ||
10467                                 error_exit "reached message should be output"
10468
10469                         [ $has_warning = "false" ] &&
10470                                 error_exit "warning message should be output"
10471
10472                         dirsize=$(stat -c%s "$DIR/$tdir")
10473
10474                         [[ $dirsize -ge $maxsize ]] && return 0
10475                         error_exit "current dir size $dirsize, " \
10476                                    "previous limit $maxsize"
10477                 elif [ $rc -ne 0 ]; then
10478                         set_dir_limits 0 0
10479                         error_exit "return $rc received instead of expected " \
10480                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
10481                 fi
10482                 nfiles=$((nfiles + 1))
10483                 dirsize=$(stat -c%s "$DIR/$tdir")
10484         done
10485
10486         set_dir_limits 0 0
10487         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
10488 }
10489 run_test 129 "test directory size limit ========================"
10490
10491 OLDIFS="$IFS"
10492 cleanup_130() {
10493         trap 0
10494         IFS="$OLDIFS"
10495 }
10496
10497 test_130a() {
10498         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10499         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10500
10501         trap cleanup_130 EXIT RETURN
10502
10503         local fm_file=$DIR/$tfile
10504         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
10505         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
10506                 error "dd failed for $fm_file"
10507
10508         # LU-1795: test filefrag/FIEMAP once, even if unsupported
10509         filefrag -ves $fm_file
10510         RC=$?
10511         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10512                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10513         [ $RC != 0 ] && error "filefrag $fm_file failed"
10514
10515         filefrag_op=$(filefrag -ve -k $fm_file |
10516                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10517         lun=$($LFS getstripe -i $fm_file)
10518
10519         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
10520         IFS=$'\n'
10521         tot_len=0
10522         for line in $filefrag_op
10523         do
10524                 frag_lun=`echo $line | cut -d: -f5`
10525                 ext_len=`echo $line | cut -d: -f4`
10526                 if (( $frag_lun != $lun )); then
10527                         cleanup_130
10528                         error "FIEMAP on 1-stripe file($fm_file) failed"
10529                         return
10530                 fi
10531                 (( tot_len += ext_len ))
10532         done
10533
10534         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
10535                 cleanup_130
10536                 error "FIEMAP on 1-stripe file($fm_file) failed;"
10537                 return
10538         fi
10539
10540         cleanup_130
10541
10542         echo "FIEMAP on single striped file succeeded"
10543 }
10544 run_test 130a "FIEMAP (1-stripe file)"
10545
10546 test_130b() {
10547         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
10548
10549         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10550         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10551
10552         trap cleanup_130 EXIT RETURN
10553
10554         local fm_file=$DIR/$tfile
10555         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10556                         error "setstripe on $fm_file"
10557         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10558                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10559
10560         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
10561                 error "dd failed on $fm_file"
10562
10563         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10564         filefrag_op=$(filefrag -ve -k $fm_file |
10565                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10566
10567         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10568                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10569
10570         IFS=$'\n'
10571         tot_len=0
10572         num_luns=1
10573         for line in $filefrag_op
10574         do
10575                 frag_lun=$(echo $line | cut -d: -f5 |
10576                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10577                 ext_len=$(echo $line | cut -d: -f4)
10578                 if (( $frag_lun != $last_lun )); then
10579                         if (( tot_len != 1024 )); then
10580                                 cleanup_130
10581                                 error "FIEMAP on $fm_file failed; returned " \
10582                                 "len $tot_len for OST $last_lun instead of 1024"
10583                                 return
10584                         else
10585                                 (( num_luns += 1 ))
10586                                 tot_len=0
10587                         fi
10588                 fi
10589                 (( tot_len += ext_len ))
10590                 last_lun=$frag_lun
10591         done
10592         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
10593                 cleanup_130
10594                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10595                         "luns or wrong len for OST $last_lun"
10596                 return
10597         fi
10598
10599         cleanup_130
10600
10601         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
10602 }
10603 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
10604
10605 test_130c() {
10606         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10607
10608         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10609         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10610
10611         trap cleanup_130 EXIT RETURN
10612
10613         local fm_file=$DIR/$tfile
10614         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
10615         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10616                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10617
10618         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
10619                         error "dd failed on $fm_file"
10620
10621         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10622         filefrag_op=$(filefrag -ve -k $fm_file |
10623                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10624
10625         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10626                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10627
10628         IFS=$'\n'
10629         tot_len=0
10630         num_luns=1
10631         for line in $filefrag_op
10632         do
10633                 frag_lun=$(echo $line | cut -d: -f5 |
10634                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10635                 ext_len=$(echo $line | cut -d: -f4)
10636                 if (( $frag_lun != $last_lun )); then
10637                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
10638                         if (( logical != 512 )); then
10639                                 cleanup_130
10640                                 error "FIEMAP on $fm_file failed; returned " \
10641                                 "logical start for lun $logical instead of 512"
10642                                 return
10643                         fi
10644                         if (( tot_len != 512 )); then
10645                                 cleanup_130
10646                                 error "FIEMAP on $fm_file failed; returned " \
10647                                 "len $tot_len for OST $last_lun instead of 1024"
10648                                 return
10649                         else
10650                                 (( num_luns += 1 ))
10651                                 tot_len=0
10652                         fi
10653                 fi
10654                 (( tot_len += ext_len ))
10655                 last_lun=$frag_lun
10656         done
10657         if (( num_luns != 2 || tot_len != 512 )); then
10658                 cleanup_130
10659                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10660                         "luns or wrong len for OST $last_lun"
10661                 return
10662         fi
10663
10664         cleanup_130
10665
10666         echo "FIEMAP on 2-stripe file with hole succeeded"
10667 }
10668 run_test 130c "FIEMAP (2-stripe file with hole)"
10669
10670 test_130d() {
10671         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
10672
10673         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10674         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10675
10676         trap cleanup_130 EXIT RETURN
10677
10678         local fm_file=$DIR/$tfile
10679         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
10680                         error "setstripe on $fm_file"
10681         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10682                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10683
10684         local actual_stripe_count=$($LFS getstripe -c $fm_file)
10685         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
10686                 error "dd failed on $fm_file"
10687
10688         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10689         filefrag_op=$(filefrag -ve -k $fm_file |
10690                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10691
10692         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10693                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10694
10695         IFS=$'\n'
10696         tot_len=0
10697         num_luns=1
10698         for line in $filefrag_op
10699         do
10700                 frag_lun=$(echo $line | cut -d: -f5 |
10701                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10702                 ext_len=$(echo $line | cut -d: -f4)
10703                 if (( $frag_lun != $last_lun )); then
10704                         if (( tot_len != 1024 )); then
10705                                 cleanup_130
10706                                 error "FIEMAP on $fm_file failed; returned " \
10707                                 "len $tot_len for OST $last_lun instead of 1024"
10708                                 return
10709                         else
10710                                 (( num_luns += 1 ))
10711                                 tot_len=0
10712                         fi
10713                 fi
10714                 (( tot_len += ext_len ))
10715                 last_lun=$frag_lun
10716         done
10717         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
10718                 cleanup_130
10719                 error "FIEMAP on $fm_file failed; returned wrong number of " \
10720                         "luns or wrong len for OST $last_lun"
10721                 return
10722         fi
10723
10724         cleanup_130
10725
10726         echo "FIEMAP on N-stripe file succeeded"
10727 }
10728 run_test 130d "FIEMAP (N-stripe file)"
10729
10730 test_130e() {
10731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10732
10733         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10734         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
10735
10736         trap cleanup_130 EXIT RETURN
10737
10738         local fm_file=$DIR/$tfile
10739         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
10740         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
10741                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
10742
10743         NUM_BLKS=512
10744         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
10745         for ((i = 0; i < $NUM_BLKS; i++))
10746         do
10747                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
10748         done
10749
10750         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10751         filefrag_op=$(filefrag -ve -k $fm_file |
10752                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
10753
10754         last_lun=$(echo $filefrag_op | cut -d: -f5 |
10755                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10756
10757         IFS=$'\n'
10758         tot_len=0
10759         num_luns=1
10760         for line in $filefrag_op
10761         do
10762                 frag_lun=$(echo $line | cut -d: -f5 |
10763                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
10764                 ext_len=$(echo $line | cut -d: -f4)
10765                 if (( $frag_lun != $last_lun )); then
10766                         if (( tot_len != $EXPECTED_LEN )); then
10767                                 cleanup_130
10768                                 error "FIEMAP on $fm_file failed; returned " \
10769                                 "len $tot_len for OST $last_lun instead " \
10770                                 "of $EXPECTED_LEN"
10771                                 return
10772                         else
10773                                 (( num_luns += 1 ))
10774                                 tot_len=0
10775                         fi
10776                 fi
10777                 (( tot_len += ext_len ))
10778                 last_lun=$frag_lun
10779         done
10780         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
10781                 cleanup_130
10782                 error "FIEMAP on $fm_file failed; returned wrong number " \
10783                         "of luns or wrong len for OST $last_lun"
10784                 return
10785         fi
10786
10787         cleanup_130
10788
10789         echo "FIEMAP with continuation calls succeeded"
10790 }
10791 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
10792
10793 test_130f() {
10794         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
10795         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
10796
10797         local fm_file=$DIR/$tfile
10798         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
10799                 error "multiop create with lov_delay_create on $fm_file"
10800
10801         filefrag -ves $fm_file || error "filefrag $fm_file failed"
10802         filefrag_extents=$(filefrag -vek $fm_file |
10803                            awk '/extents? found/ { print $2 }')
10804         if [[ "$filefrag_extents" != "0" ]]; then
10805                 error "FIEMAP on $fm_file failed; " \
10806                       "returned $filefrag_extents expected 0"
10807         fi
10808
10809         rm -f $fm_file
10810 }
10811 run_test 130f "FIEMAP (unstriped file)"
10812
10813 # Test for writev/readv
10814 test_131a() {
10815         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
10816                 error "writev test failed"
10817         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
10818                 error "readv failed"
10819         rm -f $DIR/$tfile
10820 }
10821 run_test 131a "test iov's crossing stripe boundary for writev/readv"
10822
10823 test_131b() {
10824         local fsize=$((524288 + 1048576 + 1572864))
10825         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
10826                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10827                         error "append writev test failed"
10828
10829         ((fsize += 1572864 + 1048576))
10830         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
10831                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
10832                         error "append writev test failed"
10833         rm -f $DIR/$tfile
10834 }
10835 run_test 131b "test append writev"
10836
10837 test_131c() {
10838         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
10839         error "NOT PASS"
10840 }
10841 run_test 131c "test read/write on file w/o objects"
10842
10843 test_131d() {
10844         rwv -f $DIR/$tfile -w -n 1 1572864
10845         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
10846         if [ "$NOB" != 1572864 ]; then
10847                 error "Short read filed: read $NOB bytes instead of 1572864"
10848         fi
10849         rm -f $DIR/$tfile
10850 }
10851 run_test 131d "test short read"
10852
10853 test_131e() {
10854         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
10855         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
10856         error "read hitting hole failed"
10857         rm -f $DIR/$tfile
10858 }
10859 run_test 131e "test read hitting hole"
10860
10861 check_stats() {
10862         local facet=$1
10863         local op=$2
10864         local want=${3:-0}
10865         local res
10866
10867         case $facet in
10868         mds*) res=$(do_facet $facet \
10869                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
10870                  ;;
10871         ost*) res=$(do_facet $facet \
10872                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
10873                  ;;
10874         *) error "Wrong facet '$facet'" ;;
10875         esac
10876         [ "$res" ] || error "The counter for $op on $facet was not incremented"
10877         # if the argument $3 is zero, it means any stat increment is ok.
10878         if [[ $want -gt 0 ]]; then
10879                 local count=$(echo $res | awk '{ print $2 }')
10880                 [[ $count -ne $want ]] &&
10881                         error "The $op counter on $facet is $count, not $want"
10882         fi
10883 }
10884
10885 test_133a() {
10886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10887         remote_ost_nodsh && skip "remote OST with nodsh"
10888         remote_mds_nodsh && skip "remote MDS with nodsh"
10889         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
10890                 skip_env "MDS doesn't support rename stats"
10891
10892         local testdir=$DIR/${tdir}/stats_testdir
10893
10894         mkdir -p $DIR/${tdir}
10895
10896         # clear stats.
10897         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10898         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10899
10900         # verify mdt stats first.
10901         mkdir ${testdir} || error "mkdir failed"
10902         check_stats $SINGLEMDS "mkdir" 1
10903         touch ${testdir}/${tfile} || error "touch failed"
10904         check_stats $SINGLEMDS "open" 1
10905         check_stats $SINGLEMDS "close" 1
10906         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
10907                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
10908                 check_stats $SINGLEMDS "mknod" 2
10909         }
10910         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
10911         check_stats $SINGLEMDS "unlink" 1
10912         rm -f ${testdir}/${tfile} || error "file remove failed"
10913         check_stats $SINGLEMDS "unlink" 2
10914
10915         # remove working dir and check mdt stats again.
10916         rmdir ${testdir} || error "rmdir failed"
10917         check_stats $SINGLEMDS "rmdir" 1
10918
10919         local testdir1=$DIR/${tdir}/stats_testdir1
10920         mkdir -p ${testdir}
10921         mkdir -p ${testdir1}
10922         touch ${testdir1}/test1
10923         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
10924         check_stats $SINGLEMDS "crossdir_rename" 1
10925
10926         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
10927         check_stats $SINGLEMDS "samedir_rename" 1
10928
10929         rm -rf $DIR/${tdir}
10930 }
10931 run_test 133a "Verifying MDT stats ========================================"
10932
10933 test_133b() {
10934         local res
10935
10936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10937         remote_ost_nodsh && skip "remote OST with nodsh"
10938         remote_mds_nodsh && skip "remote MDS with nodsh"
10939
10940         local testdir=$DIR/${tdir}/stats_testdir
10941
10942         mkdir -p ${testdir} || error "mkdir failed"
10943         touch ${testdir}/${tfile} || error "touch failed"
10944         cancel_lru_locks mdc
10945
10946         # clear stats.
10947         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10948         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
10949
10950         # extra mdt stats verification.
10951         chmod 444 ${testdir}/${tfile} || error "chmod failed"
10952         check_stats $SINGLEMDS "setattr" 1
10953         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10954         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
10955         then            # LU-1740
10956                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
10957                 check_stats $SINGLEMDS "getattr" 1
10958         fi
10959         rm -rf $DIR/${tdir}
10960
10961         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
10962         # so the check below is not reliable
10963         [ $MDSCOUNT -eq 1 ] || return 0
10964
10965         # Sleep to avoid a cached response.
10966         #define OBD_STATFS_CACHE_SECONDS 1
10967         sleep 2
10968         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10969         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
10970         $LFS df || error "lfs failed"
10971         check_stats $SINGLEMDS "statfs" 1
10972
10973         # check aggregated statfs (LU-10018)
10974         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
10975                 return 0
10976         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
10977                 return 0
10978         sleep 2
10979         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
10980         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
10981         df $DIR
10982         check_stats $SINGLEMDS "statfs" 1
10983
10984         # We want to check that the client didn't send OST_STATFS to
10985         # ost1 but the MDT also uses OST_STATFS for precreate. So some
10986         # extra care is needed here.
10987         if remote_mds; then
10988                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
10989                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
10990
10991                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
10992                 [ "$res" ] && error "OST got STATFS"
10993         fi
10994
10995         return 0
10996 }
10997 run_test 133b "Verifying extra MDT stats =================================="
10998
10999 test_133c() {
11000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11001         remote_ost_nodsh && skip "remote OST with nodsh"
11002         remote_mds_nodsh && skip "remote MDS with nodsh"
11003
11004         local testdir=$DIR/$tdir/stats_testdir
11005
11006         test_mkdir -p $testdir
11007
11008         # verify obdfilter stats.
11009         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11010         sync
11011         cancel_lru_locks osc
11012         wait_delete_completed
11013
11014         # clear stats.
11015         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11016         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11017
11018         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11019                 error "dd failed"
11020         sync
11021         cancel_lru_locks osc
11022         check_stats ost1 "write" 1
11023
11024         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11025         check_stats ost1 "read" 1
11026
11027         > $testdir/$tfile || error "truncate failed"
11028         check_stats ost1 "punch" 1
11029
11030         rm -f $testdir/$tfile || error "file remove failed"
11031         wait_delete_completed
11032         check_stats ost1 "destroy" 1
11033
11034         rm -rf $DIR/$tdir
11035 }
11036 run_test 133c "Verifying OST stats ========================================"
11037
11038 order_2() {
11039         local value=$1
11040         local orig=$value
11041         local order=1
11042
11043         while [ $value -ge 2 ]; do
11044                 order=$((order*2))
11045                 value=$((value/2))
11046         done
11047
11048         if [ $orig -gt $order ]; then
11049                 order=$((order*2))
11050         fi
11051         echo $order
11052 }
11053
11054 size_in_KMGT() {
11055     local value=$1
11056     local size=('K' 'M' 'G' 'T');
11057     local i=0
11058     local size_string=$value
11059
11060     while [ $value -ge 1024 ]; do
11061         if [ $i -gt 3 ]; then
11062             #T is the biggest unit we get here, if that is bigger,
11063             #just return XXXT
11064             size_string=${value}T
11065             break
11066         fi
11067         value=$((value >> 10))
11068         if [ $value -lt 1024 ]; then
11069             size_string=${value}${size[$i]}
11070             break
11071         fi
11072         i=$((i + 1))
11073     done
11074
11075     echo $size_string
11076 }
11077
11078 get_rename_size() {
11079         local size=$1
11080         local context=${2:-.}
11081         local sample=$(do_facet $SINGLEMDS $LCTL \
11082                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11083                 grep -A1 $context |
11084                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11085         echo $sample
11086 }
11087
11088 test_133d() {
11089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11090         remote_ost_nodsh && skip "remote OST with nodsh"
11091         remote_mds_nodsh && skip "remote MDS with nodsh"
11092         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11093                 skip_env "MDS doesn't support rename stats"
11094
11095         local testdir1=$DIR/${tdir}/stats_testdir1
11096         local testdir2=$DIR/${tdir}/stats_testdir2
11097         mkdir -p $DIR/${tdir}
11098
11099         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11100
11101         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11102         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11103
11104         createmany -o $testdir1/test 512 || error "createmany failed"
11105
11106         # check samedir rename size
11107         mv ${testdir1}/test0 ${testdir1}/test_0
11108
11109         local testdir1_size=$(ls -l $DIR/${tdir} |
11110                 awk '/stats_testdir1/ {print $5}')
11111         local testdir2_size=$(ls -l $DIR/${tdir} |
11112                 awk '/stats_testdir2/ {print $5}')
11113
11114         testdir1_size=$(order_2 $testdir1_size)
11115         testdir2_size=$(order_2 $testdir2_size)
11116
11117         testdir1_size=$(size_in_KMGT $testdir1_size)
11118         testdir2_size=$(size_in_KMGT $testdir2_size)
11119
11120         echo "source rename dir size: ${testdir1_size}"
11121         echo "target rename dir size: ${testdir2_size}"
11122
11123         local cmd="do_facet $SINGLEMDS $LCTL "
11124         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11125
11126         eval $cmd || error "$cmd failed"
11127         local samedir=$($cmd | grep 'same_dir')
11128         local same_sample=$(get_rename_size $testdir1_size)
11129         [ -z "$samedir" ] && error "samedir_rename_size count error"
11130         [[ $same_sample -eq 1 ]] ||
11131                 error "samedir_rename_size error $same_sample"
11132         echo "Check same dir rename stats success"
11133
11134         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11135
11136         # check crossdir rename size
11137         mv ${testdir1}/test_0 ${testdir2}/test_0
11138
11139         testdir1_size=$(ls -l $DIR/${tdir} |
11140                 awk '/stats_testdir1/ {print $5}')
11141         testdir2_size=$(ls -l $DIR/${tdir} |
11142                 awk '/stats_testdir2/ {print $5}')
11143
11144         testdir1_size=$(order_2 $testdir1_size)
11145         testdir2_size=$(order_2 $testdir2_size)
11146
11147         testdir1_size=$(size_in_KMGT $testdir1_size)
11148         testdir2_size=$(size_in_KMGT $testdir2_size)
11149
11150         echo "source rename dir size: ${testdir1_size}"
11151         echo "target rename dir size: ${testdir2_size}"
11152
11153         eval $cmd || error "$cmd failed"
11154         local crossdir=$($cmd | grep 'crossdir')
11155         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11156         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11157         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11158         [[ $src_sample -eq 1 ]] ||
11159                 error "crossdir_rename_size error $src_sample"
11160         [[ $tgt_sample -eq 1 ]] ||
11161                 error "crossdir_rename_size error $tgt_sample"
11162         echo "Check cross dir rename stats success"
11163         rm -rf $DIR/${tdir}
11164 }
11165 run_test 133d "Verifying rename_stats ========================================"
11166
11167 test_133e() {
11168         remote_mds_nodsh && skip "remote MDS with nodsh"
11169         remote_ost_nodsh && skip "remote OST with nodsh"
11170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11171
11172         local testdir=$DIR/${tdir}/stats_testdir
11173         local ctr f0 f1 bs=32768 count=42 sum
11174
11175         mkdir -p ${testdir} || error "mkdir failed"
11176
11177         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11178
11179         for ctr in {write,read}_bytes; do
11180                 sync
11181                 cancel_lru_locks osc
11182
11183                 do_facet ost1 $LCTL set_param -n \
11184                         "obdfilter.*.exports.clear=clear"
11185
11186                 if [ $ctr = write_bytes ]; then
11187                         f0=/dev/zero
11188                         f1=${testdir}/${tfile}
11189                 else
11190                         f0=${testdir}/${tfile}
11191                         f1=/dev/null
11192                 fi
11193
11194                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11195                         error "dd failed"
11196                 sync
11197                 cancel_lru_locks osc
11198
11199                 sum=$(do_facet ost1 $LCTL get_param \
11200                         "obdfilter.*.exports.*.stats" |
11201                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11202                                 $1 == ctr { sum += $7 }
11203                                 END { printf("%0.0f", sum) }')
11204
11205                 if ((sum != bs * count)); then
11206                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11207                 fi
11208         done
11209
11210         rm -rf $DIR/${tdir}
11211 }
11212 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11213
11214 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11215
11216 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11217 # not honor the -ignore_readdir_race option correctly. So we call
11218 # error_ignore() rather than error() in these cases. See LU-11152.
11219 error_133() {
11220         if (find --version; do_facet mds1 find --version) |
11221                 grep -q '\b4\.5\.1[1-4]\b'; then
11222                 error_ignore LU-11152 "$@"
11223         else
11224                 error "$@"
11225         fi
11226 }
11227
11228 test_133f() {
11229         # First without trusting modes.
11230         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11231         echo "proc_dirs='$proc_dirs'"
11232         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11233         find $proc_dirs -exec cat '{}' \; &> /dev/null
11234
11235         # Second verifying readability.
11236         $LCTL get_param -R '*' &> /dev/null
11237
11238         # Verifing writability with badarea_io.
11239         find $proc_dirs \
11240                 -ignore_readdir_race \
11241                 -type f \
11242                 -not -name force_lbug \
11243                 -not -name changelog_mask \
11244                 -exec badarea_io '{}' \; ||
11245                         error_133 "find $proc_dirs failed"
11246 }
11247 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11248
11249 test_133g() {
11250         remote_mds_nodsh && skip "remote MDS with nodsh"
11251         remote_ost_nodsh && skip "remote OST with nodsh"
11252
11253         # eventually, this can also be replaced with "lctl get_param -R",
11254         # but not until that option is always available on the server
11255         local facet
11256         for facet in mds1 ost1; do
11257                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11258                         skip_noexit "Too old lustre on $facet"
11259                 local facet_proc_dirs=$(do_facet $facet \
11260                                         \\\ls -d $proc_regexp 2>/dev/null)
11261                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11262                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11263                 do_facet $facet find $facet_proc_dirs \
11264                         ! -name req_history \
11265                         -exec cat '{}' \\\; &> /dev/null
11266
11267                 do_facet $facet find $facet_proc_dirs \
11268                         ! -name req_history \
11269                         -type f \
11270                         -exec cat '{}' \\\; &> /dev/null ||
11271                                 error "proc file read failed"
11272
11273                 do_facet $facet find $facet_proc_dirs \
11274                         -ignore_readdir_race \
11275                         -type f \
11276                         -not -name force_lbug \
11277                         -not -name changelog_mask \
11278                         -exec badarea_io '{}' \\\; ||
11279                                 error_133 "$facet find $facet_proc_dirs failed"
11280         done
11281
11282         # remount the FS in case writes/reads /proc break the FS
11283         cleanup || error "failed to unmount"
11284         setup || error "failed to setup"
11285         true
11286 }
11287 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11288
11289 test_133h() {
11290         remote_mds_nodsh && skip "remote MDS with nodsh"
11291         remote_ost_nodsh && skip "remote OST with nodsh"
11292         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11293                 skip "Need MDS version at least 2.9.54"
11294
11295         local facet
11296
11297         for facet in client mds1 ost1; do
11298                 local facet_proc_dirs=$(do_facet $facet \
11299                                         \\\ls -d $proc_regexp 2> /dev/null)
11300                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11301                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11302                 # Get the list of files that are missing the terminating newline
11303                 local missing=($(do_facet $facet \
11304                         find ${facet_proc_dirs} -type f \|              \
11305                                 while read F\; do                       \
11306                                         awk -v FS='\v' -v RS='\v\v'     \
11307                                         "'END { if(NR>0 &&              \
11308                                         \\\$NF !~ /.*\\\n\$/)           \
11309                                                 print FILENAME}'"       \
11310                                         '\$F'\;                         \
11311                                 done 2>/dev/null))
11312                 [ ${#missing[*]} -eq 0 ] ||
11313                         error "files do not end with newline: ${missing[*]}"
11314         done
11315 }
11316 run_test 133h "Proc files should end with newlines"
11317
11318 test_134a() {
11319         remote_mds_nodsh && skip "remote MDS with nodsh"
11320         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11321                 skip "Need MDS version at least 2.7.54"
11322
11323         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11324         cancel_lru_locks mdc
11325
11326         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11327         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11328         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11329
11330         local nr=1000
11331         createmany -o $DIR/$tdir/f $nr ||
11332                 error "failed to create $nr files in $DIR/$tdir"
11333         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11334
11335         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11336         do_facet mds1 $LCTL set_param fail_loc=0x327
11337         do_facet mds1 $LCTL set_param fail_val=500
11338         touch $DIR/$tdir/m
11339
11340         echo "sleep 10 seconds ..."
11341         sleep 10
11342         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11343
11344         do_facet mds1 $LCTL set_param fail_loc=0
11345         do_facet mds1 $LCTL set_param fail_val=0
11346         [ $lck_cnt -lt $unused ] ||
11347                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11348
11349         rm $DIR/$tdir/m
11350         unlinkmany $DIR/$tdir/f $nr
11351 }
11352 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11353
11354 test_134b() {
11355         remote_mds_nodsh && skip "remote MDS with nodsh"
11356         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11357                 skip "Need MDS version at least 2.7.54"
11358
11359         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11360         cancel_lru_locks mdc
11361
11362         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11363                         ldlm.lock_reclaim_threshold_mb)
11364         # disable reclaim temporarily
11365         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11366
11367         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11368         do_facet mds1 $LCTL set_param fail_loc=0x328
11369         do_facet mds1 $LCTL set_param fail_val=500
11370
11371         $LCTL set_param debug=+trace
11372
11373         local nr=600
11374         createmany -o $DIR/$tdir/f $nr &
11375         local create_pid=$!
11376
11377         echo "Sleep $TIMEOUT seconds ..."
11378         sleep $TIMEOUT
11379         if ! ps -p $create_pid  > /dev/null 2>&1; then
11380                 do_facet mds1 $LCTL set_param fail_loc=0
11381                 do_facet mds1 $LCTL set_param fail_val=0
11382                 do_facet mds1 $LCTL set_param \
11383                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11384                 error "createmany finished incorrectly!"
11385         fi
11386         do_facet mds1 $LCTL set_param fail_loc=0
11387         do_facet mds1 $LCTL set_param fail_val=0
11388         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11389         wait $create_pid || return 1
11390
11391         unlinkmany $DIR/$tdir/f $nr
11392 }
11393 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11394
11395 test_140() { #bug-17379
11396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11397
11398         test_mkdir $DIR/$tdir
11399         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11400         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11401
11402         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11403         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11404         local i=0
11405         while i=$((i + 1)); do
11406                 test_mkdir $i
11407                 cd $i || error "Changing to $i"
11408                 ln -s ../stat stat || error "Creating stat symlink"
11409                 # Read the symlink until ELOOP present,
11410                 # not LBUGing the system is considered success,
11411                 # we didn't overrun the stack.
11412                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11413                 if [ $ret -ne 0 ]; then
11414                         if [ $ret -eq 40 ]; then
11415                                 break  # -ELOOP
11416                         else
11417                                 error "Open stat symlink"
11418                                         return
11419                         fi
11420                 fi
11421         done
11422         i=$((i - 1))
11423         echo "The symlink depth = $i"
11424         [ $i -eq 5 -o $i -eq 7 -o $i -eq 8 -o $i -eq 40 ] ||
11425                                         error "Invalid symlink depth"
11426
11427         # Test recursive symlink
11428         ln -s symlink_self symlink_self
11429         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11430         echo "open symlink_self returns $ret"
11431         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11432 }
11433 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11434
11435 test_150() {
11436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11437
11438         local TF="$TMP/$tfile"
11439
11440         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11441         cp $TF $DIR/$tfile
11442         cancel_lru_locks $OSC
11443         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11444         remount_client $MOUNT
11445         df -P $MOUNT
11446         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11447
11448         $TRUNCATE $TF 6000
11449         $TRUNCATE $DIR/$tfile 6000
11450         cancel_lru_locks $OSC
11451         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11452
11453         echo "12345" >>$TF
11454         echo "12345" >>$DIR/$tfile
11455         cancel_lru_locks $OSC
11456         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
11457
11458         echo "12345" >>$TF
11459         echo "12345" >>$DIR/$tfile
11460         cancel_lru_locks $OSC
11461         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
11462
11463         rm -f $TF
11464         true
11465 }
11466 run_test 150 "truncate/append tests"
11467
11468 #LU-2902 roc_hit was not able to read all values from lproc
11469 function roc_hit_init() {
11470         local list=$(comma_list $(osts_nodes))
11471         local dir=$DIR/$tdir-check
11472         local file=$dir/$tfile
11473         local BEFORE
11474         local AFTER
11475         local idx
11476
11477         test_mkdir $dir
11478         #use setstripe to do a write to every ost
11479         for i in $(seq 0 $((OSTCOUNT-1))); do
11480                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
11481                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
11482                 idx=$(printf %04x $i)
11483                 BEFORE=$(get_osd_param $list *OST*$idx stats |
11484                         awk '$1 == "cache_access" {sum += $7}
11485                                 END { printf("%0.0f", sum) }')
11486
11487                 cancel_lru_locks osc
11488                 cat $file >/dev/null
11489
11490                 AFTER=$(get_osd_param $list *OST*$idx stats |
11491                         awk '$1 == "cache_access" {sum += $7}
11492                                 END { printf("%0.0f", sum) }')
11493
11494                 echo BEFORE:$BEFORE AFTER:$AFTER
11495                 if ! let "AFTER - BEFORE == 4"; then
11496                         rm -rf $dir
11497                         error "roc_hit is not safe to use"
11498                 fi
11499                 rm $file
11500         done
11501
11502         rm -rf $dir
11503 }
11504
11505 function roc_hit() {
11506         local list=$(comma_list $(osts_nodes))
11507         echo $(get_osd_param $list '' stats |
11508                 awk '$1 == "cache_hit" {sum += $7}
11509                         END { printf("%0.0f", sum) }')
11510 }
11511
11512 function set_cache() {
11513         local on=1
11514
11515         if [ "$2" == "off" ]; then
11516                 on=0;
11517         fi
11518         local list=$(comma_list $(osts_nodes))
11519         set_osd_param $list '' $1_cache_enable $on
11520
11521         cancel_lru_locks osc
11522 }
11523
11524 test_151() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         remote_ost_nodsh && skip "remote OST with nodsh"
11527
11528         local CPAGES=3
11529         local list=$(comma_list $(osts_nodes))
11530
11531         # check whether obdfilter is cache capable at all
11532         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
11533                 skip "not cache-capable obdfilter"
11534         fi
11535
11536         # check cache is enabled on all obdfilters
11537         if get_osd_param $list '' read_cache_enable | grep 0; then
11538                 skip "oss cache is disabled"
11539         fi
11540
11541         set_osd_param $list '' writethrough_cache_enable 1
11542
11543         # check write cache is enabled on all obdfilters
11544         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
11545                 skip "oss write cache is NOT enabled"
11546         fi
11547
11548         roc_hit_init
11549
11550         #define OBD_FAIL_OBD_NO_LRU  0x609
11551         do_nodes $list $LCTL set_param fail_loc=0x609
11552
11553         # pages should be in the case right after write
11554         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
11555                 error "dd failed"
11556
11557         local BEFORE=$(roc_hit)
11558         cancel_lru_locks osc
11559         cat $DIR/$tfile >/dev/null
11560         local AFTER=$(roc_hit)
11561
11562         do_nodes $list $LCTL set_param fail_loc=0
11563
11564         if ! let "AFTER - BEFORE == CPAGES"; then
11565                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
11566         fi
11567
11568         # the following read invalidates the cache
11569         cancel_lru_locks osc
11570         set_osd_param $list '' read_cache_enable 0
11571         cat $DIR/$tfile >/dev/null
11572
11573         # now data shouldn't be found in the cache
11574         BEFORE=$(roc_hit)
11575         cancel_lru_locks osc
11576         cat $DIR/$tfile >/dev/null
11577         AFTER=$(roc_hit)
11578         if let "AFTER - BEFORE != 0"; then
11579                 error "IN CACHE: before: $BEFORE, after: $AFTER"
11580         fi
11581
11582         set_osd_param $list '' read_cache_enable 1
11583         rm -f $DIR/$tfile
11584 }
11585 run_test 151 "test cache on oss and controls ==============================="
11586
11587 test_152() {
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589
11590         local TF="$TMP/$tfile"
11591
11592         # simulate ENOMEM during write
11593 #define OBD_FAIL_OST_NOMEM      0x226
11594         lctl set_param fail_loc=0x80000226
11595         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11596         cp $TF $DIR/$tfile
11597         sync || error "sync failed"
11598         lctl set_param fail_loc=0
11599
11600         # discard client's cache
11601         cancel_lru_locks osc
11602
11603         # simulate ENOMEM during read
11604         lctl set_param fail_loc=0x80000226
11605         cmp $TF $DIR/$tfile || error "cmp failed"
11606         lctl set_param fail_loc=0
11607
11608         rm -f $TF
11609 }
11610 run_test 152 "test read/write with enomem ============================"
11611
11612 test_153() {
11613         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
11614 }
11615 run_test 153 "test if fdatasync does not crash ======================="
11616
11617 dot_lustre_fid_permission_check() {
11618         local fid=$1
11619         local ffid=$MOUNT/.lustre/fid/$fid
11620         local test_dir=$2
11621
11622         echo "stat fid $fid"
11623         stat $ffid > /dev/null || error "stat $ffid failed."
11624         echo "touch fid $fid"
11625         touch $ffid || error "touch $ffid failed."
11626         echo "write to fid $fid"
11627         cat /etc/hosts > $ffid || error "write $ffid failed."
11628         echo "read fid $fid"
11629         diff /etc/hosts $ffid || error "read $ffid failed."
11630         echo "append write to fid $fid"
11631         cat /etc/hosts >> $ffid || error "append write $ffid failed."
11632         echo "rename fid $fid"
11633         mv $ffid $test_dir/$tfile.1 &&
11634                 error "rename $ffid to $tfile.1 should fail."
11635         touch $test_dir/$tfile.1
11636         mv $test_dir/$tfile.1 $ffid &&
11637                 error "rename $tfile.1 to $ffid should fail."
11638         rm -f $test_dir/$tfile.1
11639         echo "truncate fid $fid"
11640         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
11641         echo "link fid $fid"
11642         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
11643         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
11644                 echo "setfacl fid $fid"
11645                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
11646                 echo "getfacl fid $fid"
11647                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
11648         fi
11649         echo "unlink fid $fid"
11650         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
11651         echo "mknod fid $fid"
11652         mknod $ffid c 1 3 && error "mknod $ffid should fail."
11653
11654         fid=[0xf00000400:0x1:0x0]
11655         ffid=$MOUNT/.lustre/fid/$fid
11656
11657         echo "stat non-exist fid $fid"
11658         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
11659         echo "write to non-exist fid $fid"
11660         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
11661         echo "link new fid $fid"
11662         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
11663
11664         mkdir -p $test_dir/$tdir
11665         touch $test_dir/$tdir/$tfile
11666         fid=$($LFS path2fid $test_dir/$tdir)
11667         rc=$?
11668         [ $rc -ne 0 ] &&
11669                 error "error: could not get fid for $test_dir/$dir/$tfile."
11670
11671         ffid=$MOUNT/.lustre/fid/$fid
11672
11673         echo "ls $fid"
11674         ls $ffid > /dev/null || error "ls $ffid failed."
11675         echo "touch $fid/$tfile.1"
11676         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
11677
11678         echo "touch $MOUNT/.lustre/fid/$tfile"
11679         touch $MOUNT/.lustre/fid/$tfile && \
11680                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
11681
11682         echo "setxattr to $MOUNT/.lustre/fid"
11683         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
11684
11685         echo "listxattr for $MOUNT/.lustre/fid"
11686         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
11687
11688         echo "delxattr from $MOUNT/.lustre/fid"
11689         setfattr -x trusted.name1 $MOUNT/.lustre/fid
11690
11691         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
11692         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
11693                 error "touch invalid fid should fail."
11694
11695         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
11696         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
11697                 error "touch non-normal fid should fail."
11698
11699         echo "rename $tdir to $MOUNT/.lustre/fid"
11700         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
11701                 error "rename to $MOUNT/.lustre/fid should fail."
11702
11703         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
11704         then            # LU-3547
11705                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
11706                 local new_obf_mode=777
11707
11708                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
11709                 chmod $new_obf_mode $DIR/.lustre/fid ||
11710                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
11711
11712                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
11713                 [ $obf_mode -eq $new_obf_mode ] ||
11714                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
11715
11716                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
11717                 chmod $old_obf_mode $DIR/.lustre/fid ||
11718                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
11719         fi
11720
11721         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
11722         fid=$($LFS path2fid $test_dir/$tfile-2)
11723
11724         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
11725         then # LU-5424
11726                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
11727                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
11728                         error "create lov data thru .lustre failed"
11729         fi
11730         echo "cp /etc/passwd $test_dir/$tfile-2"
11731         cp /etc/passwd $test_dir/$tfile-2 ||
11732                 error "copy to $test_dir/$tfile-2 failed."
11733         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
11734         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
11735                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
11736
11737         rm -rf $test_dir/tfile.lnk
11738         rm -rf $test_dir/$tfile-2
11739 }
11740
11741 test_154A() {
11742         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11743                 skip "Need MDS version at least 2.4.1"
11744
11745         local tf=$DIR/$tfile
11746         touch $tf
11747
11748         local fid=$($LFS path2fid $tf)
11749         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
11750
11751         # check that we get the same pathname back
11752         local found=$($LFS fid2path $MOUNT "$fid")
11753         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
11754         [ "$found" == "$tf" ] ||
11755                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
11756 }
11757 run_test 154A "lfs path2fid and fid2path basic checks"
11758
11759 test_154B() {
11760         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11761                 skip "Need MDS version at least 2.4.1"
11762
11763         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
11764         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
11765         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
11766         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
11767
11768         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
11769         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
11770
11771         # check that we get the same pathname
11772         echo "PFID: $PFID, name: $name"
11773         local FOUND=$($LFS fid2path $MOUNT "$PFID")
11774         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
11775         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
11776                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
11777
11778         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
11779 }
11780 run_test 154B "verify the ll_decode_linkea tool"
11781
11782 test_154a() {
11783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11784         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11785         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11786                 skip "Need MDS version at least 2.2.51"
11787         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11788
11789         cp /etc/hosts $DIR/$tfile
11790
11791         fid=$($LFS path2fid $DIR/$tfile)
11792         rc=$?
11793         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
11794
11795         dot_lustre_fid_permission_check "$fid" $DIR ||
11796                 error "dot lustre permission check $fid failed"
11797
11798         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
11799
11800         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
11801
11802         touch $MOUNT/.lustre/file &&
11803                 error "creation is not allowed under .lustre"
11804
11805         mkdir $MOUNT/.lustre/dir &&
11806                 error "mkdir is not allowed under .lustre"
11807
11808         rm -rf $DIR/$tfile
11809 }
11810 run_test 154a "Open-by-FID"
11811
11812 test_154b() {
11813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11814         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
11816         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
11817                 skip "Need MDS version at least 2.2.51"
11818
11819         local remote_dir=$DIR/$tdir/remote_dir
11820         local MDTIDX=1
11821         local rc=0
11822
11823         mkdir -p $DIR/$tdir
11824         $LFS mkdir -i $MDTIDX $remote_dir ||
11825                 error "create remote directory failed"
11826
11827         cp /etc/hosts $remote_dir/$tfile
11828
11829         fid=$($LFS path2fid $remote_dir/$tfile)
11830         rc=$?
11831         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
11832
11833         dot_lustre_fid_permission_check "$fid" $remote_dir ||
11834                 error "dot lustre permission check $fid failed"
11835         rm -rf $DIR/$tdir
11836 }
11837 run_test 154b "Open-by-FID for remote directory"
11838
11839 test_154c() {
11840         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
11841                 skip "Need MDS version at least 2.4.1"
11842
11843         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
11844         local FID1=$($LFS path2fid $DIR/$tfile.1)
11845         local FID2=$($LFS path2fid $DIR/$tfile.2)
11846         local FID3=$($LFS path2fid $DIR/$tfile.3)
11847
11848         local N=1
11849         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
11850                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
11851                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
11852                 local want=FID$N
11853                 [ "$FID" = "${!want}" ] ||
11854                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
11855                 N=$((N + 1))
11856         done
11857
11858         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
11859         do
11860                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
11861                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
11862                 N=$((N + 1))
11863         done
11864 }
11865 run_test 154c "lfs path2fid and fid2path multiple arguments"
11866
11867 test_154d() {
11868         remote_mds_nodsh && skip "remote MDS with nodsh"
11869         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
11870                 skip "Need MDS version at least 2.5.53"
11871
11872         if remote_mds; then
11873                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
11874         else
11875                 nid="0@lo"
11876         fi
11877         local proc_ofile="mdt.*.exports.'$nid'.open_files"
11878         local fd
11879         local cmd
11880
11881         rm -f $DIR/$tfile
11882         touch $DIR/$tfile
11883
11884         local fid=$($LFS path2fid $DIR/$tfile)
11885         # Open the file
11886         fd=$(free_fd)
11887         cmd="exec $fd<$DIR/$tfile"
11888         eval $cmd
11889         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
11890         echo "$fid_list" | grep "$fid"
11891         rc=$?
11892
11893         cmd="exec $fd>/dev/null"
11894         eval $cmd
11895         if [ $rc -ne 0 ]; then
11896                 error "FID $fid not found in open files list $fid_list"
11897         fi
11898 }
11899 run_test 154d "Verify open file fid"
11900
11901 test_154e()
11902 {
11903         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
11904                 skip "Need MDS version at least 2.6.50"
11905
11906         if ls -a $MOUNT | grep -q '^\.lustre$'; then
11907                 error ".lustre returned by readdir"
11908         fi
11909 }
11910 run_test 154e ".lustre is not returned by readdir"
11911
11912 test_154f() {
11913         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11914
11915         # create parent directory on a single MDT to avoid cross-MDT hardlinks
11916         test_mkdir -p -c1 $DIR/$tdir/d
11917         # test dirs inherit from its stripe
11918         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
11919         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
11920         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
11921         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
11922         touch $DIR/f
11923
11924         # get fid of parents
11925         local FID0=$($LFS path2fid $DIR/$tdir/d)
11926         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
11927         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
11928         local FID3=$($LFS path2fid $DIR)
11929
11930         # check that path2fid --parents returns expected <parent_fid>/name
11931         # 1) test for a directory (single parent)
11932         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
11933         [ "$parent" == "$FID0/foo1" ] ||
11934                 error "expected parent: $FID0/foo1, got: $parent"
11935
11936         # 2) test for a file with nlink > 1 (multiple parents)
11937         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
11938         echo "$parent" | grep -F "$FID1/$tfile" ||
11939                 error "$FID1/$tfile not returned in parent list"
11940         echo "$parent" | grep -F "$FID2/link" ||
11941                 error "$FID2/link not returned in parent list"
11942
11943         # 3) get parent by fid
11944         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
11945         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11946         echo "$parent" | grep -F "$FID1/$tfile" ||
11947                 error "$FID1/$tfile not returned in parent list (by fid)"
11948         echo "$parent" | grep -F "$FID2/link" ||
11949                 error "$FID2/link not returned in parent list (by fid)"
11950
11951         # 4) test for entry in root directory
11952         parent=$($LFS path2fid --parents $DIR/f)
11953         echo "$parent" | grep -F "$FID3/f" ||
11954                 error "$FID3/f not returned in parent list"
11955
11956         # 5) test it on root directory
11957         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
11958                 error "$MOUNT should not have parents"
11959
11960         # enable xattr caching and check that linkea is correctly updated
11961         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11962         save_lustre_params client "llite.*.xattr_cache" > $save
11963         lctl set_param llite.*.xattr_cache 1
11964
11965         # 6.1) linkea update on rename
11966         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
11967
11968         # get parents by fid
11969         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11970         # foo1 should no longer be returned in parent list
11971         echo "$parent" | grep -F "$FID1" &&
11972                 error "$FID1 should no longer be in parent list"
11973         # the new path should appear
11974         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
11975                 error "$FID2/$tfile.moved is not in parent list"
11976
11977         # 6.2) linkea update on unlink
11978         rm -f $DIR/$tdir/d/foo2/link
11979         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
11980         # foo2/link should no longer be returned in parent list
11981         echo "$parent" | grep -F "$FID2/link" &&
11982                 error "$FID2/link should no longer be in parent list"
11983         true
11984
11985         rm -f $DIR/f
11986         restore_lustre_params < $save
11987         rm -f $save
11988 }
11989 run_test 154f "get parent fids by reading link ea"
11990
11991 test_154g()
11992 {
11993         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
11994         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
11995            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
11996                 skip "Need MDS version at least 2.6.92"
11997
11998         mkdir -p $DIR/$tdir
11999         llapi_fid_test -d $DIR/$tdir
12000 }
12001 run_test 154g "various llapi FID tests"
12002
12003 test_155_small_load() {
12004     local temp=$TMP/$tfile
12005     local file=$DIR/$tfile
12006
12007     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12008         error "dd of=$temp bs=6096 count=1 failed"
12009     cp $temp $file
12010     cancel_lru_locks $OSC
12011     cmp $temp $file || error "$temp $file differ"
12012
12013     $TRUNCATE $temp 6000
12014     $TRUNCATE $file 6000
12015     cmp $temp $file || error "$temp $file differ (truncate1)"
12016
12017     echo "12345" >>$temp
12018     echo "12345" >>$file
12019     cmp $temp $file || error "$temp $file differ (append1)"
12020
12021     echo "12345" >>$temp
12022     echo "12345" >>$file
12023     cmp $temp $file || error "$temp $file differ (append2)"
12024
12025     rm -f $temp $file
12026     true
12027 }
12028
12029 test_155_big_load() {
12030         remote_ost_nodsh && skip "remote OST with nodsh"
12031
12032         local temp=$TMP/$tfile
12033         local file=$DIR/$tfile
12034
12035         free_min_max
12036         local cache_size=$(do_facet ost$((MAXI+1)) \
12037                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12038         local large_file_size=$((cache_size * 2))
12039
12040         echo "OSS cache size: $cache_size KB"
12041         echo "Large file size: $large_file_size KB"
12042
12043         [ $MAXV -le $large_file_size ] &&
12044                 skip_env "max available OST size needs > $large_file_size KB"
12045
12046         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12047
12048         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12049                 error "dd of=$temp bs=$large_file_size count=1k failed"
12050         cp $temp $file
12051         ls -lh $temp $file
12052         cancel_lru_locks osc
12053         cmp $temp $file || error "$temp $file differ"
12054
12055         rm -f $temp $file
12056         true
12057 }
12058
12059 save_writethrough() {
12060         local facets=$(get_facets OST)
12061
12062         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12063 }
12064
12065 test_155a() {
12066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12067
12068         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12069
12070         save_writethrough $p
12071
12072         set_cache read on
12073         set_cache writethrough on
12074         test_155_small_load
12075         restore_lustre_params < $p
12076         rm -f $p
12077 }
12078 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12079
12080 test_155b() {
12081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12082
12083         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12084
12085         save_writethrough $p
12086
12087         set_cache read on
12088         set_cache writethrough off
12089         test_155_small_load
12090         restore_lustre_params < $p
12091         rm -f $p
12092 }
12093 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12094
12095 test_155c() {
12096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12097
12098         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12099
12100         save_writethrough $p
12101
12102         set_cache read off
12103         set_cache writethrough on
12104         test_155_small_load
12105         restore_lustre_params < $p
12106         rm -f $p
12107 }
12108 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12109
12110 test_155d() {
12111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12112
12113         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12114
12115         save_writethrough $p
12116
12117         set_cache read off
12118         set_cache writethrough off
12119         test_155_small_load
12120         restore_lustre_params < $p
12121         rm -f $p
12122 }
12123 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12124
12125 test_155e() {
12126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12127
12128         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12129
12130         save_writethrough $p
12131
12132         set_cache read on
12133         set_cache writethrough on
12134         test_155_big_load
12135         restore_lustre_params < $p
12136         rm -f $p
12137 }
12138 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12139
12140 test_155f() {
12141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12142
12143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12144
12145         save_writethrough $p
12146
12147         set_cache read on
12148         set_cache writethrough off
12149         test_155_big_load
12150         restore_lustre_params < $p
12151         rm -f $p
12152 }
12153 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12154
12155 test_155g() {
12156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12157
12158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12159
12160         save_writethrough $p
12161
12162         set_cache read off
12163         set_cache writethrough on
12164         test_155_big_load
12165         restore_lustre_params < $p
12166         rm -f $p
12167 }
12168 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12169
12170 test_155h() {
12171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12172
12173         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12174
12175         save_writethrough $p
12176
12177         set_cache read off
12178         set_cache writethrough off
12179         test_155_big_load
12180         restore_lustre_params < $p
12181         rm -f $p
12182 }
12183 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12184
12185 test_156() {
12186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12187         remote_ost_nodsh && skip "remote OST with nodsh"
12188         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12189                 skip "stats not implemented on old servers"
12190         [ "$ost1_FSTYPE" = "zfs" ] &&
12191                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12192
12193         local CPAGES=3
12194         local BEFORE
12195         local AFTER
12196         local file="$DIR/$tfile"
12197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12198
12199         save_writethrough $p
12200         roc_hit_init
12201
12202         log "Turn on read and write cache"
12203         set_cache read on
12204         set_cache writethrough on
12205
12206         log "Write data and read it back."
12207         log "Read should be satisfied from the cache."
12208         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12209         BEFORE=$(roc_hit)
12210         cancel_lru_locks osc
12211         cat $file >/dev/null
12212         AFTER=$(roc_hit)
12213         if ! let "AFTER - BEFORE == CPAGES"; then
12214                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12215         else
12216                 log "cache hits:: before: $BEFORE, after: $AFTER"
12217         fi
12218
12219         log "Read again; it should be satisfied from the cache."
12220         BEFORE=$AFTER
12221         cancel_lru_locks osc
12222         cat $file >/dev/null
12223         AFTER=$(roc_hit)
12224         if ! let "AFTER - BEFORE == CPAGES"; then
12225                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12226         else
12227                 log "cache hits:: before: $BEFORE, after: $AFTER"
12228         fi
12229
12230         log "Turn off the read cache and turn on the write cache"
12231         set_cache read off
12232         set_cache writethrough on
12233
12234         log "Read again; it should be satisfied from the cache."
12235         BEFORE=$(roc_hit)
12236         cancel_lru_locks osc
12237         cat $file >/dev/null
12238         AFTER=$(roc_hit)
12239         if ! let "AFTER - BEFORE == CPAGES"; then
12240                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12241         else
12242                 log "cache hits:: before: $BEFORE, after: $AFTER"
12243         fi
12244
12245         log "Read again; it should not be satisfied from the cache."
12246         BEFORE=$AFTER
12247         cancel_lru_locks osc
12248         cat $file >/dev/null
12249         AFTER=$(roc_hit)
12250         if ! let "AFTER - BEFORE == 0"; then
12251                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12252         else
12253                 log "cache hits:: before: $BEFORE, after: $AFTER"
12254         fi
12255
12256         log "Write data and read it back."
12257         log "Read should be satisfied from the cache."
12258         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12259         BEFORE=$(roc_hit)
12260         cancel_lru_locks osc
12261         cat $file >/dev/null
12262         AFTER=$(roc_hit)
12263         if ! let "AFTER - BEFORE == CPAGES"; then
12264                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12265         else
12266                 log "cache hits:: before: $BEFORE, after: $AFTER"
12267         fi
12268
12269         log "Read again; it should not be satisfied from the cache."
12270         BEFORE=$AFTER
12271         cancel_lru_locks osc
12272         cat $file >/dev/null
12273         AFTER=$(roc_hit)
12274         if ! let "AFTER - BEFORE == 0"; then
12275                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12276         else
12277                 log "cache hits:: before: $BEFORE, after: $AFTER"
12278         fi
12279
12280         log "Turn off read and write cache"
12281         set_cache read off
12282         set_cache writethrough off
12283
12284         log "Write data and read it back"
12285         log "It should not be satisfied from the cache."
12286         rm -f $file
12287         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12288         cancel_lru_locks osc
12289         BEFORE=$(roc_hit)
12290         cat $file >/dev/null
12291         AFTER=$(roc_hit)
12292         if ! let "AFTER - BEFORE == 0"; then
12293                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12294         else
12295                 log "cache hits:: before: $BEFORE, after: $AFTER"
12296         fi
12297
12298         log "Turn on the read cache and turn off the write cache"
12299         set_cache read on
12300         set_cache writethrough off
12301
12302         log "Write data and read it back"
12303         log "It should not be satisfied from the cache."
12304         rm -f $file
12305         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12306         BEFORE=$(roc_hit)
12307         cancel_lru_locks osc
12308         cat $file >/dev/null
12309         AFTER=$(roc_hit)
12310         if ! let "AFTER - BEFORE == 0"; then
12311                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12312         else
12313                 log "cache hits:: before: $BEFORE, after: $AFTER"
12314         fi
12315
12316         log "Read again; it should be satisfied from the cache."
12317         BEFORE=$(roc_hit)
12318         cancel_lru_locks osc
12319         cat $file >/dev/null
12320         AFTER=$(roc_hit)
12321         if ! let "AFTER - BEFORE == CPAGES"; then
12322                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12323         else
12324                 log "cache hits:: before: $BEFORE, after: $AFTER"
12325         fi
12326
12327         restore_lustre_params < $p
12328         rm -f $p $file
12329 }
12330 run_test 156 "Verification of tunables"
12331
12332 test_160a() {
12333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12334         remote_mds_nodsh && skip "remote MDS with nodsh"
12335         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12336                 skip "Need MDS version at least 2.2.0"
12337
12338         changelog_register || error "changelog_register failed"
12339         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12340         changelog_users $SINGLEMDS | grep -q $cl_user ||
12341                 error "User $cl_user not found in changelog_users"
12342
12343         # change something
12344         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12345         changelog_clear 0 || error "changelog_clear failed"
12346         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12347         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12348         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12349         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12350         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12351         rm $DIR/$tdir/pics/desktop.jpg
12352
12353         changelog_dump | tail -10
12354
12355         echo "verifying changelog mask"
12356         changelog_chmask "-MKDIR"
12357         changelog_chmask "-CLOSE"
12358
12359         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12360         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12361
12362         changelog_chmask "+MKDIR"
12363         changelog_chmask "+CLOSE"
12364
12365         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12366         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12367
12368         changelog_dump | tail -10
12369         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12370         CLOSES=$(changelog_dump | grep -c "CLOSE")
12371         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12372         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12373
12374         # verify contents
12375         echo "verifying target fid"
12376         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12377         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12378         [ "$fidc" == "$fidf" ] ||
12379                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12380         echo "verifying parent fid"
12381         # The FID returned from the Changelog may be the directory shard on
12382         # a different MDT, and not the FID returned by path2fid on the parent.
12383         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12384         # since this is what will matter when recreating this file in the tree.
12385         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12386         local pathp=$($LFS fid2path $MOUNT "$fidp")
12387         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12388                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12389
12390         echo "getting records for $cl_user"
12391         changelog_users $SINGLEMDS
12392         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12393         local nclr=3
12394         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12395                 error "changelog_clear failed"
12396         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12397         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12398         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12399                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12400
12401         local min0_rec=$(changelog_users $SINGLEMDS |
12402                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12403         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12404                           awk '{ print $1; exit; }')
12405
12406         changelog_dump | tail -n 5
12407         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12408         [ $first_rec == $((min0_rec + 1)) ] ||
12409                 error "first index should be $min0_rec + 1 not $first_rec"
12410
12411         # LU-3446 changelog index reset on MDT restart
12412         local cur_rec1=$(changelog_users $SINGLEMDS |
12413                          awk '/^current.index:/ { print $NF }')
12414         changelog_clear 0 ||
12415                 error "clear all changelog records for $cl_user failed"
12416         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12417         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12418                 error "Fail to start $SINGLEMDS"
12419         local cur_rec2=$(changelog_users $SINGLEMDS |
12420                          awk '/^current.index:/ { print $NF }')
12421         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12422         [ $cur_rec1 == $cur_rec2 ] ||
12423                 error "current index should be $cur_rec1 not $cur_rec2"
12424
12425         echo "verifying users from this test are deregistered"
12426         changelog_deregister || error "changelog_deregister failed"
12427         changelog_users $SINGLEMDS | grep -q $cl_user &&
12428                 error "User '$cl_user' still in changelog_users"
12429
12430         # lctl get_param -n mdd.*.changelog_users
12431         # current index: 144
12432         # ID    index (idle seconds)
12433         # cl3   144 (2)
12434         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12435                 # this is the normal case where all users were deregistered
12436                 # make sure no new records are added when no users are present
12437                 local last_rec1=$(changelog_users $SINGLEMDS |
12438                                   awk '/^current.index:/ { print $NF }')
12439                 touch $DIR/$tdir/chloe
12440                 local last_rec2=$(changelog_users $SINGLEMDS |
12441                                   awk '/^current.index:/ { print $NF }')
12442                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12443                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12444         else
12445                 # any changelog users must be leftovers from a previous test
12446                 changelog_users $SINGLEMDS
12447                 echo "other changelog users; can't verify off"
12448         fi
12449 }
12450 run_test 160a "changelog sanity"
12451
12452 test_160b() { # LU-3587
12453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12454         remote_mds_nodsh && skip "remote MDS with nodsh"
12455         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12456                 skip "Need MDS version at least 2.2.0"
12457
12458         changelog_register || error "changelog_register failed"
12459         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12460         changelog_users $SINGLEMDS | grep -q $cl_user ||
12461                 error "User '$cl_user' not found in changelog_users"
12462
12463         local longname1=$(str_repeat a 255)
12464         local longname2=$(str_repeat b 255)
12465
12466         cd $DIR
12467         echo "creating very long named file"
12468         touch $longname1 || error "create of '$longname1' failed"
12469         echo "renaming very long named file"
12470         mv $longname1 $longname2
12471
12472         changelog_dump | grep RENME | tail -n 5
12473         rm -f $longname2
12474 }
12475 run_test 160b "Verify that very long rename doesn't crash in changelog"
12476
12477 test_160c() {
12478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12479         remote_mds_nodsh && skip "remote MDS with nodsh"
12480
12481         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
12482                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
12483                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
12484                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
12485
12486         local rc=0
12487
12488         # Registration step
12489         changelog_register || error "changelog_register failed"
12490
12491         rm -rf $DIR/$tdir
12492         mkdir -p $DIR/$tdir
12493         $MCREATE $DIR/$tdir/foo_160c
12494         changelog_chmask "-TRUNC"
12495         $TRUNCATE $DIR/$tdir/foo_160c 200
12496         changelog_chmask "+TRUNC"
12497         $TRUNCATE $DIR/$tdir/foo_160c 199
12498         changelog_dump | tail -n 5
12499         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
12500         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
12501 }
12502 run_test 160c "verify that changelog log catch the truncate event"
12503
12504 test_160d() {
12505         remote_mds_nodsh && skip "remote MDS with nodsh"
12506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12508         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
12509                 skip "Need MDS version at least 2.7.60"
12510
12511         # Registration step
12512         changelog_register || error "changelog_register failed"
12513
12514         mkdir -p $DIR/$tdir/migrate_dir
12515         changelog_clear 0 || error "changelog_clear failed"
12516
12517         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
12518         changelog_dump | tail -n 5
12519         local migrates=$(changelog_dump | grep -c "MIGRT")
12520         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
12521 }
12522 run_test 160d "verify that changelog log catch the migrate event"
12523
12524 test_160e() {
12525         remote_mds_nodsh && skip "remote MDS with nodsh"
12526
12527         # Create a user
12528         changelog_register || error "changelog_register failed"
12529
12530         # Delete a future user (expect fail)
12531         local MDT0=$(facet_svc $SINGLEMDS)
12532         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
12533         local rc=$?
12534
12535         if [ $rc -eq 0 ]; then
12536                 error "Deleted non-existant user cl77"
12537         elif [ $rc -ne 2 ]; then
12538                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
12539         fi
12540
12541         # Clear to a bad index (1 billion should be safe)
12542         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
12543         rc=$?
12544
12545         if [ $rc -eq 0 ]; then
12546                 error "Successfully cleared to invalid CL index"
12547         elif [ $rc -ne 22 ]; then
12548                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
12549         fi
12550 }
12551 run_test 160e "changelog negative testing (should return errors)"
12552
12553 test_160f() {
12554         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12555         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12556                 skip "Need MDS version at least 2.10.56"
12557
12558         local mdts=$(comma_list $(mdts_nodes))
12559
12560         # Create a user
12561         changelog_register || error "first changelog_register failed"
12562         changelog_register || error "second changelog_register failed"
12563         local cl_users
12564         declare -A cl_user1
12565         declare -A cl_user2
12566         local user_rec1
12567         local user_rec2
12568         local i
12569
12570         # generate some changelog records to accumulate on each MDT
12571         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12572         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12573                 error "create $DIR/$tdir/$tfile failed"
12574
12575         # check changelogs have been generated
12576         local nbcl=$(changelog_dump | wc -l)
12577         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12578
12579         for param in "changelog_max_idle_time=10" \
12580                      "changelog_gc=1" \
12581                      "changelog_min_gc_interval=2" \
12582                      "changelog_min_free_cat_entries=3"; do
12583                 local MDT0=$(facet_svc $SINGLEMDS)
12584                 local var="${param%=*}"
12585                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12586
12587                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12588                 do_nodes $mdts $LCTL set_param mdd.*.$param
12589         done
12590
12591         # force cl_user2 to be idle (1st part)
12592         sleep 9
12593
12594         # simulate changelog catalog almost full
12595         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12596         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12597
12598         for i in $(seq $MDSCOUNT); do
12599                 cl_users=(${CL_USERS[mds$i]})
12600                 cl_user1[mds$i]="${cl_users[0]}"
12601                 cl_user2[mds$i]="${cl_users[1]}"
12602
12603                 [ -n "${cl_user1[mds$i]}" ] ||
12604                         error "mds$i: no user registered"
12605                 [ -n "${cl_user2[mds$i]}" ] ||
12606                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12607
12608                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12609                 [ -n "$user_rec1" ] ||
12610                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12611                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12612                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12613                 [ -n "$user_rec2" ] ||
12614                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12615                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12616                      "$user_rec1 + 2 == $user_rec2"
12617                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12618                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12619                               "$user_rec1 + 2, but is $user_rec2"
12620                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12621                 [ -n "$user_rec2" ] ||
12622                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12623                 [ $user_rec1 == $user_rec2 ] ||
12624                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12625                               "$user_rec1, but is $user_rec2"
12626         done
12627
12628         # force cl_user2 to be idle (2nd part) and to reach
12629         # changelog_max_idle_time
12630         sleep 2
12631
12632         # generate one more changelog to trigger fail_loc
12633         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12634                 error "create $DIR/$tdir/${tfile}bis failed"
12635
12636         # ensure gc thread is done
12637         for i in $(mdts_nodes); do
12638                 wait_update $i \
12639                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12640                         error "$i: GC-thread not done"
12641         done
12642
12643         local first_rec
12644         for i in $(seq $MDSCOUNT); do
12645                 # check cl_user1 still registered
12646                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12647                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12648                 # check cl_user2 unregistered
12649                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12650                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12651
12652                 # check changelogs are present and starting at $user_rec1 + 1
12653                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12654                 [ -n "$user_rec1" ] ||
12655                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12656                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12657                             awk '{ print $1; exit; }')
12658
12659                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12660                 [ $((user_rec1 + 1)) == $first_rec ] ||
12661                         error "mds$i: first index should be $user_rec1 + 1, " \
12662                               "but is $first_rec"
12663         done
12664 }
12665 run_test 160f "changelog garbage collect (timestamped users)"
12666
12667 test_160g() {
12668         remote_mds_nodsh && skip "remote MDS with nodsh"
12669         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12670                 skip "Need MDS version at least 2.10.56"
12671
12672         local mdts=$(comma_list $(mdts_nodes))
12673
12674         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
12675         do_nodes $mdts $LCTL set_param fail_loc=0x1314
12676
12677         # Create a user
12678         changelog_register || error "first changelog_register failed"
12679         changelog_register || error "second changelog_register failed"
12680         local cl_users
12681         declare -A cl_user1
12682         declare -A cl_user2
12683         local user_rec1
12684         local user_rec2
12685         local i
12686
12687         # generate some changelog records to accumulate on each MDT
12688         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12689         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12690                 error "create $DIR/$tdir/$tfile failed"
12691
12692         # check changelogs have been generated
12693         local nbcl=$(changelog_dump | wc -l)
12694         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12695
12696         # reduce the max_idle_indexes value to make sure we exceed it
12697         max_ndx=$((nbcl / 2 - 1))
12698
12699         for param in "changelog_max_idle_indexes=$max_ndx" \
12700                      "changelog_gc=1" \
12701                      "changelog_min_gc_interval=2" \
12702                      "changelog_min_free_cat_entries=3"; do
12703                 local MDT0=$(facet_svc $SINGLEMDS)
12704                 local var="${param%=*}"
12705                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12706
12707                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12708                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
12709                         error "unable to set mdd.*.$param"
12710         done
12711
12712         # simulate changelog catalog almost full
12713         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
12714         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
12715
12716         for i in $(seq $MDSCOUNT); do
12717                 cl_users=(${CL_USERS[mds$i]})
12718                 cl_user1[mds$i]="${cl_users[0]}"
12719                 cl_user2[mds$i]="${cl_users[1]}"
12720
12721                 [ -n "${cl_user1[mds$i]}" ] ||
12722                         error "mds$i: no user registered"
12723                 [ -n "${cl_user2[mds$i]}" ] ||
12724                         error "mds$i: only ${cl_user1[mds$i]} is registered"
12725
12726                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12727                 [ -n "$user_rec1" ] ||
12728                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12729                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12730                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12731                 [ -n "$user_rec2" ] ||
12732                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12733                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12734                      "$user_rec1 + 2 == $user_rec2"
12735                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12736                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12737                               "$user_rec1 + 2, but is $user_rec2"
12738                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12739                 [ -n "$user_rec2" ] ||
12740                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12741                 [ $user_rec1 == $user_rec2 ] ||
12742                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12743                               "$user_rec1, but is $user_rec2"
12744         done
12745
12746         # ensure we are past the previous changelog_min_gc_interval set above
12747         sleep 2
12748
12749         # generate one more changelog to trigger fail_loc
12750         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12751                 error "create $DIR/$tdir/${tfile}bis failed"
12752
12753         # ensure gc thread is done
12754         for i in $(mdts_nodes); do
12755                 wait_update $i \
12756                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
12757                         error "$i: GC-thread not done"
12758         done
12759
12760         local first_rec
12761         for i in $(seq $MDSCOUNT); do
12762                 # check cl_user1 still registered
12763                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12765                 # check cl_user2 unregistered
12766                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12767                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12768
12769                 # check changelogs are present and starting at $user_rec1 + 1
12770                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12771                 [ -n "$user_rec1" ] ||
12772                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12773                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12774                             awk '{ print $1; exit; }')
12775
12776                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12777                 [ $((user_rec1 + 1)) == $first_rec ] ||
12778                         error "mds$i: first index should be $user_rec1 + 1, " \
12779                               "but is $first_rec"
12780         done
12781 }
12782 run_test 160g "changelog garbage collect (old users)"
12783
12784 test_160h() {
12785         remote_mds_nodsh && skip "remote MDS with nodsh" && return
12786         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
12787                 skip "Need MDS version at least 2.10.56"
12788
12789         local mdts=$(comma_list $(mdts_nodes))
12790
12791         # Create a user
12792         changelog_register || error "first changelog_register failed"
12793         changelog_register || error "second changelog_register failed"
12794         local cl_users
12795         declare -A cl_user1
12796         declare -A cl_user2
12797         local user_rec1
12798         local user_rec2
12799         local i
12800
12801         # generate some changelog records to accumulate on each MDT
12802         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
12803         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12804                 error "create $DIR/$tdir/$tfile failed"
12805
12806         # check changelogs have been generated
12807         local nbcl=$(changelog_dump | wc -l)
12808         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12809
12810         for param in "changelog_max_idle_time=10" \
12811                      "changelog_gc=1" \
12812                      "changelog_min_gc_interval=2"; do
12813                 local MDT0=$(facet_svc $SINGLEMDS)
12814                 local var="${param%=*}"
12815                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
12816
12817                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
12818                 do_nodes $mdts $LCTL set_param mdd.*.$param
12819         done
12820
12821         # force cl_user2 to be idle (1st part)
12822         sleep 9
12823
12824         for i in $(seq $MDSCOUNT); do
12825                 cl_users=(${CL_USERS[mds$i]})
12826                 cl_user1[mds$i]="${cl_users[0]}"
12827                 cl_user2[mds$i]="${cl_users[1]}"
12828
12829                 [ -n "${cl_user1[mds$i]}" ] ||
12830                         error "mds$i: no user registered"
12831                 [ -n "${cl_user2[mds$i]}" ] ||
12832                         error "mds$i: only ${cl_user2[mds$i]} is registered"
12833
12834                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12835                 [ -n "$user_rec1" ] ||
12836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12837                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
12838                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12839                 [ -n "$user_rec2" ] ||
12840                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12841                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
12842                      "$user_rec1 + 2 == $user_rec2"
12843                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
12844                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
12845                               "$user_rec1 + 2, but is $user_rec2"
12846                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
12847                 [ -n "$user_rec2" ] ||
12848                         error "mds$i: User ${cl_user2[mds$i]} not registered"
12849                 [ $user_rec1 == $user_rec2 ] ||
12850                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
12851                               "$user_rec1, but is $user_rec2"
12852         done
12853
12854         # force cl_user2 to be idle (2nd part) and to reach
12855         # changelog_max_idle_time
12856         sleep 2
12857
12858         # force each GC-thread start and block then
12859         # one per MDT/MDD, set fail_val accordingly
12860         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
12861         do_nodes $mdts $LCTL set_param fail_loc=0x1316
12862
12863         # generate more changelogs to trigger fail_loc
12864         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12865                 error "create $DIR/$tdir/${tfile}bis failed"
12866
12867         # stop MDT to stop GC-thread, should be done in back-ground as it will
12868         # block waiting for the thread to be released and exit
12869         declare -A stop_pids
12870         for i in $(seq $MDSCOUNT); do
12871                 stop mds$i &
12872                 stop_pids[mds$i]=$!
12873         done
12874
12875         for i in $(mdts_nodes); do
12876                 local facet
12877                 local nb=0
12878                 local facets=$(facets_up_on_host $i)
12879
12880                 for facet in ${facets//,/ }; do
12881                         if [[ $facet == mds* ]]; then
12882                                 nb=$((nb + 1))
12883                         fi
12884                 done
12885                 # ensure each MDS's gc threads are still present and all in "R"
12886                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
12887                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
12888                         error "$i: expected $nb GC-thread"
12889                 wait_update $i \
12890                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
12891                         "R" 20 ||
12892                         error "$i: GC-thread not found in R-state"
12893                 # check umounts of each MDT on MDS have reached kthread_stop()
12894                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
12895                         error "$i: expected $nb umount"
12896                 wait_update $i \
12897                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
12898                         error "$i: umount not found in D-state"
12899         done
12900
12901         # release all GC-threads
12902         do_nodes $mdts $LCTL set_param fail_loc=0
12903
12904         # wait for MDT stop to complete
12905         for i in $(seq $MDSCOUNT); do
12906                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
12907         done
12908
12909         # XXX
12910         # may try to check if any orphan changelog records are present
12911         # via ldiskfs/zfs and llog_reader...
12912
12913         # re-start/mount MDTs
12914         for i in $(seq $MDSCOUNT); do
12915                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
12916                         error "Fail to start mds$i"
12917         done
12918
12919         local first_rec
12920         for i in $(seq $MDSCOUNT); do
12921                 # check cl_user1 still registered
12922                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
12923                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12924                 # check cl_user2 unregistered
12925                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
12926                         error "mds$i: User ${cl_user2[mds$i]} still registered"
12927
12928                 # check changelogs are present and starting at $user_rec1 + 1
12929                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
12930                 [ -n "$user_rec1" ] ||
12931                         error "mds$i: User ${cl_user1[mds$i]} not registered"
12932                 first_rec=$($LFS changelog $(facet_svc mds$i) |
12933                             awk '{ print $1; exit; }')
12934
12935                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
12936                 [ $((user_rec1 + 1)) == $first_rec ] ||
12937                         error "mds$i: first index should be $user_rec1 + 1, " \
12938                               "but is $first_rec"
12939         done
12940 }
12941 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
12942               "during mount"
12943
12944 test_160i() {
12945
12946         local mdts=$(comma_list $(mdts_nodes))
12947
12948         changelog_register || error "first changelog_register failed"
12949
12950         # generate some changelog records to accumulate on each MDT
12951         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
12952         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
12953                 error "create $DIR/$tdir/$tfile failed"
12954
12955         # check changelogs have been generated
12956         local nbcl=$(changelog_dump | wc -l)
12957         [[ $nbcl -eq 0 ]] && error "no changelogs found"
12958
12959         # simulate race between register and unregister
12960         # XXX as fail_loc is set per-MDS, with DNE configs the race
12961         # simulation will only occur for one MDT per MDS and for the
12962         # others the normal race scenario will take place
12963         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
12964         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
12965         do_nodes $mdts $LCTL set_param fail_val=1
12966
12967         # unregister 1st user
12968         changelog_deregister &
12969         local pid1=$!
12970         # wait some time for deregister work to reach race rdv
12971         sleep 2
12972         # register 2nd user
12973         changelog_register || error "2nd user register failed"
12974
12975         wait $pid1 || error "1st user deregister failed"
12976
12977         local i
12978         local last_rec
12979         declare -A LAST_REC
12980         for i in $(seq $MDSCOUNT); do
12981                 if changelog_users mds$i | grep "^cl"; then
12982                         # make sure new records are added with one user present
12983                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
12984                                           awk '/^current.index:/ { print $NF }')
12985                 else
12986                         error "mds$i has no user registered"
12987                 fi
12988         done
12989
12990         # generate more changelog records to accumulate on each MDT
12991         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
12992                 error "create $DIR/$tdir/${tfile}bis failed"
12993
12994         for i in $(seq $MDSCOUNT); do
12995                 last_rec=$(changelog_users $SINGLEMDS |
12996                            awk '/^current.index:/ { print $NF }')
12997                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
12998                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
12999                         error "changelogs are off on mds$i"
13000         done
13001 }
13002 run_test 160i "changelog user register/unregister race"
13003
13004 test_161a() {
13005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13006
13007         test_mkdir -c1 $DIR/$tdir
13008         cp /etc/hosts $DIR/$tdir/$tfile
13009         test_mkdir -c1 $DIR/$tdir/foo1
13010         test_mkdir -c1 $DIR/$tdir/foo2
13011         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13012         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13013         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13014         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13015         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13016         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13017                 $LFS fid2path $DIR $FID
13018                 error "bad link ea"
13019         fi
13020         # middle
13021         rm $DIR/$tdir/foo2/zachary
13022         # last
13023         rm $DIR/$tdir/foo2/thor
13024         # first
13025         rm $DIR/$tdir/$tfile
13026         # rename
13027         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13028         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13029                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13030         rm $DIR/$tdir/foo2/maggie
13031
13032         # overflow the EA
13033         local longname=$tfile.avg_len_is_thirty_two_
13034         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13035                 error_noexit 'failed to unlink many hardlinks'" EXIT
13036         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13037                 error "failed to hardlink many files"
13038         links=$($LFS fid2path $DIR $FID | wc -l)
13039         echo -n "${links}/1000 links in link EA"
13040         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13041 }
13042 run_test 161a "link ea sanity"
13043
13044 test_161b() {
13045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13046         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13047
13048         local MDTIDX=1
13049         local remote_dir=$DIR/$tdir/remote_dir
13050
13051         mkdir -p $DIR/$tdir
13052         $LFS mkdir -i $MDTIDX $remote_dir ||
13053                 error "create remote directory failed"
13054
13055         cp /etc/hosts $remote_dir/$tfile
13056         mkdir -p $remote_dir/foo1
13057         mkdir -p $remote_dir/foo2
13058         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13059         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13060         ln $remote_dir/$tfile $remote_dir/foo1/luna
13061         ln $remote_dir/$tfile $remote_dir/foo2/thor
13062
13063         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13064                      tr -d ']')
13065         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13066                 $LFS fid2path $DIR $FID
13067                 error "bad link ea"
13068         fi
13069         # middle
13070         rm $remote_dir/foo2/zachary
13071         # last
13072         rm $remote_dir/foo2/thor
13073         # first
13074         rm $remote_dir/$tfile
13075         # rename
13076         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13077         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13078         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13079                 $LFS fid2path $DIR $FID
13080                 error "bad link rename"
13081         fi
13082         rm $remote_dir/foo2/maggie
13083
13084         # overflow the EA
13085         local longname=filename_avg_len_is_thirty_two_
13086         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13087                 error "failed to hardlink many files"
13088         links=$($LFS fid2path $DIR $FID | wc -l)
13089         echo -n "${links}/1000 links in link EA"
13090         [[ ${links} -gt 60 ]] ||
13091                 error "expected at least 60 links in link EA"
13092         unlinkmany $remote_dir/foo2/$longname 1000 ||
13093         error "failed to unlink many hardlinks"
13094 }
13095 run_test 161b "link ea sanity under remote directory"
13096
13097 test_161c() {
13098         remote_mds_nodsh && skip "remote MDS with nodsh"
13099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13100         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13101                 skip "Need MDS version at least 2.1.5"
13102
13103         # define CLF_RENAME_LAST 0x0001
13104         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13105         changelog_register || error "changelog_register failed"
13106
13107         rm -rf $DIR/$tdir
13108         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13109         touch $DIR/$tdir/foo_161c
13110         touch $DIR/$tdir/bar_161c
13111         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13112         changelog_dump | grep RENME | tail -n 5
13113         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13114         changelog_clear 0 || error "changelog_clear failed"
13115         if [ x$flags != "x0x1" ]; then
13116                 error "flag $flags is not 0x1"
13117         fi
13118
13119         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13120         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13121         touch $DIR/$tdir/foo_161c
13122         touch $DIR/$tdir/bar_161c
13123         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13124         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13125         changelog_dump | grep RENME | tail -n 5
13126         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13127         changelog_clear 0 || error "changelog_clear failed"
13128         if [ x$flags != "x0x0" ]; then
13129                 error "flag $flags is not 0x0"
13130         fi
13131         echo "rename overwrite a target having nlink > 1," \
13132                 "changelog record has flags of $flags"
13133
13134         # rename doesn't overwrite a target (changelog flag 0x0)
13135         touch $DIR/$tdir/foo_161c
13136         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13137         changelog_dump | grep RENME | tail -n 5
13138         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13139         changelog_clear 0 || error "changelog_clear failed"
13140         if [ x$flags != "x0x0" ]; then
13141                 error "flag $flags is not 0x0"
13142         fi
13143         echo "rename doesn't overwrite a target," \
13144                 "changelog record has flags of $flags"
13145
13146         # define CLF_UNLINK_LAST 0x0001
13147         # unlink a file having nlink = 1 (changelog flag 0x1)
13148         rm -f $DIR/$tdir/foo2_161c
13149         changelog_dump | grep UNLNK | tail -n 5
13150         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13151         changelog_clear 0 || error "changelog_clear failed"
13152         if [ x$flags != "x0x1" ]; then
13153                 error "flag $flags is not 0x1"
13154         fi
13155         echo "unlink a file having nlink = 1," \
13156                 "changelog record has flags of $flags"
13157
13158         # unlink a file having nlink > 1 (changelog flag 0x0)
13159         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13160         rm -f $DIR/$tdir/foobar_161c
13161         changelog_dump | grep UNLNK | tail -n 5
13162         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13163         changelog_clear 0 || error "changelog_clear failed"
13164         if [ x$flags != "x0x0" ]; then
13165                 error "flag $flags is not 0x0"
13166         fi
13167         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13168 }
13169 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13170
13171 test_161d() {
13172         remote_mds_nodsh && skip "remote MDS with nodsh"
13173         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13174
13175         local pid
13176         local fid
13177
13178         changelog_register || error "changelog_register failed"
13179
13180         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13181         # interfer with $MOUNT/.lustre/fid/ access
13182         mkdir $DIR/$tdir
13183         [[ $? -eq 0 ]] || error "mkdir failed"
13184
13185         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13186         $LCTL set_param fail_loc=0x8000140c
13187         # 5s pause
13188         $LCTL set_param fail_val=5
13189
13190         # create file
13191         echo foofoo > $DIR/$tdir/$tfile &
13192         pid=$!
13193
13194         # wait for create to be delayed
13195         sleep 2
13196
13197         ps -p $pid
13198         [[ $? -eq 0 ]] || error "create should be blocked"
13199
13200         local tempfile=$(mktemp)
13201         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13202         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13203         # some delay may occur during ChangeLog publishing and file read just
13204         # above, that could allow file write to happen finally
13205         [[ -s $tempfile ]] && echo "file should be empty"
13206
13207         $LCTL set_param fail_loc=0
13208
13209         wait $pid
13210         [[ $? -eq 0 ]] || error "create failed"
13211 }
13212 run_test 161d "create with concurrent .lustre/fid access"
13213
13214 check_path() {
13215         local expected="$1"
13216         shift
13217         local fid="$2"
13218
13219         local path
13220         path=$($LFS fid2path "$@")
13221         local rc=$?
13222
13223         if [ $rc -ne 0 ]; then
13224                 error "path looked up of '$expected' failed: rc=$rc"
13225         elif [ "$path" != "$expected" ]; then
13226                 error "path looked up '$path' instead of '$expected'"
13227         else
13228                 echo "FID '$fid' resolves to path '$path' as expected"
13229         fi
13230 }
13231
13232 test_162a() { # was test_162
13233         test_mkdir -p -c1 $DIR/$tdir/d2
13234         touch $DIR/$tdir/d2/$tfile
13235         touch $DIR/$tdir/d2/x1
13236         touch $DIR/$tdir/d2/x2
13237         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13238         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13239         # regular file
13240         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13241         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13242
13243         # softlink
13244         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13245         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13246         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13247
13248         # softlink to wrong file
13249         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13250         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13251         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13252
13253         # hardlink
13254         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13255         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13256         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13257         # fid2path dir/fsname should both work
13258         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13259         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13260
13261         # hardlink count: check that there are 2 links
13262         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13263         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13264
13265         # hardlink indexing: remove the first link
13266         rm $DIR/$tdir/d2/p/q/r/hlink
13267         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13268 }
13269 run_test 162a "path lookup sanity"
13270
13271 test_162b() {
13272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13274
13275         mkdir $DIR/$tdir
13276         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13277                                 error "create striped dir failed"
13278
13279         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13280                                         tail -n 1 | awk '{print $2}')
13281         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13282
13283         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13284         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13285
13286         # regular file
13287         for ((i=0;i<5;i++)); do
13288                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13289                         error "get fid for f$i failed"
13290                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13291
13292                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13293                         error "get fid for d$i failed"
13294                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13295         done
13296
13297         return 0
13298 }
13299 run_test 162b "striped directory path lookup sanity"
13300
13301 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13302 test_162c() {
13303         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13304                 skip "Need MDS version at least 2.7.51"
13305
13306         local lpath=$tdir.local
13307         local rpath=$tdir.remote
13308
13309         test_mkdir $DIR/$lpath
13310         test_mkdir $DIR/$rpath
13311
13312         for ((i = 0; i <= 101; i++)); do
13313                 lpath="$lpath/$i"
13314                 mkdir $DIR/$lpath
13315                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13316                         error "get fid for local directory $DIR/$lpath failed"
13317                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13318
13319                 rpath="$rpath/$i"
13320                 test_mkdir $DIR/$rpath
13321                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13322                         error "get fid for remote directory $DIR/$rpath failed"
13323                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13324         done
13325
13326         return 0
13327 }
13328 run_test 162c "fid2path works with paths 100 or more directories deep"
13329
13330 test_169() {
13331         # do directio so as not to populate the page cache
13332         log "creating a 10 Mb file"
13333         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13334         log "starting reads"
13335         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13336         log "truncating the file"
13337         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13338         log "killing dd"
13339         kill %+ || true # reads might have finished
13340         echo "wait until dd is finished"
13341         wait
13342         log "removing the temporary file"
13343         rm -rf $DIR/$tfile || error "tmp file removal failed"
13344 }
13345 run_test 169 "parallel read and truncate should not deadlock"
13346
13347 test_170() {
13348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13349
13350         $LCTL clear     # bug 18514
13351         $LCTL debug_daemon start $TMP/${tfile}_log_good
13352         touch $DIR/$tfile
13353         $LCTL debug_daemon stop
13354         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13355                 error "sed failed to read log_good"
13356
13357         $LCTL debug_daemon start $TMP/${tfile}_log_good
13358         rm -rf $DIR/$tfile
13359         $LCTL debug_daemon stop
13360
13361         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13362                error "lctl df log_bad failed"
13363
13364         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13365         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13366
13367         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13368         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13369
13370         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13371                 error "bad_line good_line1 good_line2 are empty"
13372
13373         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13374         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13375         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13376
13377         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13378         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13379         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13380
13381         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13382                 error "bad_line_new good_line_new are empty"
13383
13384         local expected_good=$((good_line1 + good_line2*2))
13385
13386         rm -f $TMP/${tfile}*
13387         # LU-231, short malformed line may not be counted into bad lines
13388         if [ $bad_line -ne $bad_line_new ] &&
13389                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13390                 error "expected $bad_line bad lines, but got $bad_line_new"
13391                 return 1
13392         fi
13393
13394         if [ $expected_good -ne $good_line_new ]; then
13395                 error "expected $expected_good good lines, but got $good_line_new"
13396                 return 2
13397         fi
13398         true
13399 }
13400 run_test 170 "test lctl df to handle corrupted log ====================="
13401
13402 test_171() { # bug20592
13403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13404
13405         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13406         $LCTL set_param fail_loc=0x50e
13407         $LCTL set_param fail_val=3000
13408         multiop_bg_pause $DIR/$tfile O_s || true
13409         local MULTIPID=$!
13410         kill -USR1 $MULTIPID
13411         # cause log dump
13412         sleep 3
13413         wait $MULTIPID
13414         if dmesg | grep "recursive fault"; then
13415                 error "caught a recursive fault"
13416         fi
13417         $LCTL set_param fail_loc=0
13418         true
13419 }
13420 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13421
13422 # it would be good to share it with obdfilter-survey/iokit-libecho code
13423 setup_obdecho_osc () {
13424         local rc=0
13425         local ost_nid=$1
13426         local obdfilter_name=$2
13427         echo "Creating new osc for $obdfilter_name on $ost_nid"
13428         # make sure we can find loopback nid
13429         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13430
13431         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13432                            ${obdfilter_name}_osc_UUID || rc=2; }
13433         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13434                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13435         return $rc
13436 }
13437
13438 cleanup_obdecho_osc () {
13439         local obdfilter_name=$1
13440         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13441         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13442         return 0
13443 }
13444
13445 obdecho_test() {
13446         local OBD=$1
13447         local node=$2
13448         local pages=${3:-64}
13449         local rc=0
13450         local id
13451
13452         local count=10
13453         local obd_size=$(get_obd_size $node $OBD)
13454         local page_size=$(get_page_size $node)
13455         if [[ -n "$obd_size" ]]; then
13456                 local new_count=$((obd_size / (pages * page_size / 1024)))
13457                 [[ $new_count -ge $count ]] || count=$new_count
13458         fi
13459
13460         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
13461         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
13462                            rc=2; }
13463         if [ $rc -eq 0 ]; then
13464             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
13465             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
13466         fi
13467         echo "New object id is $id"
13468         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
13469                            rc=4; }
13470         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
13471                            "test_brw $count w v $pages $id" || rc=4; }
13472         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
13473                            rc=4; }
13474         [ $rc -eq 0 -o $rc -gt 2 ] && { do_facet $node "$LCTL --device ec "    \
13475                                         "cleanup" || rc=5; }
13476         [ $rc -eq 0 -o $rc -gt 1 ] && { do_facet $node "$LCTL --device ec "    \
13477                                         "detach" || rc=6; }
13478         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
13479         return $rc
13480 }
13481
13482 test_180a() {
13483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13484
13485         if ! module_loaded obdecho; then
13486                 load_module obdecho/obdecho &&
13487                         stack_trap "rmmod obdecho" EXIT ||
13488                         error "unable to load obdecho on client"
13489         fi
13490
13491         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
13492         local host=$($LCTL get_param -n osc.$osc.import |
13493                      awk '/current_connection:/ { print $2 }' )
13494         local target=$($LCTL get_param -n osc.$osc.import |
13495                        awk '/target:/ { print $2 }' )
13496         target=${target%_UUID}
13497
13498         if [ -n "$target" ]; then
13499                 setup_obdecho_osc $host $target &&
13500                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
13501                         { error "obdecho setup failed with $?"; return; }
13502
13503                 obdecho_test ${target}_osc client ||
13504                         error "obdecho_test failed on ${target}_osc"
13505         else
13506                 $LCTL get_param osc.$osc.import
13507                 error "there is no osc.$osc.import target"
13508         fi
13509 }
13510 run_test 180a "test obdecho on osc"
13511
13512 test_180b() {
13513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13514         remote_ost_nodsh && skip "remote OST with nodsh"
13515
13516         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13517                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13518                 error "failed to load module obdecho"
13519
13520         local target=$(do_facet ost1 $LCTL dl |
13521                        awk '/obdfilter/ { print $4; exit; }')
13522
13523         if [ -n "$target" ]; then
13524                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
13525         else
13526                 do_facet ost1 $LCTL dl
13527                 error "there is no obdfilter target on ost1"
13528         fi
13529 }
13530 run_test 180b "test obdecho directly on obdfilter"
13531
13532 test_180c() { # LU-2598
13533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13534         remote_ost_nodsh && skip "remote OST with nodsh"
13535         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
13536                 skip "Need MDS version at least 2.4.0"
13537
13538         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
13539                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
13540                 error "failed to load module obdecho"
13541
13542         local target=$(do_facet ost1 $LCTL dl |
13543                        awk '/obdfilter/ { print $4; exit; }')
13544
13545         if [ -n "$target" ]; then
13546                 local pages=16384 # 64MB bulk I/O RPC size
13547
13548                 obdecho_test "$target" ost1 "$pages" ||
13549                         error "obdecho_test with pages=$pages failed with $?"
13550         else
13551                 do_facet ost1 $LCTL dl
13552                 error "there is no obdfilter target on ost1"
13553         fi
13554 }
13555 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
13556
13557 test_181() { # bug 22177
13558         test_mkdir $DIR/$tdir
13559         # create enough files to index the directory
13560         createmany -o $DIR/$tdir/foobar 4000
13561         # print attributes for debug purpose
13562         lsattr -d .
13563         # open dir
13564         multiop_bg_pause $DIR/$tdir D_Sc || return 1
13565         MULTIPID=$!
13566         # remove the files & current working dir
13567         unlinkmany $DIR/$tdir/foobar 4000
13568         rmdir $DIR/$tdir
13569         kill -USR1 $MULTIPID
13570         wait $MULTIPID
13571         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
13572         return 0
13573 }
13574 run_test 181 "Test open-unlinked dir ========================"
13575
13576 test_182() {
13577         local fcount=1000
13578         local tcount=10
13579
13580         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13581
13582         $LCTL set_param mdc.*.rpc_stats=clear
13583
13584         for (( i = 0; i < $tcount; i++ )) ; do
13585                 mkdir $DIR/$tdir/$i
13586         done
13587
13588         for (( i = 0; i < $tcount; i++ )) ; do
13589                 createmany -o $DIR/$tdir/$i/f- $fcount &
13590         done
13591         wait
13592
13593         for (( i = 0; i < $tcount; i++ )) ; do
13594                 unlinkmany $DIR/$tdir/$i/f- $fcount &
13595         done
13596         wait
13597
13598         $LCTL get_param mdc.*.rpc_stats
13599
13600         rm -rf $DIR/$tdir
13601 }
13602 run_test 182 "Test parallel modify metadata operations ================"
13603
13604 test_183() { # LU-2275
13605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13606         remote_mds_nodsh && skip "remote MDS with nodsh"
13607         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
13608                 skip "Need MDS version at least 2.3.56"
13609
13610         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13611         echo aaa > $DIR/$tdir/$tfile
13612
13613 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
13614         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
13615
13616         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
13617         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
13618
13619         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
13620
13621         # Flush negative dentry cache
13622         touch $DIR/$tdir/$tfile
13623
13624         # We are not checking for any leaked references here, they'll
13625         # become evident next time we do cleanup with module unload.
13626         rm -rf $DIR/$tdir
13627 }
13628 run_test 183 "No crash or request leak in case of strange dispositions ========"
13629
13630 # test suite 184 is for LU-2016, LU-2017
13631 test_184a() {
13632         check_swap_layouts_support
13633
13634         dir0=$DIR/$tdir/$testnum
13635         test_mkdir -p -c1 $dir0
13636         ref1=/etc/passwd
13637         ref2=/etc/group
13638         file1=$dir0/f1
13639         file2=$dir0/f2
13640         $LFS setstripe -c1 $file1
13641         cp $ref1 $file1
13642         $LFS setstripe -c2 $file2
13643         cp $ref2 $file2
13644         gen1=$($LFS getstripe -g $file1)
13645         gen2=$($LFS getstripe -g $file2)
13646
13647         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
13648         gen=$($LFS getstripe -g $file1)
13649         [[ $gen1 != $gen ]] ||
13650                 "Layout generation on $file1 does not change"
13651         gen=$($LFS getstripe -g $file2)
13652         [[ $gen2 != $gen ]] ||
13653                 "Layout generation on $file2 does not change"
13654
13655         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
13656         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
13657
13658         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
13659 }
13660 run_test 184a "Basic layout swap"
13661
13662 test_184b() {
13663         check_swap_layouts_support
13664
13665         dir0=$DIR/$tdir/$testnum
13666         mkdir -p $dir0 || error "creating dir $dir0"
13667         file1=$dir0/f1
13668         file2=$dir0/f2
13669         file3=$dir0/f3
13670         dir1=$dir0/d1
13671         dir2=$dir0/d2
13672         mkdir $dir1 $dir2
13673         $LFS setstripe -c1 $file1
13674         $LFS setstripe -c2 $file2
13675         $LFS setstripe -c1 $file3
13676         chown $RUNAS_ID $file3
13677         gen1=$($LFS getstripe -g $file1)
13678         gen2=$($LFS getstripe -g $file2)
13679
13680         $LFS swap_layouts $dir1 $dir2 &&
13681                 error "swap of directories layouts should fail"
13682         $LFS swap_layouts $dir1 $file1 &&
13683                 error "swap of directory and file layouts should fail"
13684         $RUNAS $LFS swap_layouts $file1 $file2 &&
13685                 error "swap of file we cannot write should fail"
13686         $LFS swap_layouts $file1 $file3 &&
13687                 error "swap of file with different owner should fail"
13688         /bin/true # to clear error code
13689 }
13690 run_test 184b "Forbidden layout swap (will generate errors)"
13691
13692 test_184c() {
13693         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
13694         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
13695         check_swap_layouts_support
13696
13697         local dir0=$DIR/$tdir/$testnum
13698         mkdir -p $dir0 || error "creating dir $dir0"
13699
13700         local ref1=$dir0/ref1
13701         local ref2=$dir0/ref2
13702         local file1=$dir0/file1
13703         local file2=$dir0/file2
13704         # create a file large enough for the concurrent test
13705         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
13706         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
13707         echo "ref file size: ref1($(stat -c %s $ref1))," \
13708              "ref2($(stat -c %s $ref2))"
13709
13710         cp $ref2 $file2
13711         dd if=$ref1 of=$file1 bs=16k &
13712         local DD_PID=$!
13713
13714         # Make sure dd starts to copy file
13715         while [ ! -f $file1 ]; do sleep 0.1; done
13716
13717         $LFS swap_layouts $file1 $file2
13718         local rc=$?
13719         wait $DD_PID
13720         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
13721         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
13722
13723         # how many bytes copied before swapping layout
13724         local copied=$(stat -c %s $file2)
13725         local remaining=$(stat -c %s $ref1)
13726         remaining=$((remaining - copied))
13727         echo "Copied $copied bytes before swapping layout..."
13728
13729         cmp -n $copied $file1 $ref2 | grep differ &&
13730                 error "Content mismatch [0, $copied) of ref2 and file1"
13731         cmp -n $copied $file2 $ref1 ||
13732                 error "Content mismatch [0, $copied) of ref1 and file2"
13733         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
13734                 error "Content mismatch [$copied, EOF) of ref1 and file1"
13735
13736         # clean up
13737         rm -f $ref1 $ref2 $file1 $file2
13738 }
13739 run_test 184c "Concurrent write and layout swap"
13740
13741 test_184d() {
13742         check_swap_layouts_support
13743         [ -z "$(which getfattr 2>/dev/null)" ] &&
13744                 skip_env "no getfattr command"
13745
13746         local file1=$DIR/$tdir/$tfile-1
13747         local file2=$DIR/$tdir/$tfile-2
13748         local file3=$DIR/$tdir/$tfile-3
13749         local lovea1
13750         local lovea2
13751
13752         mkdir -p $DIR/$tdir
13753         touch $file1 || error "create $file1 failed"
13754         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
13755                 error "create $file2 failed"
13756         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
13757                 error "create $file3 failed"
13758         lovea1=$(get_layout_param $file1)
13759
13760         $LFS swap_layouts $file2 $file3 ||
13761                 error "swap $file2 $file3 layouts failed"
13762         $LFS swap_layouts $file1 $file2 ||
13763                 error "swap $file1 $file2 layouts failed"
13764
13765         lovea2=$(get_layout_param $file2)
13766         echo "$lovea1"
13767         echo "$lovea2"
13768         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
13769
13770         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13771         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
13772 }
13773 run_test 184d "allow stripeless layouts swap"
13774
13775 test_184e() {
13776         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
13777                 skip "Need MDS version at least 2.6.94"
13778         check_swap_layouts_support
13779         [ -z "$(which getfattr 2>/dev/null)" ] &&
13780                 skip_env "no getfattr command"
13781
13782         local file1=$DIR/$tdir/$tfile-1
13783         local file2=$DIR/$tdir/$tfile-2
13784         local file3=$DIR/$tdir/$tfile-3
13785         local lovea
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
13794         $LFS swap_layouts $file1 $file2 ||
13795                 error "swap $file1 $file2 layouts failed"
13796
13797         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
13798         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
13799
13800         echo 123 > $file1 || error "Should be able to write into $file1"
13801
13802         $LFS swap_layouts $file1 $file3 ||
13803                 error "swap $file1 $file3 layouts failed"
13804
13805         echo 123 > $file1 || error "Should be able to write into $file1"
13806
13807         rm -rf $file1 $file2 $file3
13808 }
13809 run_test 184e "Recreate layout after stripeless layout swaps"
13810
13811 test_184f() {
13812         # Create a file with name longer than sizeof(struct stat) ==
13813         # 144 to see if we can get chars from the file name to appear
13814         # in the returned striping. Note that 'f' == 0x66.
13815         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
13816
13817         mkdir -p $DIR/$tdir
13818         mcreate $DIR/$tdir/$file
13819         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
13820                 error "IOC_MDC_GETFILEINFO returned garbage striping"
13821         fi
13822 }
13823 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
13824
13825 test_185() { # LU-2441
13826         # LU-3553 - no volatile file support in old servers
13827         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
13828                 skip "Need MDS version at least 2.3.60"
13829
13830         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
13831         touch $DIR/$tdir/spoo
13832         local mtime1=$(stat -c "%Y" $DIR/$tdir)
13833         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
13834                 error "cannot create/write a volatile file"
13835         [ "$FILESET" == "" ] &&
13836         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
13837                 error "FID is still valid after close"
13838
13839         multiop_bg_pause $DIR/$tdir vVw4096_c
13840         local multi_pid=$!
13841
13842         local OLD_IFS=$IFS
13843         IFS=":"
13844         local fidv=($fid)
13845         IFS=$OLD_IFS
13846         # assume that the next FID for this client is sequential, since stdout
13847         # is unfortunately eaten by multiop_bg_pause
13848         local n=$((${fidv[1]} + 1))
13849         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
13850         if [ "$FILESET" == "" ]; then
13851                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
13852                         error "FID is missing before close"
13853         fi
13854         kill -USR1 $multi_pid
13855         # 1 second delay, so if mtime change we will see it
13856         sleep 1
13857         local mtime2=$(stat -c "%Y" $DIR/$tdir)
13858         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
13859 }
13860 run_test 185 "Volatile file support"
13861
13862 test_187a() {
13863         remote_mds_nodsh && skip "remote MDS with nodsh"
13864         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13865                 skip "Need MDS version at least 2.3.0"
13866
13867         local dir0=$DIR/$tdir/$testnum
13868         mkdir -p $dir0 || error "creating dir $dir0"
13869
13870         local file=$dir0/file1
13871         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
13872         local dv1=$($LFS data_version $file)
13873         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
13874         local dv2=$($LFS data_version $file)
13875         [[ $dv1 != $dv2 ]] ||
13876                 error "data version did not change on write $dv1 == $dv2"
13877
13878         # clean up
13879         rm -f $file1
13880 }
13881 run_test 187a "Test data version change"
13882
13883 test_187b() {
13884         remote_mds_nodsh && skip "remote MDS with nodsh"
13885         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
13886                 skip "Need MDS version at least 2.3.0"
13887
13888         local dir0=$DIR/$tdir/$testnum
13889         mkdir -p $dir0 || error "creating dir $dir0"
13890
13891         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
13892         [[ ${DV[0]} != ${DV[1]} ]] ||
13893                 error "data version did not change on write"\
13894                       " ${DV[0]} == ${DV[1]}"
13895
13896         # clean up
13897         rm -f $file1
13898 }
13899 run_test 187b "Test data version change on volatile file"
13900
13901 test_200() {
13902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13903         remote_mgs_nodsh && skip "remote MGS with nodsh"
13904         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13905
13906         local POOL=${POOL:-cea1}
13907         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
13908         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
13909         # Pool OST targets
13910         local first_ost=0
13911         local last_ost=$(($OSTCOUNT - 1))
13912         local ost_step=2
13913         local ost_list=$(seq $first_ost $ost_step $last_ost)
13914         local ost_range="$first_ost $last_ost $ost_step"
13915         local test_path=$POOL_ROOT/$POOL_DIR_NAME
13916         local file_dir=$POOL_ROOT/file_tst
13917         local subdir=$test_path/subdir
13918         local rc=0
13919
13920         if ! combined_mgs_mds ; then
13921                 mount_mgs_client
13922         fi
13923
13924         while : ; do
13925                 # former test_200a test_200b
13926                 pool_add $POOL                          || { rc=$? ; break; }
13927                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
13928                 # former test_200c test_200d
13929                 mkdir -p $test_path
13930                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
13931                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
13932                 mkdir -p $subdir
13933                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
13934                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
13935                                                         || { rc=$? ; break; }
13936                 # former test_200e test_200f
13937                 local files=$((OSTCOUNT*3))
13938                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
13939                                                         || { rc=$? ; break; }
13940                 pool_create_files $POOL $file_dir $files "$ost_list" \
13941                                                         || { rc=$? ; break; }
13942                 # former test_200g test_200h
13943                 pool_lfs_df $POOL                       || { rc=$? ; break; }
13944                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
13945
13946                 # former test_201a test_201b test_201c
13947                 pool_remove_first_target $POOL          || { rc=$? ; break; }
13948
13949                 local f=$test_path/$tfile
13950                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
13951                 pool_remove $POOL $f                    || { rc=$? ; break; }
13952                 break
13953         done
13954
13955         destroy_test_pools
13956
13957         if ! combined_mgs_mds ; then
13958                 umount_mgs_client
13959         fi
13960         return $rc
13961 }
13962 run_test 200 "OST pools"
13963
13964 # usage: default_attr <count | size | offset>
13965 default_attr() {
13966         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
13967 }
13968
13969 # usage: check_default_stripe_attr
13970 check_default_stripe_attr() {
13971         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
13972         case $1 in
13973         --stripe-count|-c)
13974                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
13975         --stripe-size|-S)
13976                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
13977         --stripe-index|-i)
13978                 EXPECTED=-1;;
13979         *)
13980                 error "unknown getstripe attr '$1'"
13981         esac
13982
13983         [ $ACTUAL == $EXPECTED ] ||
13984                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
13985 }
13986
13987 test_204a() {
13988         test_mkdir $DIR/$tdir
13989         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
13990
13991         check_default_stripe_attr --stripe-count
13992         check_default_stripe_attr --stripe-size
13993         check_default_stripe_attr --stripe-index
13994 }
13995 run_test 204a "Print default stripe attributes"
13996
13997 test_204b() {
13998         test_mkdir $DIR/$tdir
13999         $LFS setstripe --stripe-count 1 $DIR/$tdir
14000
14001         check_default_stripe_attr --stripe-size
14002         check_default_stripe_attr --stripe-index
14003 }
14004 run_test 204b "Print default stripe size and offset"
14005
14006 test_204c() {
14007         test_mkdir $DIR/$tdir
14008         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14009
14010         check_default_stripe_attr --stripe-count
14011         check_default_stripe_attr --stripe-index
14012 }
14013 run_test 204c "Print default stripe count and offset"
14014
14015 test_204d() {
14016         test_mkdir $DIR/$tdir
14017         $LFS setstripe --stripe-index 0 $DIR/$tdir
14018
14019         check_default_stripe_attr --stripe-count
14020         check_default_stripe_attr --stripe-size
14021 }
14022 run_test 204d "Print default stripe count and size"
14023
14024 test_204e() {
14025         test_mkdir $DIR/$tdir
14026         $LFS setstripe -d $DIR/$tdir
14027
14028         check_default_stripe_attr --stripe-count --raw
14029         check_default_stripe_attr --stripe-size --raw
14030         check_default_stripe_attr --stripe-index --raw
14031 }
14032 run_test 204e "Print raw stripe attributes"
14033
14034 test_204f() {
14035         test_mkdir $DIR/$tdir
14036         $LFS setstripe --stripe-count 1 $DIR/$tdir
14037
14038         check_default_stripe_attr --stripe-size --raw
14039         check_default_stripe_attr --stripe-index --raw
14040 }
14041 run_test 204f "Print raw stripe size and offset"
14042
14043 test_204g() {
14044         test_mkdir $DIR/$tdir
14045         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14046
14047         check_default_stripe_attr --stripe-count --raw
14048         check_default_stripe_attr --stripe-index --raw
14049 }
14050 run_test 204g "Print raw stripe count and offset"
14051
14052 test_204h() {
14053         test_mkdir $DIR/$tdir
14054         $LFS setstripe --stripe-index 0 $DIR/$tdir
14055
14056         check_default_stripe_attr --stripe-count --raw
14057         check_default_stripe_attr --stripe-size --raw
14058 }
14059 run_test 204h "Print raw stripe count and size"
14060
14061 # Figure out which job scheduler is being used, if any,
14062 # or use a fake one
14063 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14064         JOBENV=SLURM_JOB_ID
14065 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14066         JOBENV=LSB_JOBID
14067 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14068         JOBENV=PBS_JOBID
14069 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14070         JOBENV=LOADL_STEP_ID
14071 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14072         JOBENV=JOB_ID
14073 else
14074         $LCTL list_param jobid_name > /dev/null 2>&1
14075         if [ $? -eq 0 ]; then
14076                 JOBENV=nodelocal
14077         else
14078                 JOBENV=FAKE_JOBID
14079         fi
14080 fi
14081 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14082
14083 verify_jobstats() {
14084         local cmd=($1)
14085         shift
14086         local facets="$@"
14087
14088 # we don't really need to clear the stats for this test to work, since each
14089 # command has a unique jobid, but it makes debugging easier if needed.
14090 #       for facet in $facets; do
14091 #               local dev=$(convert_facet2label $facet)
14092 #               # clear old jobstats
14093 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14094 #       done
14095
14096         # use a new JobID for each test, or we might see an old one
14097         [ "$JOBENV" = "FAKE_JOBID" ] &&
14098                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14099
14100         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14101
14102         [ "$JOBENV" = "nodelocal" ] && {
14103                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14104                 $LCTL set_param jobid_name=$FAKE_JOBID
14105                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14106         }
14107
14108         log "Test: ${cmd[*]}"
14109         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14110
14111         if [ $JOBENV = "FAKE_JOBID" ]; then
14112                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14113         else
14114                 ${cmd[*]}
14115         fi
14116
14117         # all files are created on OST0000
14118         for facet in $facets; do
14119                 local stats="*.$(convert_facet2label $facet).job_stats"
14120
14121                 # strip out libtool wrappers for in-tree executables
14122                 if [ $(do_facet $facet lctl get_param $stats |
14123                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14124                         do_facet $facet lctl get_param $stats
14125                         error "No jobstats for $JOBVAL found on $facet::$stats"
14126                 fi
14127         done
14128 }
14129
14130 jobstats_set() {
14131         local new_jobenv=$1
14132
14133         set_persistent_param_and_check client "jobid_var" \
14134                 "$FSNAME.sys.jobid_var" $new_jobenv
14135 }
14136
14137 test_205() { # Job stats
14138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14139         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14140                 skip "Need MDS version with at least 2.7.1"
14141         remote_mgs_nodsh && skip "remote MGS with nodsh"
14142         remote_mds_nodsh && skip "remote MDS with nodsh"
14143         remote_ost_nodsh && skip "remote OST with nodsh"
14144         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14145                 skip "Server doesn't support jobstats"
14146         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14147
14148         local old_jobenv=$($LCTL get_param -n jobid_var)
14149         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14150
14151         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14152                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14153         else
14154                 stack_trap "do_facet mgs $PERM_CMD \
14155                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14156         fi
14157         changelog_register
14158
14159         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14160                                 mdt.*.job_cleanup_interval | head -n 1)
14161         local new_interval=5
14162         do_facet $SINGLEMDS \
14163                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14164         stack_trap "do_facet $SINGLEMDS \
14165                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14166         local start=$SECONDS
14167
14168         local cmd
14169         # mkdir
14170         cmd="mkdir $DIR/$tdir"
14171         verify_jobstats "$cmd" "$SINGLEMDS"
14172         # rmdir
14173         cmd="rmdir $DIR/$tdir"
14174         verify_jobstats "$cmd" "$SINGLEMDS"
14175         # mkdir on secondary MDT
14176         if [ $MDSCOUNT -gt 1 ]; then
14177                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14178                 verify_jobstats "$cmd" "mds2"
14179         fi
14180         # mknod
14181         cmd="mknod $DIR/$tfile c 1 3"
14182         verify_jobstats "$cmd" "$SINGLEMDS"
14183         # unlink
14184         cmd="rm -f $DIR/$tfile"
14185         verify_jobstats "$cmd" "$SINGLEMDS"
14186         # create all files on OST0000 so verify_jobstats can find OST stats
14187         # open & close
14188         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14189         verify_jobstats "$cmd" "$SINGLEMDS"
14190         # setattr
14191         cmd="touch $DIR/$tfile"
14192         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14193         # write
14194         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14195         verify_jobstats "$cmd" "ost1"
14196         # read
14197         cancel_lru_locks osc
14198         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14199         verify_jobstats "$cmd" "ost1"
14200         # truncate
14201         cmd="$TRUNCATE $DIR/$tfile 0"
14202         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14203         # rename
14204         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14205         verify_jobstats "$cmd" "$SINGLEMDS"
14206         # jobstats expiry - sleep until old stats should be expired
14207         local left=$((new_interval + 5 - (SECONDS - start)))
14208         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14209                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14210                         "0" $left
14211         cmd="mkdir $DIR/$tdir.expire"
14212         verify_jobstats "$cmd" "$SINGLEMDS"
14213         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14214             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14215
14216         # Ensure that jobid are present in changelog (if supported by MDS)
14217         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14218                 changelog_dump | tail -10
14219                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14220                 [ $jobids -eq 9 ] ||
14221                         error "Wrong changelog jobid count $jobids != 9"
14222
14223                 # LU-5862
14224                 JOBENV="disable"
14225                 jobstats_set $JOBENV
14226                 touch $DIR/$tfile
14227                 changelog_dump | grep $tfile
14228                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14229                 [ $jobids -eq 0 ] ||
14230                         error "Unexpected jobids when jobid_var=$JOBENV"
14231         fi
14232
14233         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14234         JOBENV="JOBCOMPLEX"
14235         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14236
14237         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14238 }
14239 run_test 205 "Verify job stats"
14240
14241 # LU-1480, LU-1773 and LU-1657
14242 test_206() {
14243         mkdir -p $DIR/$tdir
14244         $LFS setstripe -c -1 $DIR/$tdir
14245 #define OBD_FAIL_LOV_INIT 0x1403
14246         $LCTL set_param fail_loc=0xa0001403
14247         $LCTL set_param fail_val=1
14248         touch $DIR/$tdir/$tfile || true
14249 }
14250 run_test 206 "fail lov_init_raid0() doesn't lbug"
14251
14252 test_207a() {
14253         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14254         local fsz=`stat -c %s $DIR/$tfile`
14255         cancel_lru_locks mdc
14256
14257         # do not return layout in getattr intent
14258 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14259         $LCTL set_param fail_loc=0x170
14260         local sz=`stat -c %s $DIR/$tfile`
14261
14262         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14263
14264         rm -rf $DIR/$tfile
14265 }
14266 run_test 207a "can refresh layout at glimpse"
14267
14268 test_207b() {
14269         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14270         local cksum=`md5sum $DIR/$tfile`
14271         local fsz=`stat -c %s $DIR/$tfile`
14272         cancel_lru_locks mdc
14273         cancel_lru_locks osc
14274
14275         # do not return layout in getattr intent
14276 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14277         $LCTL set_param fail_loc=0x171
14278
14279         # it will refresh layout after the file is opened but before read issues
14280         echo checksum is "$cksum"
14281         echo "$cksum" |md5sum -c --quiet || error "file differs"
14282
14283         rm -rf $DIR/$tfile
14284 }
14285 run_test 207b "can refresh layout at open"
14286
14287 test_208() {
14288         # FIXME: in this test suite, only RD lease is used. This is okay
14289         # for now as only exclusive open is supported. After generic lease
14290         # is done, this test suite should be revised. - Jinshan
14291
14292         remote_mds_nodsh && skip "remote MDS with nodsh"
14293         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14294                 skip "Need MDS version at least 2.4.52"
14295
14296         echo "==== test 1: verify get lease work"
14297         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14298
14299         echo "==== test 2: verify lease can be broken by upcoming open"
14300         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14301         local PID=$!
14302         sleep 1
14303
14304         $MULTIOP $DIR/$tfile oO_RDONLY:c
14305         kill -USR1 $PID && wait $PID || error "break lease error"
14306
14307         echo "==== test 3: verify lease can't be granted if an open already exists"
14308         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14309         local PID=$!
14310         sleep 1
14311
14312         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14313         kill -USR1 $PID && wait $PID || error "open file error"
14314
14315         echo "==== test 4: lease can sustain over recovery"
14316         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14317         PID=$!
14318         sleep 1
14319
14320         fail mds1
14321
14322         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14323
14324         echo "==== test 5: lease broken can't be regained by replay"
14325         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14326         PID=$!
14327         sleep 1
14328
14329         # open file to break lease and then recovery
14330         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14331         fail mds1
14332
14333         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14334
14335         rm -f $DIR/$tfile
14336 }
14337 run_test 208 "Exclusive open"
14338
14339 test_209() {
14340         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14341                 skip_env "must have disp_stripe"
14342
14343         touch $DIR/$tfile
14344         sync; sleep 5; sync;
14345
14346         echo 3 > /proc/sys/vm/drop_caches
14347         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14348
14349         # open/close 500 times
14350         for i in $(seq 500); do
14351                 cat $DIR/$tfile
14352         done
14353
14354         echo 3 > /proc/sys/vm/drop_caches
14355         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14356
14357         echo "before: $req_before, after: $req_after"
14358         [ $((req_after - req_before)) -ge 300 ] &&
14359                 error "open/close requests are not freed"
14360         return 0
14361 }
14362 run_test 209 "read-only open/close requests should be freed promptly"
14363
14364 test_212() {
14365         size=`date +%s`
14366         size=$((size % 8192 + 1))
14367         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14368         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14369         rm -f $DIR/f212 $DIR/f212.xyz
14370 }
14371 run_test 212 "Sendfile test ============================================"
14372
14373 test_213() {
14374         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14375         cancel_lru_locks osc
14376         lctl set_param fail_loc=0x8000040f
14377         # generate a read lock
14378         cat $DIR/$tfile > /dev/null
14379         # write to the file, it will try to cancel the above read lock.
14380         cat /etc/hosts >> $DIR/$tfile
14381 }
14382 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14383
14384 test_214() { # for bug 20133
14385         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14386         for (( i=0; i < 340; i++ )) ; do
14387                 touch $DIR/$tdir/d214c/a$i
14388         done
14389
14390         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14391         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14392         ls $DIR/d214c || error "ls $DIR/d214c failed"
14393         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14394         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14395 }
14396 run_test 214 "hash-indexed directory test - bug 20133"
14397
14398 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14399 create_lnet_proc_files() {
14400         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14401 }
14402
14403 # counterpart of create_lnet_proc_files
14404 remove_lnet_proc_files() {
14405         rm -f $TMP/lnet_$1.sys
14406 }
14407
14408 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14409 # 3rd arg as regexp for body
14410 check_lnet_proc_stats() {
14411         local l=$(cat "$TMP/lnet_$1" |wc -l)
14412         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14413
14414         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14415 }
14416
14417 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14418 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14419 # optional and can be regexp for 2nd line (lnet.routes case)
14420 check_lnet_proc_entry() {
14421         local blp=2          # blp stands for 'position of 1st line of body'
14422         [ -z "$5" ] || blp=3 # lnet.routes case
14423
14424         local l=$(cat "$TMP/lnet_$1" |wc -l)
14425         # subtracting one from $blp because the body can be empty
14426         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14427
14428         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14429                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14430
14431         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14432                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14433
14434         # bail out if any unexpected line happened
14435         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14436         [ "$?" != 0 ] || error "$2 misformatted"
14437 }
14438
14439 test_215() { # for bugs 18102, 21079, 21517
14440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14441
14442         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14443         local P='[1-9][0-9]*'           # positive numeric
14444         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14445         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14446         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14447         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14448
14449         local L1 # regexp for 1st line
14450         local L2 # regexp for 2nd line (optional)
14451         local BR # regexp for the rest (body)
14452
14453         # lnet.stats should look as 11 space-separated non-negative numerics
14454         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
14455         create_lnet_proc_files "stats"
14456         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
14457         remove_lnet_proc_files "stats"
14458
14459         # lnet.routes should look like this:
14460         # Routing disabled/enabled
14461         # net hops priority state router
14462         # where net is a string like tcp0, hops > 0, priority >= 0,
14463         # state is up/down,
14464         # router is a string like 192.168.1.1@tcp2
14465         L1="^Routing (disabled|enabled)$"
14466         L2="^net +hops +priority +state +router$"
14467         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
14468         create_lnet_proc_files "routes"
14469         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
14470         remove_lnet_proc_files "routes"
14471
14472         # lnet.routers should look like this:
14473         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
14474         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
14475         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
14476         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
14477         L1="^ref +rtr_ref +alive_cnt +state +last_ping +ping_sent +deadline +down_ni +router$"
14478         BR="^$P +$P +$N +(up|down) +$N +(0|1) +$I +$I +$NID$"
14479         create_lnet_proc_files "routers"
14480         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
14481         remove_lnet_proc_files "routers"
14482
14483         # lnet.peers should look like this:
14484         # nid refs state last max rtr min tx min queue
14485         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
14486         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
14487         # numeric (0 or >0 or <0), queue >= 0.
14488         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
14489         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
14490         create_lnet_proc_files "peers"
14491         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
14492         remove_lnet_proc_files "peers"
14493
14494         # lnet.buffers  should look like this:
14495         # pages count credits min
14496         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
14497         L1="^pages +count +credits +min$"
14498         BR="^ +$N +$N +$I +$I$"
14499         create_lnet_proc_files "buffers"
14500         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
14501         remove_lnet_proc_files "buffers"
14502
14503         # lnet.nis should look like this:
14504         # nid status alive refs peer rtr max tx min
14505         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
14506         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
14507         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
14508         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
14509         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
14510         create_lnet_proc_files "nis"
14511         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
14512         remove_lnet_proc_files "nis"
14513
14514         # can we successfully write to lnet.stats?
14515         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
14516 }
14517 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
14518
14519 test_216() { # bug 20317
14520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14521         remote_ost_nodsh && skip "remote OST with nodsh"
14522
14523         local node
14524         local facets=$(get_facets OST)
14525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14526
14527         save_lustre_params client "osc.*.contention_seconds" > $p
14528         save_lustre_params $facets \
14529                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
14530         save_lustre_params $facets \
14531                 "ldlm.namespaces.filter-*.contended_locks" >> $p
14532         save_lustre_params $facets \
14533                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
14534         clear_stats osc.*.osc_stats
14535
14536         # agressive lockless i/o settings
14537         do_nodes $(comma_list $(osts_nodes)) \
14538                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
14539                         ldlm.namespaces.filter-*.contended_locks=0 \
14540                         ldlm.namespaces.filter-*.contention_seconds=60"
14541         lctl set_param -n osc.*.contention_seconds=60
14542
14543         $DIRECTIO write $DIR/$tfile 0 10 4096
14544         $CHECKSTAT -s 40960 $DIR/$tfile
14545
14546         # disable lockless i/o
14547         do_nodes $(comma_list $(osts_nodes)) \
14548                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
14549                         ldlm.namespaces.filter-*.contended_locks=32 \
14550                         ldlm.namespaces.filter-*.contention_seconds=0"
14551         lctl set_param -n osc.*.contention_seconds=0
14552         clear_stats osc.*.osc_stats
14553
14554         dd if=/dev/zero of=$DIR/$tfile count=0
14555         $CHECKSTAT -s 0 $DIR/$tfile
14556
14557         restore_lustre_params <$p
14558         rm -f $p
14559         rm $DIR/$tfile
14560 }
14561 run_test 216 "check lockless direct write updates file size and kms correctly"
14562
14563 test_217() { # bug 22430
14564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14565
14566         local node
14567         local nid
14568
14569         for node in $(nodes_list); do
14570                 nid=$(host_nids_address $node $NETTYPE)
14571                 if [[ $nid = *-* ]] ; then
14572                         echo "lctl ping $(h2nettype $nid)"
14573                         lctl ping $(h2nettype $nid)
14574                 else
14575                         echo "skipping $node (no hyphen detected)"
14576                 fi
14577         done
14578 }
14579 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
14580
14581 test_218() {
14582        # do directio so as not to populate the page cache
14583        log "creating a 10 Mb file"
14584        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14585        log "starting reads"
14586        dd if=$DIR/$tfile of=/dev/null bs=4096 &
14587        log "truncating the file"
14588        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14589        log "killing dd"
14590        kill %+ || true # reads might have finished
14591        echo "wait until dd is finished"
14592        wait
14593        log "removing the temporary file"
14594        rm -rf $DIR/$tfile || error "tmp file removal failed"
14595 }
14596 run_test 218 "parallel read and truncate should not deadlock"
14597
14598 test_219() {
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600
14601         # write one partial page
14602         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
14603         # set no grant so vvp_io_commit_write will do sync write
14604         $LCTL set_param fail_loc=0x411
14605         # write a full page at the end of file
14606         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
14607
14608         $LCTL set_param fail_loc=0
14609         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
14610         $LCTL set_param fail_loc=0x411
14611         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
14612
14613         # LU-4201
14614         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
14615         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
14616 }
14617 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
14618
14619 test_220() { #LU-325
14620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14621         remote_ost_nodsh && skip "remote OST with nodsh"
14622         remote_mds_nodsh && skip "remote MDS with nodsh"
14623         remote_mgs_nodsh && skip "remote MGS with nodsh"
14624
14625         local OSTIDX=0
14626
14627         # create on MDT0000 so the last_id and next_id are correct
14628         mkdir $DIR/$tdir
14629         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
14630         OST=${OST%_UUID}
14631
14632         # on the mdt's osc
14633         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
14634         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
14635                         osc.$mdtosc_proc1.prealloc_last_id)
14636         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
14637                         osc.$mdtosc_proc1.prealloc_next_id)
14638
14639         $LFS df -i
14640
14641         if ! combined_mgs_mds ; then
14642                 mount_mgs_client
14643         fi
14644
14645         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
14646         #define OBD_FAIL_OST_ENOINO              0x229
14647         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
14648         create_pool $FSNAME.$TESTNAME || return 1
14649         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
14650
14651         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
14652
14653         MDSOBJS=$((last_id - next_id))
14654         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
14655
14656         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
14657         echo "OST still has $count kbytes free"
14658
14659         echo "create $MDSOBJS files @next_id..."
14660         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
14661
14662         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14663                         osc.$mdtosc_proc1.prealloc_last_id)
14664         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
14665                         osc.$mdtosc_proc1.prealloc_next_id)
14666
14667         echo "after creation, last_id=$last_id2, next_id=$next_id2"
14668         $LFS df -i
14669
14670         echo "cleanup..."
14671
14672         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
14673         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
14674
14675         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
14676                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
14677         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
14678                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
14679         echo "unlink $MDSOBJS files @$next_id..."
14680         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
14681
14682         if ! combined_mgs_mds ; then
14683                 umount_mgs_client
14684         fi
14685 }
14686 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
14687
14688 test_221() {
14689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14690
14691         dd if=`which date` of=$MOUNT/date oflag=sync
14692         chmod +x $MOUNT/date
14693
14694         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
14695         $LCTL set_param fail_loc=0x80001401
14696
14697         $MOUNT/date > /dev/null
14698         rm -f $MOUNT/date
14699 }
14700 run_test 221 "make sure fault and truncate race to not cause OOM"
14701
14702 test_222a () {
14703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14704
14705         rm -rf $DIR/$tdir
14706         test_mkdir $DIR/$tdir
14707         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14708         createmany -o $DIR/$tdir/$tfile 10
14709         cancel_lru_locks mdc
14710         cancel_lru_locks osc
14711         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14712         $LCTL set_param fail_loc=0x31a
14713         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
14714         $LCTL set_param fail_loc=0
14715         rm -r $DIR/$tdir
14716 }
14717 run_test 222a "AGL for ls should not trigger CLIO lock failure"
14718
14719 test_222b () {
14720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14721
14722         rm -rf $DIR/$tdir
14723         test_mkdir $DIR/$tdir
14724         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14725         createmany -o $DIR/$tdir/$tfile 10
14726         cancel_lru_locks mdc
14727         cancel_lru_locks osc
14728         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
14729         $LCTL set_param fail_loc=0x31a
14730         rm -r $DIR/$tdir || error "AGL for rmdir failed"
14731         $LCTL set_param fail_loc=0
14732 }
14733 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
14734
14735 test_223 () {
14736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14737
14738         rm -rf $DIR/$tdir
14739         test_mkdir $DIR/$tdir
14740         $LFS setstripe -c 1 -i 0 $DIR/$tdir
14741         createmany -o $DIR/$tdir/$tfile 10
14742         cancel_lru_locks mdc
14743         cancel_lru_locks osc
14744         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
14745         $LCTL set_param fail_loc=0x31b
14746         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
14747         $LCTL set_param fail_loc=0
14748         rm -r $DIR/$tdir
14749 }
14750 run_test 223 "osc reenqueue if without AGL lock granted ======================="
14751
14752 test_224a() { # LU-1039, MRP-303
14753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14754
14755         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
14756         $LCTL set_param fail_loc=0x508
14757         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
14758         $LCTL set_param fail_loc=0
14759         df $DIR
14760 }
14761 run_test 224a "Don't panic on bulk IO failure"
14762
14763 test_224b() { # LU-1039, MRP-303
14764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14765
14766         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
14767         cancel_lru_locks osc
14768         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
14769         $LCTL set_param fail_loc=0x515
14770         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
14771         $LCTL set_param fail_loc=0
14772         df $DIR
14773 }
14774 run_test 224b "Don't panic on bulk IO failure"
14775
14776 test_224c() { # LU-6441
14777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14778         remote_mds_nodsh && skip "remote MDS with nodsh"
14779
14780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14781         save_writethrough $p
14782         set_cache writethrough on
14783
14784         local pages_per_rpc=$($LCTL get_param \
14785                                 osc.*.max_pages_per_rpc)
14786         local at_max=$($LCTL get_param -n at_max)
14787         local timeout=$($LCTL get_param -n timeout)
14788         local test_at="at_max"
14789         local param_at="$FSNAME.sys.at_max"
14790         local test_timeout="timeout"
14791         local param_timeout="$FSNAME.sys.timeout"
14792
14793         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
14794
14795         set_persistent_param_and_check client "$test_at" "$param_at" 0
14796         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
14797
14798         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
14799         do_facet ost1 "$LCTL set_param fail_loc=0x520"
14800         $LFS setstripe -c 1 -i 0 $DIR/$tfile
14801         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
14802         sync
14803         do_facet ost1 "$LCTL set_param fail_loc=0"
14804
14805         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
14806         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
14807                 $timeout
14808
14809         $LCTL set_param -n $pages_per_rpc
14810         restore_lustre_params < $p
14811         rm -f $p
14812 }
14813 run_test 224c "Don't hang if one of md lost during large bulk RPC"
14814
14815 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
14816 test_225a () {
14817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14818         if [ -z ${MDSSURVEY} ]; then
14819                 skip_env "mds-survey not found"
14820         fi
14821         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14822                 skip "Need MDS version at least 2.2.51"
14823
14824         local mds=$(facet_host $SINGLEMDS)
14825         local target=$(do_nodes $mds 'lctl dl' |
14826                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14827
14828         local cmd1="file_count=1000 thrhi=4"
14829         local cmd2="dir_count=2 layer=mdd stripe_count=0"
14830         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14831         local cmd="$cmd1 $cmd2 $cmd3"
14832
14833         rm -f ${TMP}/mds_survey*
14834         echo + $cmd
14835         eval $cmd || error "mds-survey with zero-stripe failed"
14836         cat ${TMP}/mds_survey*
14837         rm -f ${TMP}/mds_survey*
14838 }
14839 run_test 225a "Metadata survey sanity with zero-stripe"
14840
14841 test_225b () {
14842         if [ -z ${MDSSURVEY} ]; then
14843                 skip_env "mds-survey not found"
14844         fi
14845         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
14846                 skip "Need MDS version at least 2.2.51"
14847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14848         remote_mds_nodsh && skip "remote MDS with nodsh"
14849         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
14850                 skip_env "Need to mount OST to test"
14851         fi
14852
14853         local mds=$(facet_host $SINGLEMDS)
14854         local target=$(do_nodes $mds 'lctl dl' |
14855                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
14856
14857         local cmd1="file_count=1000 thrhi=4"
14858         local cmd2="dir_count=2 layer=mdd stripe_count=1"
14859         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
14860         local cmd="$cmd1 $cmd2 $cmd3"
14861
14862         rm -f ${TMP}/mds_survey*
14863         echo + $cmd
14864         eval $cmd || error "mds-survey with stripe_count failed"
14865         cat ${TMP}/mds_survey*
14866         rm -f ${TMP}/mds_survey*
14867 }
14868 run_test 225b "Metadata survey sanity with stripe_count = 1"
14869
14870 mcreate_path2fid () {
14871         local mode=$1
14872         local major=$2
14873         local minor=$3
14874         local name=$4
14875         local desc=$5
14876         local path=$DIR/$tdir/$name
14877         local fid
14878         local rc
14879         local fid_path
14880
14881         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
14882                 error "cannot create $desc"
14883
14884         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
14885         rc=$?
14886         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
14887
14888         fid_path=$($LFS fid2path $MOUNT $fid)
14889         rc=$?
14890         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
14891
14892         [ "$path" == "$fid_path" ] ||
14893                 error "fid2path returned $fid_path, expected $path"
14894
14895         echo "pass with $path and $fid"
14896 }
14897
14898 test_226a () {
14899         rm -rf $DIR/$tdir
14900         mkdir -p $DIR/$tdir
14901
14902         mcreate_path2fid 0010666 0 0 fifo "FIFO"
14903         mcreate_path2fid 0020666 1 3 null "character special file (null)"
14904         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
14905         mcreate_path2fid 0040666 0 0 dir "directory"
14906         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
14907         mcreate_path2fid 0100666 0 0 file "regular file"
14908         mcreate_path2fid 0120666 0 0 link "symbolic link"
14909         mcreate_path2fid 0140666 0 0 sock "socket"
14910 }
14911 run_test 226a "call path2fid and fid2path on files of all type"
14912
14913 test_226b () {
14914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14915
14916         local MDTIDX=1
14917
14918         rm -rf $DIR/$tdir
14919         mkdir -p $DIR/$tdir
14920         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
14921                 error "create remote directory failed"
14922         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
14923         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
14924                                 "character special file (null)"
14925         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
14926                                 "character special file (no device)"
14927         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
14928         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
14929                                 "block special file (loop)"
14930         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
14931         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
14932         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
14933 }
14934 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
14935
14936 # LU-1299 Executing or running ldd on a truncated executable does not
14937 # cause an out-of-memory condition.
14938 test_227() {
14939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14940         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
14941
14942         dd if=$(which date) of=$MOUNT/date bs=1k count=1
14943         chmod +x $MOUNT/date
14944
14945         $MOUNT/date > /dev/null
14946         ldd $MOUNT/date > /dev/null
14947         rm -f $MOUNT/date
14948 }
14949 run_test 227 "running truncated executable does not cause OOM"
14950
14951 # LU-1512 try to reuse idle OI blocks
14952 test_228a() {
14953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14954         remote_mds_nodsh && skip "remote MDS with nodsh"
14955         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
14956
14957         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
14958         local myDIR=$DIR/$tdir
14959
14960         mkdir -p $myDIR
14961         #define OBD_FAIL_SEQ_EXHAUST             0x1002
14962         $LCTL set_param fail_loc=0x80001002
14963         createmany -o $myDIR/t- 10000
14964         $LCTL set_param fail_loc=0
14965         # The guard is current the largest FID holder
14966         touch $myDIR/guard
14967         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
14968                     tr -d '[')
14969         local IDX=$(($SEQ % 64))
14970
14971         do_facet $SINGLEMDS sync
14972         # Make sure journal flushed.
14973         sleep 6
14974         local blk1=$(do_facet $SINGLEMDS \
14975                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14976                      grep Blockcount | awk '{print $4}')
14977
14978         # Remove old files, some OI blocks will become idle.
14979         unlinkmany $myDIR/t- 10000
14980         # Create new files, idle OI blocks should be reused.
14981         createmany -o $myDIR/t- 2000
14982         do_facet $SINGLEMDS sync
14983         # Make sure journal flushed.
14984         sleep 6
14985         local blk2=$(do_facet $SINGLEMDS \
14986                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
14987                      grep Blockcount | awk '{print $4}')
14988
14989         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
14990 }
14991 run_test 228a "try to reuse idle OI blocks"
14992
14993 test_228b() {
14994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14995         remote_mds_nodsh && skip "remote MDS with nodsh"
14996         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
14997
14998         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
14999         local myDIR=$DIR/$tdir
15000
15001         mkdir -p $myDIR
15002         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15003         $LCTL set_param fail_loc=0x80001002
15004         createmany -o $myDIR/t- 10000
15005         $LCTL set_param fail_loc=0
15006         # The guard is current the largest FID holder
15007         touch $myDIR/guard
15008         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15009                     tr -d '[')
15010         local IDX=$(($SEQ % 64))
15011
15012         do_facet $SINGLEMDS sync
15013         # Make sure journal flushed.
15014         sleep 6
15015         local blk1=$(do_facet $SINGLEMDS \
15016                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15017                      grep Blockcount | awk '{print $4}')
15018
15019         # Remove old files, some OI blocks will become idle.
15020         unlinkmany $myDIR/t- 10000
15021
15022         # stop the MDT
15023         stop $SINGLEMDS || error "Fail to stop MDT."
15024         # remount the MDT
15025         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15026
15027         df $MOUNT || error "Fail to df."
15028         # Create new files, idle OI blocks should be reused.
15029         createmany -o $myDIR/t- 2000
15030         do_facet $SINGLEMDS sync
15031         # Make sure journal flushed.
15032         sleep 6
15033         local blk2=$(do_facet $SINGLEMDS \
15034                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15035                      grep Blockcount | awk '{print $4}')
15036
15037         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15038 }
15039 run_test 228b "idle OI blocks can be reused after MDT restart"
15040
15041 #LU-1881
15042 test_228c() {
15043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15044         remote_mds_nodsh && skip "remote MDS with nodsh"
15045         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15046
15047         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15048         local myDIR=$DIR/$tdir
15049
15050         mkdir -p $myDIR
15051         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15052         $LCTL set_param fail_loc=0x80001002
15053         # 20000 files can guarantee there are index nodes in the OI file
15054         createmany -o $myDIR/t- 20000
15055         $LCTL set_param fail_loc=0
15056         # The guard is current the largest FID holder
15057         touch $myDIR/guard
15058         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15059                     tr -d '[')
15060         local IDX=$(($SEQ % 64))
15061
15062         do_facet $SINGLEMDS sync
15063         # Make sure journal flushed.
15064         sleep 6
15065         local blk1=$(do_facet $SINGLEMDS \
15066                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15067                      grep Blockcount | awk '{print $4}')
15068
15069         # Remove old files, some OI blocks will become idle.
15070         unlinkmany $myDIR/t- 20000
15071         rm -f $myDIR/guard
15072         # The OI file should become empty now
15073
15074         # Create new files, idle OI blocks should be reused.
15075         createmany -o $myDIR/t- 2000
15076         do_facet $SINGLEMDS sync
15077         # Make sure journal flushed.
15078         sleep 6
15079         local blk2=$(do_facet $SINGLEMDS \
15080                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15081                      grep Blockcount | awk '{print $4}')
15082
15083         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15084 }
15085 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15086
15087 test_229() { # LU-2482, LU-3448
15088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15089         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15090         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15091                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15092
15093         rm -f $DIR/$tfile
15094
15095         # Create a file with a released layout and stripe count 2.
15096         $MULTIOP $DIR/$tfile H2c ||
15097                 error "failed to create file with released layout"
15098
15099         $LFS getstripe -v $DIR/$tfile
15100
15101         local pattern=$($LFS getstripe -L $DIR/$tfile)
15102         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15103
15104         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15105                 error "getstripe"
15106         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15107         stat $DIR/$tfile || error "failed to stat released file"
15108
15109         chown $RUNAS_ID $DIR/$tfile ||
15110                 error "chown $RUNAS_ID $DIR/$tfile failed"
15111
15112         chgrp $RUNAS_ID $DIR/$tfile ||
15113                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15114
15115         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15116         rm $DIR/$tfile || error "failed to remove released file"
15117 }
15118 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15119
15120 test_230a() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15123         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15124                 skip "Need MDS version at least 2.11.52"
15125
15126         local MDTIDX=1
15127
15128         test_mkdir $DIR/$tdir
15129         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15130         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15131         [ $mdt_idx -ne 0 ] &&
15132                 error "create local directory on wrong MDT $mdt_idx"
15133
15134         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15135                         error "create remote directory failed"
15136         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15137         [ $mdt_idx -ne $MDTIDX ] &&
15138                 error "create remote directory on wrong MDT $mdt_idx"
15139
15140         createmany -o $DIR/$tdir/test_230/t- 10 ||
15141                 error "create files on remote directory failed"
15142         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15143         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15144         rm -r $DIR/$tdir || error "unlink remote directory failed"
15145 }
15146 run_test 230a "Create remote directory and files under the remote directory"
15147
15148 test_230b() {
15149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15151         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15152                 skip "Need MDS version at least 2.11.52"
15153
15154         local MDTIDX=1
15155         local mdt_index
15156         local i
15157         local file
15158         local pid
15159         local stripe_count
15160         local migrate_dir=$DIR/$tdir/migrate_dir
15161         local other_dir=$DIR/$tdir/other_dir
15162
15163         test_mkdir $DIR/$tdir
15164         test_mkdir -i0 -c1 $migrate_dir
15165         test_mkdir -i0 -c1 $other_dir
15166         for ((i=0; i<10; i++)); do
15167                 mkdir -p $migrate_dir/dir_${i}
15168                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15169                         error "create files under remote dir failed $i"
15170         done
15171
15172         cp /etc/passwd $migrate_dir/$tfile
15173         cp /etc/passwd $other_dir/$tfile
15174         chattr +SAD $migrate_dir
15175         chattr +SAD $migrate_dir/$tfile
15176
15177         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15178         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15179         local old_dir_mode=$(stat -c%f $migrate_dir)
15180         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15181
15182         mkdir -p $migrate_dir/dir_default_stripe2
15183         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15184         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15185
15186         mkdir -p $other_dir
15187         ln $migrate_dir/$tfile $other_dir/luna
15188         ln $migrate_dir/$tfile $migrate_dir/sofia
15189         ln $other_dir/$tfile $migrate_dir/david
15190         ln -s $migrate_dir/$tfile $other_dir/zachary
15191         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15192         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15193
15194         $LFS migrate -m $MDTIDX $migrate_dir ||
15195                 error "fails on migrating remote dir to MDT1"
15196
15197         echo "migratate to MDT1, then checking.."
15198         for ((i = 0; i < 10; i++)); do
15199                 for file in $(find $migrate_dir/dir_${i}); do
15200                         mdt_index=$($LFS getstripe -m $file)
15201                         [ $mdt_index == $MDTIDX ] ||
15202                                 error "$file is not on MDT${MDTIDX}"
15203                 done
15204         done
15205
15206         # the multiple link file should still in MDT0
15207         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15208         [ $mdt_index == 0 ] ||
15209                 error "$file is not on MDT${MDTIDX}"
15210
15211         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15212         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15213                 error " expect $old_dir_flag get $new_dir_flag"
15214
15215         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15216         [ "$old_file_flag" = "$new_file_flag" ] ||
15217                 error " expect $old_file_flag get $new_file_flag"
15218
15219         local new_dir_mode=$(stat -c%f $migrate_dir)
15220         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15221                 error "expect mode $old_dir_mode get $new_dir_mode"
15222
15223         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15224         [ "$old_file_mode" = "$new_file_mode" ] ||
15225                 error "expect mode $old_file_mode get $new_file_mode"
15226
15227         diff /etc/passwd $migrate_dir/$tfile ||
15228                 error "$tfile different after migration"
15229
15230         diff /etc/passwd $other_dir/luna ||
15231                 error "luna different after migration"
15232
15233         diff /etc/passwd $migrate_dir/sofia ||
15234                 error "sofia different after migration"
15235
15236         diff /etc/passwd $migrate_dir/david ||
15237                 error "david different after migration"
15238
15239         diff /etc/passwd $other_dir/zachary ||
15240                 error "zachary different after migration"
15241
15242         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15243                 error "${tfile}_ln different after migration"
15244
15245         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15246                 error "${tfile}_ln_other different after migration"
15247
15248         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15249         [ $stripe_count = 2 ] ||
15250                 error "dir strpe_count $d != 2 after migration."
15251
15252         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15253         [ $stripe_count = 2 ] ||
15254                 error "file strpe_count $d != 2 after migration."
15255
15256         #migrate back to MDT0
15257         MDTIDX=0
15258
15259         $LFS migrate -m $MDTIDX $migrate_dir ||
15260                 error "fails on migrating remote dir to MDT0"
15261
15262         echo "migrate back to MDT0, checking.."
15263         for file in $(find $migrate_dir); do
15264                 mdt_index=$($LFS getstripe -m $file)
15265                 [ $mdt_index == $MDTIDX ] ||
15266                         error "$file is not on MDT${MDTIDX}"
15267         done
15268
15269         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15270         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15271                 error " expect $old_dir_flag get $new_dir_flag"
15272
15273         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15274         [ "$old_file_flag" = "$new_file_flag" ] ||
15275                 error " expect $old_file_flag get $new_file_flag"
15276
15277         local new_dir_mode=$(stat -c%f $migrate_dir)
15278         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15279                 error "expect mode $old_dir_mode get $new_dir_mode"
15280
15281         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15282         [ "$old_file_mode" = "$new_file_mode" ] ||
15283                 error "expect mode $old_file_mode get $new_file_mode"
15284
15285         diff /etc/passwd ${migrate_dir}/$tfile ||
15286                 error "$tfile different after migration"
15287
15288         diff /etc/passwd ${other_dir}/luna ||
15289                 error "luna different after migration"
15290
15291         diff /etc/passwd ${migrate_dir}/sofia ||
15292                 error "sofia different after migration"
15293
15294         diff /etc/passwd ${other_dir}/zachary ||
15295                 error "zachary different after migration"
15296
15297         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15298                 error "${tfile}_ln different after migration"
15299
15300         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15301                 error "${tfile}_ln_other different after migration"
15302
15303         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15304         [ $stripe_count = 2 ] ||
15305                 error "dir strpe_count $d != 2 after migration."
15306
15307         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15308         [ $stripe_count = 2 ] ||
15309                 error "file strpe_count $d != 2 after migration."
15310
15311         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15312 }
15313 run_test 230b "migrate directory"
15314
15315 test_230c() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15318         remote_mds_nodsh && skip "remote MDS with nodsh"
15319         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15320                 skip "Need MDS version at least 2.11.52"
15321
15322         local MDTIDX=1
15323         local total=3
15324         local mdt_index
15325         local file
15326         local migrate_dir=$DIR/$tdir/migrate_dir
15327
15328         #If migrating directory fails in the middle, all entries of
15329         #the directory is still accessiable.
15330         test_mkdir $DIR/$tdir
15331         test_mkdir -i0 -c1 $migrate_dir
15332         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15333         stat $migrate_dir
15334         createmany -o $migrate_dir/f $total ||
15335                 error "create files under ${migrate_dir} failed"
15336
15337         # fail after migrating top dir, and this will fail only once, so the
15338         # first sub file migration will fail (currently f3), others succeed.
15339         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15340         do_facet mds1 lctl set_param fail_loc=0x1801
15341         local t=$(ls $migrate_dir | wc -l)
15342         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15343                 error "migrate should fail"
15344         local u=$(ls $migrate_dir | wc -l)
15345         [ "$u" == "$t" ] || error "$u != $t during migration"
15346
15347         # add new dir/file should succeed
15348         mkdir $migrate_dir/dir ||
15349                 error "mkdir failed under migrating directory"
15350         touch $migrate_dir/file ||
15351                 error "create file failed under migrating directory"
15352
15353         # add file with existing name should fail
15354         for file in $migrate_dir/f*; do
15355                 stat $file > /dev/null || error "stat $file failed"
15356                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15357                         error "open(O_CREAT|O_EXCL) $file should fail"
15358                 $MULTIOP $file m && error "create $file should fail"
15359                 touch $DIR/$tdir/remote_dir/$tfile ||
15360                         error "touch $tfile failed"
15361                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15362                         error "link $file should fail"
15363                 mdt_index=$($LFS getstripe -m $file)
15364                 if [ $mdt_index == 0 ]; then
15365                         # file failed to migrate is not allowed to rename to
15366                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15367                                 error "rename to $file should fail"
15368                 else
15369                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15370                                 error "rename to $file failed"
15371                 fi
15372                 echo hello >> $file || error "write $file failed"
15373         done
15374
15375         # resume migration with different options should fail
15376         $LFS migrate -m 0 $migrate_dir &&
15377                 error "migrate -m 0 $migrate_dir should fail"
15378
15379         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15380                 error "migrate -c 2 $migrate_dir should fail"
15381
15382         # resume migration should succeed
15383         $LFS migrate -m $MDTIDX $migrate_dir ||
15384                 error "migrate $migrate_dir failed"
15385
15386         echo "Finish migration, then checking.."
15387         for file in $(find $migrate_dir); do
15388                 mdt_index=$($LFS getstripe -m $file)
15389                 [ $mdt_index == $MDTIDX ] ||
15390                         error "$file is not on MDT${MDTIDX}"
15391         done
15392
15393         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15394 }
15395 run_test 230c "check directory accessiblity if migration failed"
15396
15397 test_230d() {
15398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15400         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15401                 skip "Need MDS version at least 2.11.52"
15402         # LU-11235
15403         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15404
15405         local migrate_dir=$DIR/$tdir/migrate_dir
15406         local old_index
15407         local new_index
15408         local old_count
15409         local new_count
15410         local new_hash
15411         local mdt_index
15412         local i
15413         local j
15414
15415         old_index=$((RANDOM % MDSCOUNT))
15416         old_count=$((MDSCOUNT - old_index))
15417         new_index=$((RANDOM % MDSCOUNT))
15418         new_count=$((MDSCOUNT - new_index))
15419         new_hash="all_char"
15420
15421         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15422         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15423
15424         test_mkdir $DIR/$tdir
15425         test_mkdir -i $old_index -c $old_count $migrate_dir
15426
15427         for ((i=0; i<100; i++)); do
15428                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15429                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15430                         error "create files under remote dir failed $i"
15431         done
15432
15433         echo -n "Migrate from MDT$old_index "
15434         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15435         echo -n "to MDT$new_index"
15436         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15437         echo
15438
15439         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15440         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15441                 error "migrate remote dir error"
15442
15443         echo "Finish migration, then checking.."
15444         for file in $(find $migrate_dir); do
15445                 mdt_index=$($LFS getstripe -m $file)
15446                 if [ $mdt_index -lt $new_index ] ||
15447                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15448                         error "$file is on MDT$mdt_index"
15449                 fi
15450         done
15451
15452         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15453 }
15454 run_test 230d "check migrate big directory"
15455
15456 test_230e() {
15457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15459         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15460                 skip "Need MDS version at least 2.11.52"
15461
15462         local i
15463         local j
15464         local a_fid
15465         local b_fid
15466
15467         mkdir -p $DIR/$tdir
15468         mkdir $DIR/$tdir/migrate_dir
15469         mkdir $DIR/$tdir/other_dir
15470         touch $DIR/$tdir/migrate_dir/a
15471         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
15472         ls $DIR/$tdir/other_dir
15473
15474         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15475                 error "migrate dir fails"
15476
15477         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15478         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15479
15480         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15481         [ $mdt_index == 0 ] || error "a is not on MDT0"
15482
15483         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
15484                 error "migrate dir fails"
15485
15486         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
15487         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
15488
15489         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15490         [ $mdt_index == 1 ] || error "a is not on MDT1"
15491
15492         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
15493         [ $mdt_index == 1 ] || error "b is not on MDT1"
15494
15495         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15496         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
15497
15498         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
15499
15500         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15501 }
15502 run_test 230e "migrate mulitple local link files"
15503
15504 test_230f() {
15505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15507         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15508                 skip "Need MDS version at least 2.11.52"
15509
15510         local a_fid
15511         local ln_fid
15512
15513         mkdir -p $DIR/$tdir
15514         mkdir $DIR/$tdir/migrate_dir
15515         $LFS mkdir -i1 $DIR/$tdir/other_dir
15516         touch $DIR/$tdir/migrate_dir/a
15517         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
15518         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
15519         ls $DIR/$tdir/other_dir
15520
15521         # a should be migrated to MDT1, since no other links on MDT0
15522         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15523                 error "#1 migrate dir fails"
15524         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
15525         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
15526         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15527         [ $mdt_index == 1 ] || error "a is not on MDT1"
15528
15529         # a should stay on MDT1, because it is a mulitple link file
15530         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15531                 error "#2 migrate dir fails"
15532         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15533         [ $mdt_index == 1 ] || error "a is not on MDT1"
15534
15535         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
15536                 error "#3 migrate dir fails"
15537
15538         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
15539         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
15540         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
15541
15542         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
15543         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
15544
15545         # a should be migrated to MDT0, since no other links on MDT1
15546         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
15547                 error "#4 migrate dir fails"
15548         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
15549         [ $mdt_index == 0 ] || error "a is not on MDT0"
15550
15551         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15552 }
15553 run_test 230f "migrate mulitple remote link files"
15554
15555 test_230g() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15558         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15559                 skip "Need MDS version at least 2.11.52"
15560
15561         mkdir -p $DIR/$tdir/migrate_dir
15562
15563         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
15564                 error "migrating dir to non-exist MDT succeeds"
15565         true
15566 }
15567 run_test 230g "migrate dir to non-exist MDT"
15568
15569 test_230h() {
15570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15572         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15573                 skip "Need MDS version at least 2.11.52"
15574
15575         local mdt_index
15576
15577         mkdir -p $DIR/$tdir/migrate_dir
15578
15579         $LFS migrate -m1 $DIR &&
15580                 error "migrating mountpoint1 should fail"
15581
15582         $LFS migrate -m1 $DIR/$tdir/.. &&
15583                 error "migrating mountpoint2 should fail"
15584
15585         # same as mv
15586         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
15587                 error "migrating $tdir/migrate_dir/.. should fail"
15588
15589         true
15590 }
15591 run_test 230h "migrate .. and root"
15592
15593 test_230i() {
15594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15596         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15597                 skip "Need MDS version at least 2.11.52"
15598
15599         mkdir -p $DIR/$tdir/migrate_dir
15600
15601         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
15602                 error "migration fails with a tailing slash"
15603
15604         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
15605                 error "migration fails with two tailing slashes"
15606 }
15607 run_test 230i "lfs migrate -m tolerates trailing slashes"
15608
15609 test_230j() {
15610         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15611         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15612                 skip "Need MDS version at least 2.11.52"
15613
15614         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
15615         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
15616                 error "create $tfile failed"
15617         cat /etc/passwd > $DIR/$tdir/$tfile
15618
15619         $LFS migrate -m 1 $DIR/$tdir
15620
15621         cmp /etc/passwd $DIR/$tdir/$tfile ||
15622                 error "DoM file mismatch after migration"
15623 }
15624 run_test 230j "DoM file data not changed after dir migration"
15625
15626 test_230k() {
15627         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
15628         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15629                 skip "Need MDS version at least 2.11.56"
15630
15631         local total=20
15632         local files_on_starting_mdt=0
15633
15634         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
15635         $LFS getdirstripe $DIR/$tdir
15636         for i in $(seq $total); do
15637                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
15638                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15639                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15640         done
15641
15642         echo "$files_on_starting_mdt files on MDT0"
15643
15644         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
15645         $LFS getdirstripe $DIR/$tdir
15646
15647         files_on_starting_mdt=0
15648         for i in $(seq $total); do
15649                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15650                         error "file $tfile.$i mismatch after migration"
15651                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
15652                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15653         done
15654
15655         echo "$files_on_starting_mdt files on MDT1 after migration"
15656         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
15657
15658         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
15659         $LFS getdirstripe $DIR/$tdir
15660
15661         files_on_starting_mdt=0
15662         for i in $(seq $total); do
15663                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
15664                         error "file $tfile.$i mismatch after 2nd migration"
15665                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
15666                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
15667         done
15668
15669         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
15670         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
15671
15672         true
15673 }
15674 run_test 230k "file data not changed after dir migration"
15675
15676 test_230l() {
15677         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
15678         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
15679                 skip "Need MDS version at least 2.11.56"
15680
15681         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
15682         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
15683                 error "create files under remote dir failed $i"
15684         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
15685 }
15686 run_test 230l "readdir between MDTs won't crash"
15687
15688 test_231a()
15689 {
15690         # For simplicity this test assumes that max_pages_per_rpc
15691         # is the same across all OSCs
15692         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
15693         local bulk_size=$((max_pages * PAGE_SIZE))
15694         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
15695                                        head -n 1)
15696
15697         mkdir -p $DIR/$tdir
15698         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
15699                 error "failed to set stripe with -S ${brw_size}M option"
15700
15701         # clear the OSC stats
15702         $LCTL set_param osc.*.stats=0 &>/dev/null
15703         stop_writeback
15704
15705         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
15706         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
15707                 oflag=direct &>/dev/null || error "dd failed"
15708
15709         sync; sleep 1; sync # just to be safe
15710         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
15711         if [ x$nrpcs != "x1" ]; then
15712                 $LCTL get_param osc.*.stats
15713                 error "found $nrpcs ost_write RPCs, not 1 as expected"
15714         fi
15715
15716         start_writeback
15717         # Drop the OSC cache, otherwise we will read from it
15718         cancel_lru_locks osc
15719
15720         # clear the OSC stats
15721         $LCTL set_param osc.*.stats=0 &>/dev/null
15722
15723         # Client reads $bulk_size.
15724         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
15725                 iflag=direct &>/dev/null || error "dd failed"
15726
15727         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
15728         if [ x$nrpcs != "x1" ]; then
15729                 $LCTL get_param osc.*.stats
15730                 error "found $nrpcs ost_read RPCs, not 1 as expected"
15731         fi
15732 }
15733 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
15734
15735 test_231b() {
15736         mkdir -p $DIR/$tdir
15737         local i
15738         for i in {0..1023}; do
15739                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
15740                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
15741                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
15742         done
15743         sync
15744 }
15745 run_test 231b "must not assert on fully utilized OST request buffer"
15746
15747 test_232a() {
15748         mkdir -p $DIR/$tdir
15749         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15750
15751         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15752         do_facet ost1 $LCTL set_param fail_loc=0x31c
15753
15754         # ignore dd failure
15755         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
15756
15757         do_facet ost1 $LCTL set_param fail_loc=0
15758         umount_client $MOUNT || error "umount failed"
15759         mount_client $MOUNT || error "mount failed"
15760         stop ost1 || error "cannot stop ost1"
15761         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15762 }
15763 run_test 232a "failed lock should not block umount"
15764
15765 test_232b() {
15766         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
15767                 skip "Need MDS version at least 2.10.58"
15768
15769         mkdir -p $DIR/$tdir
15770         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
15771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
15772         sync
15773         cancel_lru_locks osc
15774
15775         #define OBD_FAIL_LDLM_OST_LVB            0x31c
15776         do_facet ost1 $LCTL set_param fail_loc=0x31c
15777
15778         # ignore failure
15779         $LFS data_version $DIR/$tdir/$tfile || true
15780
15781         do_facet ost1 $LCTL set_param fail_loc=0
15782         umount_client $MOUNT || error "umount failed"
15783         mount_client $MOUNT || error "mount failed"
15784         stop ost1 || error "cannot stop ost1"
15785         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
15786 }
15787 run_test 232b "failed data version lock should not block umount"
15788
15789 test_233a() {
15790         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
15791                 skip "Need MDS version at least 2.3.64"
15792         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15793
15794         local fid=$($LFS path2fid $MOUNT)
15795
15796         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15797                 error "cannot access $MOUNT using its FID '$fid'"
15798 }
15799 run_test 233a "checking that OBF of the FS root succeeds"
15800
15801 test_233b() {
15802         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
15803                 skip "Need MDS version at least 2.5.90"
15804         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
15805
15806         local fid=$($LFS path2fid $MOUNT/.lustre)
15807
15808         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15809                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
15810
15811         fid=$($LFS path2fid $MOUNT/.lustre/fid)
15812         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
15813                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
15814 }
15815 run_test 233b "checking that OBF of the FS .lustre succeeds"
15816
15817 test_234() {
15818         local p="$TMP/sanityN-$TESTNAME.parameters"
15819         save_lustre_params client "llite.*.xattr_cache" > $p
15820         lctl set_param llite.*.xattr_cache 1 ||
15821                 skip_env "xattr cache is not supported"
15822
15823         mkdir -p $DIR/$tdir || error "mkdir failed"
15824         touch $DIR/$tdir/$tfile || error "touch failed"
15825         # OBD_FAIL_LLITE_XATTR_ENOMEM
15826         $LCTL set_param fail_loc=0x1405
15827         getfattr -n user.attr $DIR/$tdir/$tfile &&
15828                 error "getfattr should have failed with ENOMEM"
15829         $LCTL set_param fail_loc=0x0
15830         rm -rf $DIR/$tdir
15831
15832         restore_lustre_params < $p
15833         rm -f $p
15834 }
15835 run_test 234 "xattr cache should not crash on ENOMEM"
15836
15837 test_235() {
15838         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
15839                 skip "Need MDS version at least 2.4.52"
15840
15841         flock_deadlock $DIR/$tfile
15842         local RC=$?
15843         case $RC in
15844                 0)
15845                 ;;
15846                 124) error "process hangs on a deadlock"
15847                 ;;
15848                 *) error "error executing flock_deadlock $DIR/$tfile"
15849                 ;;
15850         esac
15851 }
15852 run_test 235 "LU-1715: flock deadlock detection does not work properly"
15853
15854 #LU-2935
15855 test_236() {
15856         check_swap_layouts_support
15857
15858         local ref1=/etc/passwd
15859         local ref2=/etc/group
15860         local file1=$DIR/$tdir/f1
15861         local file2=$DIR/$tdir/f2
15862
15863         test_mkdir -c1 $DIR/$tdir
15864         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
15865         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
15866         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
15867         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
15868         local fd=$(free_fd)
15869         local cmd="exec $fd<>$file2"
15870         eval $cmd
15871         rm $file2
15872         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
15873                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
15874         cmd="exec $fd>&-"
15875         eval $cmd
15876         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15877
15878         #cleanup
15879         rm -rf $DIR/$tdir
15880 }
15881 run_test 236 "Layout swap on open unlinked file"
15882
15883 # LU-4659 linkea consistency
15884 test_238() {
15885         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15886                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15887                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15888                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15889
15890         touch $DIR/$tfile
15891         ln $DIR/$tfile $DIR/$tfile.lnk
15892         touch $DIR/$tfile.new
15893         mv $DIR/$tfile.new $DIR/$tfile
15894         local fid1=$($LFS path2fid $DIR/$tfile)
15895         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
15896         local path1=$($LFS fid2path $FSNAME "$fid1")
15897         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
15898         local path2=$($LFS fid2path $FSNAME "$fid2")
15899         [ $tfile.lnk == $path2 ] ||
15900                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
15901         rm -f $DIR/$tfile*
15902 }
15903 run_test 238 "Verify linkea consistency"
15904
15905 test_239A() { # was test_239
15906         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
15907                 skip "Need MDS version at least 2.5.60"
15908
15909         local list=$(comma_list $(mdts_nodes))
15910
15911         mkdir -p $DIR/$tdir
15912         createmany -o $DIR/$tdir/f- 5000
15913         unlinkmany $DIR/$tdir/f- 5000
15914         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
15915                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
15916         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
15917                         osp.*MDT*.sync_in_flight" | calc_sum)
15918         [ "$changes" -eq 0 ] || error "$changes not synced"
15919 }
15920 run_test 239A "osp_sync test"
15921
15922 test_239a() { #LU-5297
15923         remote_mds_nodsh && skip "remote MDS with nodsh"
15924
15925         touch $DIR/$tfile
15926         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
15927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
15928         chgrp $RUNAS_GID $DIR/$tfile
15929         wait_delete_completed
15930 }
15931 run_test 239a "process invalid osp sync record correctly"
15932
15933 test_239b() { #LU-5297
15934         remote_mds_nodsh && skip "remote MDS with nodsh"
15935
15936         touch $DIR/$tfile1
15937         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
15938         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
15939         chgrp $RUNAS_GID $DIR/$tfile1
15940         wait_delete_completed
15941         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15942         touch $DIR/$tfile2
15943         chgrp $RUNAS_GID $DIR/$tfile2
15944         wait_delete_completed
15945 }
15946 run_test 239b "process osp sync record with ENOMEM error correctly"
15947
15948 test_240() {
15949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15950         remote_mds_nodsh && skip "remote MDS with nodsh"
15951
15952         mkdir -p $DIR/$tdir
15953
15954         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
15955                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
15956         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
15957                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
15958
15959         umount_client $MOUNT || error "umount failed"
15960         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
15961         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
15962         mount_client $MOUNT || error "failed to mount client"
15963
15964         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
15965         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
15966 }
15967 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
15968
15969 test_241_bio() {
15970         local count=$1
15971         local bsize=$2
15972
15973         for LOOP in $(seq $count); do
15974                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
15975                 cancel_lru_locks $OSC || true
15976         done
15977 }
15978
15979 test_241_dio() {
15980         local count=$1
15981         local bsize=$2
15982
15983         for LOOP in $(seq $1); do
15984                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
15985                         2>/dev/null
15986         done
15987 }
15988
15989 test_241a() { # was test_241
15990         local bsize=$PAGE_SIZE
15991
15992         (( bsize < 40960 )) && bsize=40960
15993         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
15994         ls -la $DIR/$tfile
15995         cancel_lru_locks $OSC
15996         test_241_bio 1000 $bsize &
15997         PID=$!
15998         test_241_dio 1000 $bsize
15999         wait $PID
16000 }
16001 run_test 241a "bio vs dio"
16002
16003 test_241b() {
16004         local bsize=$PAGE_SIZE
16005
16006         (( bsize < 40960 )) && bsize=40960
16007         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16008         ls -la $DIR/$tfile
16009         test_241_dio 1000 $bsize &
16010         PID=$!
16011         test_241_dio 1000 $bsize
16012         wait $PID
16013 }
16014 run_test 241b "dio vs dio"
16015
16016 test_242() {
16017         remote_mds_nodsh && skip "remote MDS with nodsh"
16018
16019         mkdir -p $DIR/$tdir
16020         touch $DIR/$tdir/$tfile
16021
16022         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16023         do_facet mds1 lctl set_param fail_loc=0x105
16024         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16025
16026         do_facet mds1 lctl set_param fail_loc=0
16027         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16028 }
16029 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16030
16031 test_243()
16032 {
16033         test_mkdir $DIR/$tdir
16034         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16035 }
16036 run_test 243 "various group lock tests"
16037
16038 test_244()
16039 {
16040         test_mkdir $DIR/$tdir
16041         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16042         sendfile_grouplock $DIR/$tdir/$tfile || \
16043                 error "sendfile+grouplock failed"
16044         rm -rf $DIR/$tdir
16045 }
16046 run_test 244 "sendfile with group lock tests"
16047
16048 test_245() {
16049         local flagname="multi_mod_rpcs"
16050         local connect_data_name="max_mod_rpcs"
16051         local out
16052
16053         # check if multiple modify RPCs flag is set
16054         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16055                 grep "connect_flags:")
16056         echo "$out"
16057
16058         echo "$out" | grep -qw $flagname
16059         if [ $? -ne 0 ]; then
16060                 echo "connect flag $flagname is not set"
16061                 return
16062         fi
16063
16064         # check if multiple modify RPCs data is set
16065         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16066         echo "$out"
16067
16068         echo "$out" | grep -qw $connect_data_name ||
16069                 error "import should have connect data $connect_data_name"
16070 }
16071 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16072
16073 test_246() { # LU-7371
16074         remote_ost_nodsh && skip "remote OST with nodsh"
16075         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16076                 skip "Need OST version >= 2.7.62"
16077
16078         do_facet ost1 $LCTL set_param fail_val=4095
16079 #define OBD_FAIL_OST_READ_SIZE          0x234
16080         do_facet ost1 $LCTL set_param fail_loc=0x234
16081         $LFS setstripe $DIR/$tfile -i 0 -c 1
16082         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16083         cancel_lru_locks $FSNAME-OST0000
16084         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16085 }
16086 run_test 246 "Read file of size 4095 should return right length"
16087
16088 cleanup_247() {
16089         local submount=$1
16090
16091         trap 0
16092         umount_client $submount
16093         rmdir $submount
16094 }
16095
16096 test_247a() {
16097         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16098                 grep -q subtree ||
16099                 skip_env "Fileset feature is not supported"
16100
16101         local submount=${MOUNT}_$tdir
16102
16103         mkdir $MOUNT/$tdir
16104         mkdir -p $submount || error "mkdir $submount failed"
16105         FILESET="$FILESET/$tdir" mount_client $submount ||
16106                 error "mount $submount failed"
16107         trap "cleanup_247 $submount" EXIT
16108         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16109         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16110                 error "read $MOUNT/$tdir/$tfile failed"
16111         cleanup_247 $submount
16112 }
16113 run_test 247a "mount subdir as fileset"
16114
16115 test_247b() {
16116         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16117                 skip_env "Fileset feature is not supported"
16118
16119         local submount=${MOUNT}_$tdir
16120
16121         rm -rf $MOUNT/$tdir
16122         mkdir -p $submount || error "mkdir $submount failed"
16123         SKIP_FILESET=1
16124         FILESET="$FILESET/$tdir" mount_client $submount &&
16125                 error "mount $submount should fail"
16126         rmdir $submount
16127 }
16128 run_test 247b "mount subdir that dose not exist"
16129
16130 test_247c() {
16131         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16132                 skip_env "Fileset feature is not supported"
16133
16134         local submount=${MOUNT}_$tdir
16135
16136         mkdir -p $MOUNT/$tdir/dir1
16137         mkdir -p $submount || error "mkdir $submount failed"
16138         trap "cleanup_247 $submount" EXIT
16139         FILESET="$FILESET/$tdir" mount_client $submount ||
16140                 error "mount $submount failed"
16141         local fid=$($LFS path2fid $MOUNT/)
16142         $LFS fid2path $submount $fid && error "fid2path should fail"
16143         cleanup_247 $submount
16144 }
16145 run_test 247c "running fid2path outside root"
16146
16147 test_247d() {
16148         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16149                 skip "Fileset feature is not supported"
16150
16151         local submount=${MOUNT}_$tdir
16152
16153         mkdir -p $MOUNT/$tdir/dir1
16154         mkdir -p $submount || error "mkdir $submount failed"
16155         FILESET="$FILESET/$tdir" mount_client $submount ||
16156                 error "mount $submount failed"
16157         trap "cleanup_247 $submount" EXIT
16158         local fid=$($LFS path2fid $submount/dir1)
16159         $LFS fid2path $submount $fid || error "fid2path should succeed"
16160         cleanup_247 $submount
16161 }
16162 run_test 247d "running fid2path inside root"
16163
16164 # LU-8037
16165 test_247e() {
16166         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16167                 grep -q subtree ||
16168                 skip "Fileset feature is not supported"
16169
16170         local submount=${MOUNT}_$tdir
16171
16172         mkdir $MOUNT/$tdir
16173         mkdir -p $submount || error "mkdir $submount failed"
16174         FILESET="$FILESET/.." mount_client $submount &&
16175                 error "mount $submount should fail"
16176         rmdir $submount
16177 }
16178 run_test 247e "mount .. as fileset"
16179
16180 test_248() {
16181         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16182         [ -z "$fast_read_sav" ] && skip "no fast read support"
16183
16184         # create a large file for fast read verification
16185         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16186
16187         # make sure the file is created correctly
16188         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16189                 { rm -f $DIR/$tfile; skip "file creation error"; }
16190
16191         echo "Test 1: verify that fast read is 4 times faster on cache read"
16192
16193         # small read with fast read enabled
16194         $LCTL set_param -n llite.*.fast_read=1
16195         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16196                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16197                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16198         # small read with fast read disabled
16199         $LCTL set_param -n llite.*.fast_read=0
16200         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16201                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16202                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16203
16204         # verify that fast read is 4 times faster for cache read
16205         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16206                 error_not_in_vm "fast read was not 4 times faster: " \
16207                            "$t_fast vs $t_slow"
16208
16209         echo "Test 2: verify the performance between big and small read"
16210         $LCTL set_param -n llite.*.fast_read=1
16211
16212         # 1k non-cache read
16213         cancel_lru_locks osc
16214         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16215                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16216                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16217
16218         # 1M non-cache read
16219         cancel_lru_locks osc
16220         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16221                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16222                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16223
16224         # verify that big IO is not 4 times faster than small IO
16225         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16226                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16227
16228         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16229         rm -f $DIR/$tfile
16230 }
16231 run_test 248 "fast read verification"
16232
16233 test_249() { # LU-7890
16234         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16235                 skip "Need at least version 2.8.54"
16236
16237         rm -f $DIR/$tfile
16238         $LFS setstripe -c 1 $DIR/$tfile
16239         # Offset 2T == 4k * 512M
16240         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16241                 error "dd to 2T offset failed"
16242 }
16243 run_test 249 "Write above 2T file size"
16244
16245 test_250() {
16246         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16247          && skip "no 16TB file size limit on ZFS"
16248
16249         $LFS setstripe -c 1 $DIR/$tfile
16250         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16251         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16252         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16253         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16254                 conv=notrunc,fsync && error "append succeeded"
16255         return 0
16256 }
16257 run_test 250 "Write above 16T limit"
16258
16259 test_251() {
16260         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16261
16262         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16263         #Skip once - writing the first stripe will succeed
16264         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16265         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16266                 error "short write happened"
16267
16268         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16269         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16270                 error "short read happened"
16271
16272         rm -f $DIR/$tfile
16273 }
16274 run_test 251 "Handling short read and write correctly"
16275
16276 test_252() {
16277         remote_mds_nodsh && skip "remote MDS with nodsh"
16278         remote_ost_nodsh && skip "remote OST with nodsh"
16279         if [ "$ost1_FSTYPE" != "ldiskfs" -o "$mds1_FSTYPE" != "ldiskfs" ]; then
16280                 skip_env "ldiskfs only test"
16281         fi
16282
16283         local tgt
16284         local dev
16285         local out
16286         local uuid
16287         local num
16288         local gen
16289
16290         # check lr_reader on OST0000
16291         tgt=ost1
16292         dev=$(facet_device $tgt)
16293         out=$(do_facet $tgt $LR_READER $dev)
16294         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16295         echo "$out"
16296         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16297         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16298                 error "Invalid uuid returned by $LR_READER on target $tgt"
16299         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16300
16301         # check lr_reader -c on MDT0000
16302         tgt=mds1
16303         dev=$(facet_device $tgt)
16304         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16305                 skip "$LR_READER does not support additional options"
16306         fi
16307         out=$(do_facet $tgt $LR_READER -c $dev)
16308         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16309         echo "$out"
16310         num=$(echo "$out" | grep -c "mdtlov")
16311         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16312                 error "Invalid number of mdtlov clients returned by $LR_READER"
16313         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16314
16315         # check lr_reader -cr on MDT0000
16316         out=$(do_facet $tgt $LR_READER -cr $dev)
16317         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16318         echo "$out"
16319         echo "$out" | grep -q "^reply_data:$" ||
16320                 error "$LR_READER should have returned 'reply_data' section"
16321         num=$(echo "$out" | grep -c "client_generation")
16322         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16323 }
16324 run_test 252 "check lr_reader tool"
16325
16326 test_253_fill_ost() {
16327         local size_mb #how many MB should we write to pass watermark
16328         local lwm=$3  #low watermark
16329         local free_10mb #10% of free space
16330
16331         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16332         size_mb=$((free_kb / 1024 - lwm))
16333         free_10mb=$((free_kb / 10240))
16334         #If 10% of free space cross low watermark use it
16335         if (( free_10mb > size_mb )); then
16336                 size_mb=$free_10mb
16337         else
16338                 #At least we need to store 1.1 of difference between
16339                 #free space and low watermark
16340                 size_mb=$((size_mb + size_mb / 10))
16341         fi
16342         if (( lwm <= $((free_kb / 1024)) )) || [ ! -f $DIR/$tdir/1 ]; then
16343                 dd if=/dev/zero of=$DIR/$tdir/1 bs=1M count=$size_mb \
16344                          oflag=append conv=notrunc
16345         fi
16346
16347         sleep_maxage
16348
16349         free_kb=$($LFS df $MOUNT | grep $1 | awk '{ print $4 }')
16350         echo "OST still has $((free_kb / 1024)) mbytes free"
16351 }
16352
16353 test_253() {
16354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16355         remote_mds_nodsh && skip "remote MDS with nodsh"
16356         remote_mgs_nodsh && skip "remote MGS with nodsh"
16357
16358         local ostidx=0
16359         local rc=0
16360
16361         local ost_name=$($LFS osts |
16362                 sed -n 's/^'$ostidx': \(.*\)_UUID .*/\1/p')
16363         # on the mdt's osc
16364         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16365         do_facet $SINGLEMDS $LCTL get_param -n \
16366                 osp.$mdtosc_proc1.reserved_mb_high ||
16367                 skip  "remote MDS does not support reserved_mb_high"
16368
16369         rm -rf $DIR/$tdir
16370         wait_mds_ost_sync
16371         wait_delete_completed
16372         mkdir $DIR/$tdir
16373
16374         local last_wm_h=$(do_facet $SINGLEMDS $LCTL get_param -n \
16375                         osp.$mdtosc_proc1.reserved_mb_high)
16376         local last_wm_l=$(do_facet $SINGLEMDS $LCTL get_param -n \
16377                         osp.$mdtosc_proc1.reserved_mb_low)
16378         echo "prev high watermark $last_wm_h, prev low watermark $last_wm_l"
16379
16380         if ! combined_mgs_mds ; then
16381                 mount_mgs_client
16382         fi
16383         create_pool $FSNAME.$TESTNAME || error "Pool creation failed"
16384         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $ost_name ||
16385                 error "Adding $ost_name to pool failed"
16386
16387         # Wait for client to see a OST at pool
16388         wait_update $HOSTNAME "$LCTL get_param -n
16389                 lov.$FSNAME-*.pools.$TESTNAME | sort -u |
16390                 grep $ost_name" "$ost_name""_UUID" $((TIMEOUT/2)) ||
16391                 error "Client can not see the pool"
16392         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16393                 error "Setstripe failed"
16394
16395         dd if=/dev/zero of=$DIR/$tdir/0 bs=1M count=10
16396         local blocks=$($LFS df $MOUNT | grep $ost_name | awk '{ print $4 }')
16397         echo "OST still has $((blocks/1024)) mbytes free"
16398
16399         local new_lwm=$((blocks/1024-10))
16400         do_facet $SINGLEMDS $LCTL set_param \
16401                         osp.$mdtosc_proc1.reserved_mb_high=$((new_lwm+5))
16402         do_facet $SINGLEMDS $LCTL set_param \
16403                         osp.$mdtosc_proc1.reserved_mb_low=$new_lwm
16404
16405         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16406
16407         #First enospc could execute orphan deletion so repeat.
16408         test_253_fill_ost $ost_name $mdtosc_proc1 $new_lwm
16409
16410         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16411                         osp.$mdtosc_proc1.prealloc_status)
16412         echo "prealloc_status $oa_status"
16413
16414         dd if=/dev/zero of=$DIR/$tdir/2 bs=1M count=1 &&
16415                 error "File creation should fail"
16416         #object allocation was stopped, but we still able to append files
16417         dd if=/dev/zero of=$DIR/$tdir/1 bs=1M seek=6 count=5 oflag=append ||
16418                 error "Append failed"
16419         rm -f $DIR/$tdir/1 $DIR/$tdir/0 $DIR/$tdir/r*
16420
16421         wait_delete_completed
16422
16423         sleep_maxage
16424
16425         for i in $(seq 10 12); do
16426                 dd if=/dev/zero of=$DIR/$tdir/$i bs=1M count=1 2>/dev/null ||
16427                         error "File creation failed after rm";
16428         done
16429
16430         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16431                         osp.$mdtosc_proc1.prealloc_status)
16432         echo "prealloc_status $oa_status"
16433
16434         if (( oa_status != 0 )); then
16435                 error "Object allocation still disable after rm"
16436         fi
16437         do_facet $SINGLEMDS $LCTL set_param \
16438                         osp.$mdtosc_proc1.reserved_mb_high=$last_wm_h
16439         do_facet $SINGLEMDS $LCTL set_param \
16440                         osp.$mdtosc_proc1.reserved_mb_low=$last_wm_l
16441
16442
16443         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $ost_name ||
16444                 error "Remove $ost_name from pool failed"
16445         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16446                 error "Pool destroy fialed"
16447
16448         if ! combined_mgs_mds ; then
16449                 umount_mgs_client
16450         fi
16451 }
16452 run_test 253 "Check object allocation limit"
16453
16454 test_254() {
16455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16456         remote_mds_nodsh && skip "remote MDS with nodsh"
16457         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16458                 skip "MDS does not support changelog_size"
16459
16460         local cl_user
16461         local MDT0=$(facet_svc $SINGLEMDS)
16462
16463         changelog_register || error "changelog_register failed"
16464
16465         changelog_clear 0 || error "changelog_clear failed"
16466
16467         local size1=$(do_facet $SINGLEMDS \
16468                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16469         echo "Changelog size $size1"
16470
16471         rm -rf $DIR/$tdir
16472         $LFS mkdir -i 0 $DIR/$tdir
16473         # change something
16474         mkdir -p $DIR/$tdir/pics/2008/zachy
16475         touch $DIR/$tdir/pics/2008/zachy/timestamp
16476         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16477         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16478         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16479         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16480         rm $DIR/$tdir/pics/desktop.jpg
16481
16482         local size2=$(do_facet $SINGLEMDS \
16483                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16484         echo "Changelog size after work $size2"
16485
16486         (( $size2 > $size1 )) ||
16487                 error "new Changelog size=$size2 less than old size=$size1"
16488 }
16489 run_test 254 "Check changelog size"
16490
16491 ladvise_no_type()
16492 {
16493         local type=$1
16494         local file=$2
16495
16496         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16497                 awk -F: '{print $2}' | grep $type > /dev/null
16498         if [ $? -ne 0 ]; then
16499                 return 0
16500         fi
16501         return 1
16502 }
16503
16504 ladvise_no_ioctl()
16505 {
16506         local file=$1
16507
16508         lfs ladvise -a willread $file > /dev/null 2>&1
16509         if [ $? -eq 0 ]; then
16510                 return 1
16511         fi
16512
16513         lfs ladvise -a willread $file 2>&1 |
16514                 grep "Inappropriate ioctl for device" > /dev/null
16515         if [ $? -eq 0 ]; then
16516                 return 0
16517         fi
16518         return 1
16519 }
16520
16521 percent() {
16522         bc <<<"scale=2; ($1 - $2) * 100 / $2"
16523 }
16524
16525 # run a random read IO workload
16526 # usage: random_read_iops <filename> <filesize> <iosize>
16527 random_read_iops() {
16528         local file=$1
16529         local fsize=$2
16530         local iosize=${3:-4096}
16531
16532         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
16533                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
16534 }
16535
16536 drop_file_oss_cache() {
16537         local file="$1"
16538         local nodes="$2"
16539
16540         $LFS ladvise -a dontneed $file 2>/dev/null ||
16541                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
16542 }
16543
16544 ladvise_willread_performance()
16545 {
16546         local repeat=10
16547         local average_origin=0
16548         local average_cache=0
16549         local average_ladvise=0
16550
16551         for ((i = 1; i <= $repeat; i++)); do
16552                 echo "Iter $i/$repeat: reading without willread hint"
16553                 cancel_lru_locks osc
16554                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16555                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
16556                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
16557                 average_origin=$(bc <<<"$average_origin + $speed_origin")
16558
16559                 cancel_lru_locks osc
16560                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
16561                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
16562                 average_cache=$(bc <<<"$average_cache + $speed_cache")
16563
16564                 cancel_lru_locks osc
16565                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
16566                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
16567                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
16568                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
16569                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
16570         done
16571         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
16572         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
16573         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
16574
16575         speedup_cache=$(percent $average_cache $average_origin)
16576         speedup_ladvise=$(percent $average_ladvise $average_origin)
16577
16578         echo "Average uncached read: $average_origin"
16579         echo "Average speedup with OSS cached read: " \
16580                 "$average_cache = +$speedup_cache%"
16581         echo "Average speedup with ladvise willread: " \
16582                 "$average_ladvise = +$speedup_ladvise%"
16583
16584         local lowest_speedup=20
16585         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
16586                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
16587                         "got $average_cache%. Skipping ladvise willread check."
16588                 return 0
16589         fi
16590
16591         # the test won't work on ZFS until it supports 'ladvise dontneed', but
16592         # it is still good to run until then to exercise 'ladvise willread'
16593         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16594                 [ "$ost1_FSTYPE" = "zfs" ] &&
16595                 echo "osd-zfs does not support dontneed or drop_caches" &&
16596                 return 0
16597
16598         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
16599         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
16600                 error_not_in_vm "Speedup with willread is less than " \
16601                         "$lowest_speedup%, got $average_ladvise%"
16602 }
16603
16604 test_255a() {
16605         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16606                 skip "lustre < 2.8.54 does not support ladvise "
16607         remote_ost_nodsh && skip "remote OST with nodsh"
16608
16609         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
16610
16611         ladvise_no_type willread $DIR/$tfile &&
16612                 skip "willread ladvise is not supported"
16613
16614         ladvise_no_ioctl $DIR/$tfile &&
16615                 skip "ladvise ioctl is not supported"
16616
16617         local size_mb=100
16618         local size=$((size_mb * 1048576))
16619         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16620                 error "dd to $DIR/$tfile failed"
16621
16622         lfs ladvise -a willread $DIR/$tfile ||
16623                 error "Ladvise failed with no range argument"
16624
16625         lfs ladvise -a willread -s 0 $DIR/$tfile ||
16626                 error "Ladvise failed with no -l or -e argument"
16627
16628         lfs ladvise -a willread -e 1 $DIR/$tfile ||
16629                 error "Ladvise failed with only -e argument"
16630
16631         lfs ladvise -a willread -l 1 $DIR/$tfile ||
16632                 error "Ladvise failed with only -l argument"
16633
16634         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
16635                 error "End offset should not be smaller than start offset"
16636
16637         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
16638                 error "End offset should not be equal to start offset"
16639
16640         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
16641                 error "Ladvise failed with overflowing -s argument"
16642
16643         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
16644                 error "Ladvise failed with overflowing -e argument"
16645
16646         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
16647                 error "Ladvise failed with overflowing -l argument"
16648
16649         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
16650                 error "Ladvise succeeded with conflicting -l and -e arguments"
16651
16652         echo "Synchronous ladvise should wait"
16653         local delay=4
16654 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
16655         do_nodes $(comma_list $(osts_nodes)) \
16656                 $LCTL set_param fail_val=$delay fail_loc=0x237
16657
16658         local start_ts=$SECONDS
16659         lfs ladvise -a willread $DIR/$tfile ||
16660                 error "Ladvise failed with no range argument"
16661         local end_ts=$SECONDS
16662         local inteval_ts=$((end_ts - start_ts))
16663
16664         if [ $inteval_ts -lt $(($delay - 1)) ]; then
16665                 error "Synchronous advice didn't wait reply"
16666         fi
16667
16668         echo "Asynchronous ladvise shouldn't wait"
16669         local start_ts=$SECONDS
16670         lfs ladvise -a willread -b $DIR/$tfile ||
16671                 error "Ladvise failed with no range argument"
16672         local end_ts=$SECONDS
16673         local inteval_ts=$((end_ts - start_ts))
16674
16675         if [ $inteval_ts -gt $(($delay / 2)) ]; then
16676                 error "Asynchronous advice blocked"
16677         fi
16678
16679         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
16680         ladvise_willread_performance
16681 }
16682 run_test 255a "check 'lfs ladvise -a willread'"
16683
16684 facet_meminfo() {
16685         local facet=$1
16686         local info=$2
16687
16688         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
16689 }
16690
16691 test_255b() {
16692         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
16693                 skip "lustre < 2.8.54 does not support ladvise "
16694         remote_ost_nodsh && skip "remote OST with nodsh"
16695
16696         lfs setstripe -c 1 -i 0 $DIR/$tfile
16697
16698         ladvise_no_type dontneed $DIR/$tfile &&
16699                 skip "dontneed ladvise is not supported"
16700
16701         ladvise_no_ioctl $DIR/$tfile &&
16702                 skip "ladvise ioctl is not supported"
16703
16704         ! $LFS ladvise -a dontneed $DIR/$tfile &&
16705                 [ "$ost1_FSTYPE" = "zfs" ] &&
16706                 skip "zfs-osd does not support 'ladvise dontneed'"
16707
16708         local size_mb=100
16709         local size=$((size_mb * 1048576))
16710         # In order to prevent disturbance of other processes, only check 3/4
16711         # of the memory usage
16712         local kibibytes=$((size_mb * 1024 * 3 / 4))
16713
16714         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
16715                 error "dd to $DIR/$tfile failed"
16716
16717         #force write to complete before dropping OST cache & checking memory
16718         sync
16719
16720         local total=$(facet_meminfo ost1 MemTotal)
16721         echo "Total memory: $total KiB"
16722
16723         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
16724         local before_read=$(facet_meminfo ost1 Cached)
16725         echo "Cache used before read: $before_read KiB"
16726
16727         lfs ladvise -a willread $DIR/$tfile ||
16728                 error "Ladvise willread failed"
16729         local after_read=$(facet_meminfo ost1 Cached)
16730         echo "Cache used after read: $after_read KiB"
16731
16732         lfs ladvise -a dontneed $DIR/$tfile ||
16733                 error "Ladvise dontneed again failed"
16734         local no_read=$(facet_meminfo ost1 Cached)
16735         echo "Cache used after dontneed ladvise: $no_read KiB"
16736
16737         if [ $total -lt $((before_read + kibibytes)) ]; then
16738                 echo "Memory is too small, abort checking"
16739                 return 0
16740         fi
16741
16742         if [ $((before_read + kibibytes)) -gt $after_read ]; then
16743                 error "Ladvise willread should use more memory" \
16744                         "than $kibibytes KiB"
16745         fi
16746
16747         if [ $((no_read + kibibytes)) -gt $after_read ]; then
16748                 error "Ladvise dontneed should release more memory" \
16749                         "than $kibibytes KiB"
16750         fi
16751 }
16752 run_test 255b "check 'lfs ladvise -a dontneed'"
16753
16754 test_255c() {
16755         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
16756                 skip "lustre < 2.10.53 does not support lockahead"
16757
16758         local count
16759         local new_count
16760         local difference
16761         local i
16762         local rc
16763
16764         test_mkdir -p $DIR/$tdir
16765         $LFS setstripe -i 0 $DIR/$tdir
16766
16767         #test 10 returns only success/failure
16768         i=10
16769         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16770         rc=$?
16771         if [ $rc -eq 255 ]; then
16772                 error "Ladvise test${i} failed, ${rc}"
16773         fi
16774
16775         #test 11 counts lock enqueue requests, all others count new locks
16776         i=11
16777         count=$(do_facet ost1 \
16778                 $LCTL get_param -n ost.OSS.ost.stats)
16779         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
16780
16781         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16782         rc=$?
16783         if [ $rc -eq 255 ]; then
16784                 error "Ladvise test${i} failed, ${rc}"
16785         fi
16786
16787         new_count=$(do_facet ost1 \
16788                 $LCTL get_param -n ost.OSS.ost.stats)
16789         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
16790                    awk '{ print $2 }')
16791
16792         difference="$((new_count - count))"
16793         if [ $difference -ne $rc ]; then
16794                 error "Ladvise test${i}, bad enqueue count, returned " \
16795                       "${rc}, actual ${difference}"
16796         fi
16797
16798         for i in $(seq 12 21); do
16799                 # If we do not do this, we run the risk of having too many
16800                 # locks and starting lock cancellation while we are checking
16801                 # lock counts.
16802                 cancel_lru_locks osc
16803
16804                 count=$($LCTL get_param -n \
16805                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16806
16807                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
16808                 rc=$?
16809                 if [ $rc -eq 255 ]; then
16810                         error "Ladvise test ${i} failed, ${rc}"
16811                 fi
16812
16813                 new_count=$($LCTL get_param -n \
16814                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
16815                 difference="$((new_count - count))"
16816
16817                 # Test 15 output is divided by 100 to map down to valid return
16818                 if [ $i -eq 15 ]; then
16819                         rc="$((rc * 100))"
16820                 fi
16821
16822                 if [ $difference -ne $rc ]; then
16823                         error "Ladvise test ${i}, bad lock count, returned " \
16824                               "${rc}, actual ${difference}"
16825                 fi
16826         done
16827
16828         #test 22 returns only success/failure
16829         i=22
16830         lockahead_test -d $DIR/$tdir -t $i -f $tfile
16831         rc=$?
16832         if [ $rc -eq 255 ]; then
16833                 error "Ladvise test${i} failed, ${rc}"
16834         fi
16835 }
16836 run_test 255c "suite of ladvise lockahead tests"
16837
16838 test_256() {
16839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16840         remote_mds_nodsh && skip "remote MDS with nodsh"
16841         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16842         changelog_users $SINGLEMDS | grep "^cl" &&
16843                 skip "active changelog user"
16844
16845         local cl_user
16846         local cat_sl
16847         local mdt_dev
16848
16849         mdt_dev=$(mdsdevname 1)
16850         echo $mdt_dev
16851
16852         changelog_register || error "changelog_register failed"
16853
16854         rm -rf $DIR/$tdir
16855         mkdir -p $DIR/$tdir
16856
16857         changelog_clear 0 || error "changelog_clear failed"
16858
16859         # change something
16860         touch $DIR/$tdir/{1..10}
16861
16862         # stop the MDT
16863         stop $SINGLEMDS || error "Fail to stop MDT"
16864
16865         # remount the MDT
16866
16867         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
16868
16869         #after mount new plainllog is used
16870         touch $DIR/$tdir/{11..19}
16871         local tmpfile=$(mktemp -u $tfile.XXXXXX)
16872         cat_sl=$(do_facet $SINGLEMDS "sync; \
16873                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16874                  llog_reader $tmpfile | grep -c type=1064553b")
16875         do_facet $SINGLEMDS llog_reader $tmpfile
16876
16877         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
16878
16879         changelog_clear 0 || error "changelog_clear failed"
16880
16881         cat_sl=$(do_facet $SINGLEMDS "sync; \
16882                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
16883                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
16884
16885         if (( cat_sl == 2 )); then
16886                 error "Empty plain llog was not deleted from changelog catalog"
16887         elif (( cat_sl != 1 )); then
16888                 error "Active plain llog shouldn't be deleted from catalog"
16889         fi
16890 }
16891 run_test 256 "Check llog delete for empty and not full state"
16892
16893 test_257() {
16894         remote_mds_nodsh && skip "remote MDS with nodsh"
16895         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
16896                 skip "Need MDS version at least 2.8.55"
16897
16898         test_mkdir $DIR/$tdir
16899
16900         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
16901                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
16902         stat $DIR/$tdir
16903
16904 #define OBD_FAIL_MDS_XATTR_REP                  0x161
16905         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
16906         local facet=mds$((mdtidx + 1))
16907         set_nodes_failloc $(facet_active_host $facet) 0x80000161
16908         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
16909
16910         stop $facet || error "stop MDS failed"
16911         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
16912                 error "start MDS fail"
16913         wait_recovery_complete $facet
16914 }
16915 run_test 257 "xattr locks are not lost"
16916
16917 # Verify we take the i_mutex when security requires it
16918 test_258a() {
16919 #define OBD_FAIL_IMUTEX_SEC 0x141c
16920         $LCTL set_param fail_loc=0x141c
16921         touch $DIR/$tfile
16922         chmod u+s $DIR/$tfile
16923         chmod a+rwx $DIR/$tfile
16924         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16925         RC=$?
16926         if [ $RC -ne 0 ]; then
16927                 error "error, failed to take i_mutex, rc=$?"
16928         fi
16929         rm -f $DIR/$tfile
16930 }
16931 run_test 258a
16932
16933 # Verify we do NOT take the i_mutex in the normal case
16934 test_258b() {
16935 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
16936         $LCTL set_param fail_loc=0x141d
16937         touch $DIR/$tfile
16938         chmod a+rwx $DIR
16939         chmod a+rw $DIR/$tfile
16940         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
16941         RC=$?
16942         if [ $RC -ne 0 ]; then
16943                 error "error, took i_mutex unnecessarily, rc=$?"
16944         fi
16945         rm -f $DIR/$tfile
16946
16947 }
16948 run_test 258b "verify i_mutex security behavior"
16949
16950 test_259() {
16951         local file=$DIR/$tfile
16952         local before
16953         local after
16954
16955         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
16956
16957         stack_trap "rm -f $file" EXIT
16958
16959         wait_delete_completed
16960         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16961         echo "before: $before"
16962
16963         $LFS setstripe -i 0 -c 1 $file
16964         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
16965         sync_all_data
16966         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16967         echo "after write: $after"
16968
16969 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
16970         do_facet ost1 $LCTL set_param fail_loc=0x2301
16971         $TRUNCATE $file 0
16972         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16973         echo "after truncate: $after"
16974
16975         stop ost1
16976         do_facet ost1 $LCTL set_param fail_loc=0
16977         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16978         sleep 2
16979         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
16980         echo "after restart: $after"
16981         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
16982                 error "missing truncate?"
16983
16984         return 0
16985 }
16986 run_test 259 "crash at delayed truncate"
16987
16988 test_260() {
16989 #define OBD_FAIL_MDC_CLOSE               0x806
16990         $LCTL set_param fail_loc=0x80000806
16991         touch $DIR/$tfile
16992
16993 }
16994 run_test 260 "Check mdc_close fail"
16995
16996 ### Data-on-MDT sanity tests ###
16997 test_270a() {
16998         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
16999                 skip "Need MDS version at least 2.10.55 for DoM"
17000
17001         # create DoM file
17002         local dom=$DIR/$tdir/dom_file
17003         local tmp=$DIR/$tdir/tmp_file
17004
17005         mkdir -p $DIR/$tdir
17006
17007         # basic checks for DoM component creation
17008         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17009                 error "Can set MDT layout to non-first entry"
17010
17011         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17012                 error "Can define multiple entries as MDT layout"
17013
17014         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17015
17016         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17017         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17018         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17019
17020         local mdtidx=$($LFS getstripe -m $dom)
17021         local mdtname=MDT$(printf %04x $mdtidx)
17022         local facet=mds$((mdtidx + 1))
17023         local space_check=1
17024
17025         # Skip free space checks with ZFS
17026         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17027
17028         # write
17029         sync
17030         local size_tmp=$((65536 * 3))
17031         local mdtfree1=$(do_facet $facet \
17032                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17033
17034         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17035         # check also direct IO along write
17036         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17037         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17038         sync
17039         cmp $tmp $dom || error "file data is different"
17040         [ $(stat -c%s $dom) == $size_tmp ] ||
17041                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17042         if [ $space_check == 1 ]; then
17043                 local mdtfree2=$(do_facet $facet \
17044                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17045
17046                 # increase in usage from by $size_tmp
17047                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17048                         error "MDT free space wrong after write: " \
17049                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17050         fi
17051
17052         # truncate
17053         local size_dom=10000
17054
17055         $TRUNCATE $dom $size_dom
17056         [ $(stat -c%s $dom) == $size_dom ] ||
17057                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17058         if [ $space_check == 1 ]; then
17059                 mdtfree1=$(do_facet $facet \
17060                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17061                 # decrease in usage from $size_tmp to new $size_dom
17062                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17063                   $(((size_tmp - size_dom) / 1024)) ] ||
17064                         error "MDT free space is wrong after truncate: " \
17065                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17066         fi
17067
17068         # append
17069         cat $tmp >> $dom
17070         sync
17071         size_dom=$((size_dom + size_tmp))
17072         [ $(stat -c%s $dom) == $size_dom ] ||
17073                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17074         if [ $space_check == 1 ]; then
17075                 mdtfree2=$(do_facet $facet \
17076                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17077                 # increase in usage by $size_tmp from previous
17078                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17079                         error "MDT free space is wrong after append: " \
17080                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17081         fi
17082
17083         # delete
17084         rm $dom
17085         if [ $space_check == 1 ]; then
17086                 mdtfree1=$(do_facet $facet \
17087                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17088                 # decrease in usage by $size_dom from previous
17089                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17090                         error "MDT free space is wrong after removal: " \
17091                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17092         fi
17093
17094         # combined striping
17095         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17096                 error "Can't create DoM + OST striping"
17097
17098         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17099         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17100         # check also direct IO along write
17101         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17102         sync
17103         cmp $tmp $dom || error "file data is different"
17104         [ $(stat -c%s $dom) == $size_tmp ] ||
17105                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17106         rm $dom $tmp
17107
17108         return 0
17109 }
17110 run_test 270a "DoM: basic functionality tests"
17111
17112 test_270b() {
17113         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17114                 skip "Need MDS version at least 2.10.55"
17115
17116         local dom=$DIR/$tdir/dom_file
17117         local max_size=1048576
17118
17119         mkdir -p $DIR/$tdir
17120         $LFS setstripe -E $max_size -L mdt $dom
17121
17122         # truncate over the limit
17123         $TRUNCATE $dom $(($max_size + 1)) &&
17124                 error "successful truncate over the maximum size"
17125         # write over the limit
17126         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17127                 error "successful write over the maximum size"
17128         # append over the limit
17129         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17130         echo "12345" >> $dom && error "successful append over the maximum size"
17131         rm $dom
17132
17133         return 0
17134 }
17135 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17136
17137 test_270c() {
17138         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17139                 skip "Need MDS version at least 2.10.55"
17140
17141         mkdir -p $DIR/$tdir
17142         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17143
17144         # check files inherit DoM EA
17145         touch $DIR/$tdir/first
17146         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17147                 error "bad pattern"
17148         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17149                 error "bad stripe count"
17150         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17151                 error "bad stripe size"
17152
17153         # check directory inherits DoM EA and uses it as default
17154         mkdir $DIR/$tdir/subdir
17155         touch $DIR/$tdir/subdir/second
17156         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17157                 error "bad pattern in sub-directory"
17158         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17159                 error "bad stripe count in sub-directory"
17160         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17161                 error "bad stripe size in sub-directory"
17162         return 0
17163 }
17164 run_test 270c "DoM: DoM EA inheritance tests"
17165
17166 test_270d() {
17167         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17168                 skip "Need MDS version at least 2.10.55"
17169
17170         mkdir -p $DIR/$tdir
17171         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17172
17173         # inherit default DoM striping
17174         mkdir $DIR/$tdir/subdir
17175         touch $DIR/$tdir/subdir/f1
17176
17177         # change default directory striping
17178         $LFS setstripe -c 1 $DIR/$tdir/subdir
17179         touch $DIR/$tdir/subdir/f2
17180         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17181                 error "wrong default striping in file 2"
17182         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17183                 error "bad pattern in file 2"
17184         return 0
17185 }
17186 run_test 270d "DoM: change striping from DoM to RAID0"
17187
17188 test_270e() {
17189         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17190                 skip "Need MDS version at least 2.10.55"
17191
17192         mkdir -p $DIR/$tdir/dom
17193         mkdir -p $DIR/$tdir/norm
17194         DOMFILES=20
17195         NORMFILES=10
17196         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17197         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17198
17199         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17200         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17201
17202         # find DoM files by layout
17203         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17204         [ $NUM -eq  $DOMFILES ] ||
17205                 error "lfs find -L: found $NUM, expected $DOMFILES"
17206         echo "Test 1: lfs find 20 DOM files by layout: OK"
17207
17208         # there should be 1 dir with default DOM striping
17209         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17210         [ $NUM -eq  1 ] ||
17211                 error "lfs find -L: found $NUM, expected 1 dir"
17212         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17213
17214         # find DoM files by stripe size
17215         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17216         [ $NUM -eq  $DOMFILES ] ||
17217                 error "lfs find -S: found $NUM, expected $DOMFILES"
17218         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17219
17220         # find files by stripe offset except DoM files
17221         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17222         [ $NUM -eq  $NORMFILES ] ||
17223                 error "lfs find -i: found $NUM, expected $NORMFILES"
17224         echo "Test 5: lfs find no DOM files by stripe index: OK"
17225         return 0
17226 }
17227 run_test 270e "DoM: lfs find with DoM files test"
17228
17229 test_270f() {
17230         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17231                 skip "Need MDS version at least 2.10.55"
17232
17233         local mdtname=${FSNAME}-MDT0000-mdtlov
17234         local dom=$DIR/$tdir/dom_file
17235         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17236                                                 lod.$mdtname.dom_stripesize)
17237         local dom_limit=131072
17238
17239         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17240         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17241                                                 lod.$mdtname.dom_stripesize)
17242         [ ${dom_limit} -eq ${dom_current} ] ||
17243                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17244
17245         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17246         $LFS setstripe -d $DIR/$tdir
17247         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17248                 error "Can't set directory default striping"
17249
17250         # exceed maximum stripe size
17251         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17252                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17253         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17254                 error "Able to create DoM component size more than LOD limit"
17255
17256         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17257         dom_current=$(do_facet mds1 $LCTL get_param -n \
17258                                                 lod.$mdtname.dom_stripesize)
17259         [ 0 -eq ${dom_current} ] ||
17260                 error "Can't set zero DoM stripe limit"
17261         rm $dom
17262
17263         # attempt to create DoM file on server with disabled DoM should
17264         # remove DoM entry from layout and be succeed
17265         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17266                 error "Can't create DoM file (DoM is disabled)"
17267         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17268                 error "File has DoM component while DoM is disabled"
17269         rm $dom
17270
17271         # attempt to create DoM file with only DoM stripe should return error
17272         $LFS setstripe -E $dom_limit -L mdt $dom &&
17273                 error "Able to create DoM-only file while DoM is disabled"
17274
17275         # too low values to be aligned with smallest stripe size 64K
17276         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17277         dom_current=$(do_facet mds1 $LCTL get_param -n \
17278                                                 lod.$mdtname.dom_stripesize)
17279         [ 30000 -eq ${dom_current} ] &&
17280                 error "Can set too small DoM stripe limit"
17281
17282         # 64K is a minimal stripe size in Lustre, expect limit of that size
17283         [ 65536 -eq ${dom_current} ] ||
17284                 error "Limit is not set to 64K but ${dom_current}"
17285
17286         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17287         dom_current=$(do_facet mds1 $LCTL get_param -n \
17288                                                 lod.$mdtname.dom_stripesize)
17289         echo $dom_current
17290         [ 2147483648 -eq ${dom_current} ] &&
17291                 error "Can set too large DoM stripe limit"
17292
17293         do_facet mds1 $LCTL set_param -n \
17294                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17295         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17296                 error "Can't create DoM component size after limit change"
17297         do_facet mds1 $LCTL set_param -n \
17298                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17299         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17300                 error "Can't create DoM file after limit decrease"
17301         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17302                 error "Can create big DoM component after limit decrease"
17303         touch ${dom}_def ||
17304                 error "Can't create file with old default layout"
17305
17306         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17307         return 0
17308 }
17309 run_test 270f "DoM: maximum DoM stripe size checks"
17310
17311 test_271a() {
17312         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17313                 skip "Need MDS version at least 2.10.55"
17314
17315         local dom=$DIR/$tdir/dom
17316
17317         mkdir -p $DIR/$tdir
17318
17319         $LFS setstripe -E 1024K -L mdt $dom
17320
17321         lctl set_param -n mdc.*.stats=clear
17322         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17323         cat $dom > /dev/null
17324         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17325         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17326         ls $dom
17327         rm -f $dom
17328 }
17329 run_test 271a "DoM: data is cached for read after write"
17330
17331 test_271b() {
17332         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17333                 skip "Need MDS version at least 2.10.55"
17334
17335         local dom=$DIR/$tdir/dom
17336
17337         mkdir -p $DIR/$tdir
17338
17339         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17340
17341         lctl set_param -n mdc.*.stats=clear
17342         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17343         cancel_lru_locks mdc
17344         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17345         # second stat to check size is cached on client
17346         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17347         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17348         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17349         rm -f $dom
17350 }
17351 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17352
17353 test_271ba() {
17354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17355                 skip "Need MDS version at least 2.10.55"
17356
17357         local dom=$DIR/$tdir/dom
17358
17359         mkdir -p $DIR/$tdir
17360
17361         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17362
17363         lctl set_param -n mdc.*.stats=clear
17364         lctl set_param -n osc.*.stats=clear
17365         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17366         cancel_lru_locks mdc
17367         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17368         # second stat to check size is cached on client
17369         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17370         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17371         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17372         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17373         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17374         rm -f $dom
17375 }
17376 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17377
17378
17379 get_mdc_stats() {
17380         local mdtidx=$1
17381         local param=$2
17382         local mdt=MDT$(printf %04x $mdtidx)
17383
17384         if [ -z $param ]; then
17385                 lctl get_param -n mdc.*$mdt*.stats
17386         else
17387                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17388         fi
17389 }
17390
17391 test_271c() {
17392         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17393                 skip "Need MDS version at least 2.10.55"
17394
17395         local dom=$DIR/$tdir/dom
17396
17397         mkdir -p $DIR/$tdir
17398
17399         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17400
17401         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17402         local facet=mds$((mdtidx + 1))
17403
17404         cancel_lru_locks mdc
17405         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17406         createmany -o $dom 1000
17407         lctl set_param -n mdc.*.stats=clear
17408         smalliomany -w $dom 1000 200
17409         get_mdc_stats $mdtidx
17410         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17411         # Each file has 1 open, 1 IO enqueues, total 2000
17412         # but now we have also +1 getxattr for security.capability, total 3000
17413         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17414         unlinkmany $dom 1000
17415
17416         cancel_lru_locks mdc
17417         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17418         createmany -o $dom 1000
17419         lctl set_param -n mdc.*.stats=clear
17420         smalliomany -w $dom 1000 200
17421         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17422         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17423         # for OPEN and IO lock.
17424         [ $((enq - enq_2)) -ge 1000 ] ||
17425                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17426         unlinkmany $dom 1000
17427         return 0
17428 }
17429 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17430
17431 cleanup_271def_tests() {
17432         trap 0
17433         rm -f $1
17434 }
17435
17436 test_271d() {
17437         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17438                 skip "Need MDS version at least 2.10.57"
17439
17440         local dom=$DIR/$tdir/dom
17441         local tmp=$TMP/$tfile
17442         trap "cleanup_271def_tests $tmp" EXIT
17443
17444         mkdir -p $DIR/$tdir
17445
17446         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17447
17448         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17449
17450         cancel_lru_locks mdc
17451         dd if=/dev/urandom of=$tmp bs=1000 count=1
17452         dd if=$tmp of=$dom bs=1000 count=1
17453         cancel_lru_locks mdc
17454
17455         cat /etc/hosts >> $tmp
17456         lctl set_param -n mdc.*.stats=clear
17457
17458         # append data to the same file it should update local page
17459         echo "Append to the same page"
17460         cat /etc/hosts >> $dom
17461         local num=$(get_mdc_stats $mdtidx ost_read)
17462         local ra=$(get_mdc_stats $mdtidx req_active)
17463         local rw=$(get_mdc_stats $mdtidx req_waittime)
17464
17465         [ -z $num ] || error "$num READ RPC occured"
17466         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17467         echo "... DONE"
17468
17469         # compare content
17470         cmp $tmp $dom || error "file miscompare"
17471
17472         cancel_lru_locks mdc
17473         lctl set_param -n mdc.*.stats=clear
17474
17475         echo "Open and read file"
17476         cat $dom > /dev/null
17477         local num=$(get_mdc_stats $mdtidx ost_read)
17478         local ra=$(get_mdc_stats $mdtidx req_active)
17479         local rw=$(get_mdc_stats $mdtidx req_waittime)
17480
17481         [ -z $num ] || error "$num READ RPC occured"
17482         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17483         echo "... DONE"
17484
17485         # compare content
17486         cmp $tmp $dom || error "file miscompare"
17487
17488         return 0
17489 }
17490 run_test 271d "DoM: read on open (1K file in reply buffer)"
17491
17492 test_271e() {
17493         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17494                 skip "Need MDS version at least 2.10.57"
17495
17496         local dom=$DIR/$tdir/dom
17497         local tmp=$TMP/${tfile}.data
17498         trap "cleanup_271def_tests $tmp" EXIT
17499
17500         mkdir -p $DIR/$tdir
17501
17502         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17503
17504         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17505
17506         cancel_lru_locks mdc
17507         dd if=/dev/urandom of=$tmp bs=30K count=1
17508         dd if=$tmp of=$dom bs=30K count=1
17509         cancel_lru_locks mdc
17510         cat /etc/hosts >> $tmp
17511         lctl set_param -n mdc.*.stats=clear
17512
17513         echo "Append to the same page"
17514         cat /etc/hosts >> $dom
17515
17516         local num=$(get_mdc_stats $mdtidx ost_read)
17517         local ra=$(get_mdc_stats $mdtidx req_active)
17518         local rw=$(get_mdc_stats $mdtidx req_waittime)
17519
17520         [ -z $num ] || error "$num READ RPC occured"
17521         # Reply buffer can be adjusted for larger buffer by resend
17522         echo "... DONE with $((ra - rw)) resends"
17523
17524         # compare content
17525         cmp $tmp $dom || error "file miscompare"
17526
17527         cancel_lru_locks mdc
17528         lctl set_param -n mdc.*.stats=clear
17529
17530         echo "Open and read file"
17531         cat $dom > /dev/null
17532         local num=$(get_mdc_stats $mdtidx ost_read)
17533         local ra=$(get_mdc_stats $mdtidx req_active)
17534         local rw=$(get_mdc_stats $mdtidx req_waittime)
17535
17536         [ -z $num ] || error "$num READ RPC occured"
17537         # Reply buffer can be adjusted for larger buffer by resend
17538         echo "... DONE with $((ra - rw)) resends"
17539
17540         # compare content
17541         cmp $tmp $dom || error "file miscompare"
17542
17543         return 0
17544 }
17545 run_test 271e "DoM: read on open (30K file with reply buffer adjusting)"
17546
17547 test_271f() {
17548         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17549                 skip "Need MDS version at least 2.10.57"
17550
17551         local dom=$DIR/$tdir/dom
17552         local tmp=$TMP/$tfile
17553         trap "cleanup_271def_tests $tmp" EXIT
17554
17555         mkdir -p $DIR/$tdir
17556
17557         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17558
17559         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17560
17561         cancel_lru_locks mdc
17562         dd if=/dev/urandom of=$tmp bs=200000 count=1
17563         dd if=$tmp of=$dom bs=200000 count=1
17564         cancel_lru_locks mdc
17565         cat /etc/hosts >> $tmp
17566         lctl set_param -n mdc.*.stats=clear
17567
17568         echo "Append to the same page"
17569         cat /etc/hosts >> $dom
17570         local num=$(get_mdc_stats $mdtidx ost_read)
17571         local ra=$(get_mdc_stats $mdtidx req_active)
17572         local rw=$(get_mdc_stats $mdtidx req_waittime)
17573
17574         [ -z $num ] || error "$num READ RPC occured"
17575         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17576         echo "... DONE"
17577
17578         # compare content
17579         cmp $tmp $dom || error "file miscompare"
17580
17581         cancel_lru_locks mdc
17582         lctl set_param -n mdc.*.stats=clear
17583
17584         echo "Open and read file"
17585         cat $dom > /dev/null
17586         local num=$(get_mdc_stats $mdtidx ost_read)
17587         local ra=$(get_mdc_stats $mdtidx req_active)
17588         local rw=$(get_mdc_stats $mdtidx req_waittime)
17589
17590         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
17591         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17592         echo "... DONE"
17593
17594         # compare content
17595         cmp $tmp $dom || error "file miscompare"
17596
17597         return 0
17598 }
17599 run_test 271f "DoM: read on open (200K file and read tail)"
17600
17601 test_272a() {
17602         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17603                 skip "Need MDS version at least 2.11.50"
17604
17605         local dom=$DIR/$tdir/dom
17606         mkdir -p $DIR/$tdir
17607
17608         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
17609         dd if=/dev/urandom of=$dom bs=512K count=1 ||
17610                 error "failed to write data into $dom"
17611         local old_md5=$(md5sum $dom)
17612
17613         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
17614                 error "failed to migrate to the same DoM component"
17615
17616         local new_md5=$(md5sum $dom)
17617
17618         [ "$old_md5" == "$new_md5" ] ||
17619                 error "md5sum differ: $old_md5, $new_md5"
17620
17621         [ $($LFS getstripe -c $dom) -eq 2 ] ||
17622                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
17623 }
17624 run_test 272a "DoM migration: new layout with the same DOM component"
17625
17626 test_272b() {
17627         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17628                 skip "Need MDS version at least 2.11.50"
17629
17630         local dom=$DIR/$tdir/dom
17631         mkdir -p $DIR/$tdir
17632         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17633
17634         local mdtidx=$($LFS getstripe -m $dom)
17635         local mdtname=MDT$(printf %04x $mdtidx)
17636         local facet=mds$((mdtidx + 1))
17637
17638         local mdtfree1=$(do_facet $facet \
17639                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17640         dd if=/dev/urandom of=$dom bs=2M count=1 ||
17641                 error "failed to write data into $dom"
17642         local old_md5=$(md5sum $dom)
17643         cancel_lru_locks mdc
17644         local mdtfree1=$(do_facet $facet \
17645                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17646
17647         $LFS migrate -c2 $dom ||
17648                 error "failed to migrate to the new composite layout"
17649         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17650                 error "MDT stripe was not removed"
17651
17652         cancel_lru_locks mdc
17653         local new_md5=$(md5sum $dom)
17654         [ "$old_md5" != "$new_md5" ] &&
17655                 error "$old_md5 != $new_md5"
17656
17657         # Skip free space checks with ZFS
17658         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17659                 local mdtfree2=$(do_facet $facet \
17660                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17661                 [ $mdtfree2 -gt $mdtfree1 ] ||
17662                         error "MDT space is not freed after migration"
17663         fi
17664         return 0
17665 }
17666 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
17667
17668 test_272c() {
17669         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17670                 skip "Need MDS version at least 2.11.50"
17671
17672         local dom=$DIR/$tdir/$tfile
17673         mkdir -p $DIR/$tdir
17674         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
17675
17676         local mdtidx=$($LFS getstripe -m $dom)
17677         local mdtname=MDT$(printf %04x $mdtidx)
17678         local facet=mds$((mdtidx + 1))
17679
17680         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
17681                 error "failed to write data into $dom"
17682         local old_md5=$(md5sum $dom)
17683         cancel_lru_locks mdc
17684         local mdtfree1=$(do_facet $facet \
17685                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17686
17687         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
17688                 error "failed to migrate to the new composite layout"
17689         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
17690                 error "MDT stripe was not removed"
17691
17692         cancel_lru_locks mdc
17693         local new_md5=$(md5sum $dom)
17694         [ "$old_md5" != "$new_md5" ] &&
17695                 error "$old_md5 != $new_md5"
17696
17697         # Skip free space checks with ZFS
17698         if [ "$(facet_fstype $facet)" != "zfs" ]; then
17699                 local mdtfree2=$(do_facet $facet \
17700                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17701                 [ $mdtfree2 -gt $mdtfree1 ] ||
17702                         error "MDS space is not freed after migration"
17703         fi
17704         return 0
17705 }
17706 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
17707
17708 test_273a() {
17709         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
17710                 skip "Need MDS version at least 2.11.50"
17711
17712         # Layout swap cannot be done if either file has DOM component,
17713         # this will never be supported, migration should be used instead
17714
17715         local dom=$DIR/$tdir/$tfile
17716         mkdir -p $DIR/$tdir
17717
17718         $LFS setstripe -c2 ${dom}_plain
17719         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
17720         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
17721                 error "can swap layout with DoM component"
17722         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
17723                 error "can swap layout with DoM component"
17724
17725         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
17726         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
17727                 error "can swap layout with DoM component"
17728         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
17729                 error "can swap layout with DoM component"
17730         return 0
17731 }
17732 run_test 273a "DoM: layout swapping should fail with DOM"
17733
17734 test_275() {
17735         remote_ost_nodsh && skip "remote OST with nodsh"
17736         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
17737                 skip "Need OST version >= 2.10.57"
17738
17739         local file=$DIR/$tfile
17740         local oss
17741
17742         oss=$(comma_list $(osts_nodes))
17743
17744         dd if=/dev/urandom of=$file bs=1M count=2 ||
17745                 error "failed to create a file"
17746         cancel_lru_locks osc
17747
17748         #lock 1
17749         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17750                 error "failed to read a file"
17751
17752 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
17753         $LCTL set_param fail_loc=0x8000031f
17754
17755         cancel_lru_locks osc &
17756         sleep 1
17757
17758 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
17759         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
17760         #IO takes another lock, but matches the PENDING one
17761         #and places it to the IO RPC
17762         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
17763                 error "failed to read a file with PENDING lock"
17764 }
17765 run_test 275 "Read on a canceled duplicate lock"
17766
17767 test_276() {
17768         remote_ost_nodsh && skip "remote OST with nodsh"
17769         local pid
17770
17771         do_facet ost1 "(while true; do \
17772                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
17773                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
17774         pid=$!
17775
17776         for LOOP in $(seq 20); do
17777                 stop ost1
17778                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
17779         done
17780         kill -9 $pid
17781         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
17782                 rm $TMP/sanity_276_pid"
17783 }
17784 run_test 276 "Race between mount and obd_statfs"
17785
17786 cleanup_test_300() {
17787         trap 0
17788         umask $SAVE_UMASK
17789 }
17790 test_striped_dir() {
17791         local mdt_index=$1
17792         local stripe_count
17793         local stripe_index
17794
17795         mkdir -p $DIR/$tdir
17796
17797         SAVE_UMASK=$(umask)
17798         trap cleanup_test_300 RETURN EXIT
17799
17800         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
17801                                                 $DIR/$tdir/striped_dir ||
17802                 error "set striped dir error"
17803
17804         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
17805         [ "$mode" = "755" ] || error "expect 755 got $mode"
17806
17807         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
17808                 error "getdirstripe failed"
17809         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
17810         if [ "$stripe_count" != "2" ]; then
17811                 error "1:stripe_count is $stripe_count, expect 2"
17812         fi
17813         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
17814         if [ "$stripe_count" != "2" ]; then
17815                 error "2:stripe_count is $stripe_count, expect 2"
17816         fi
17817
17818         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
17819         if [ "$stripe_index" != "$mdt_index" ]; then
17820                 error "stripe_index is $stripe_index, expect $mdt_index"
17821         fi
17822
17823         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17824                 error "nlink error after create striped dir"
17825
17826         mkdir $DIR/$tdir/striped_dir/a
17827         mkdir $DIR/$tdir/striped_dir/b
17828
17829         stat $DIR/$tdir/striped_dir/a ||
17830                 error "create dir under striped dir failed"
17831         stat $DIR/$tdir/striped_dir/b ||
17832                 error "create dir under striped dir failed"
17833
17834         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
17835                 error "nlink error after mkdir"
17836
17837         rmdir $DIR/$tdir/striped_dir/a
17838         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
17839                 error "nlink error after rmdir"
17840
17841         rmdir $DIR/$tdir/striped_dir/b
17842         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
17843                 error "nlink error after rmdir"
17844
17845         chattr +i $DIR/$tdir/striped_dir
17846         createmany -o $DIR/$tdir/striped_dir/f 10 &&
17847                 error "immutable flags not working under striped dir!"
17848         chattr -i $DIR/$tdir/striped_dir
17849
17850         rmdir $DIR/$tdir/striped_dir ||
17851                 error "rmdir striped dir error"
17852
17853         cleanup_test_300
17854
17855         true
17856 }
17857
17858 test_300a() {
17859         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17860                 skip "skipped for lustre < 2.7.0"
17861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17863
17864         test_striped_dir 0 || error "failed on striped dir on MDT0"
17865         test_striped_dir 1 || error "failed on striped dir on MDT0"
17866 }
17867 run_test 300a "basic striped dir sanity test"
17868
17869 test_300b() {
17870         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17871                 skip "skipped for lustre < 2.7.0"
17872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17873         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17874
17875         local i
17876         local mtime1
17877         local mtime2
17878         local mtime3
17879
17880         test_mkdir $DIR/$tdir || error "mkdir fail"
17881         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17882                 error "set striped dir error"
17883         for i in {0..9}; do
17884                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
17885                 sleep 1
17886                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
17887                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
17888                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
17889                 sleep 1
17890                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
17891                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
17892                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
17893         done
17894         true
17895 }
17896 run_test 300b "check ctime/mtime for striped dir"
17897
17898 test_300c() {
17899         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17900                 skip "skipped for lustre < 2.7.0"
17901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17903
17904         local file_count
17905
17906         mkdir -p $DIR/$tdir
17907         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
17908                 error "set striped dir error"
17909
17910         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
17911                 error "chown striped dir failed"
17912
17913         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
17914                 error "create 5k files failed"
17915
17916         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
17917
17918         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
17919
17920         rm -rf $DIR/$tdir
17921 }
17922 run_test 300c "chown && check ls under striped directory"
17923
17924 test_300d() {
17925         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
17926                 skip "skipped for lustre < 2.7.0"
17927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17929
17930         local stripe_count
17931         local file
17932
17933         mkdir -p $DIR/$tdir
17934         $LFS setstripe -c 2 $DIR/$tdir
17935
17936         #local striped directory
17937         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17938                 error "set striped dir error"
17939         createmany -o $DIR/$tdir/striped_dir/f 10 ||
17940                 error "create 10 files failed"
17941
17942         #remote striped directory
17943         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
17944                 error "set striped dir error"
17945         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
17946                 error "create 10 files failed"
17947
17948         for file in $(find $DIR/$tdir); do
17949                 stripe_count=$($LFS getstripe -c $file)
17950                 [ $stripe_count -eq 2 ] ||
17951                         error "wrong stripe $stripe_count for $file"
17952         done
17953
17954         rm -rf $DIR/$tdir
17955 }
17956 run_test 300d "check default stripe under striped directory"
17957
17958 test_300e() {
17959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
17960                 skip "Need MDS version at least 2.7.55"
17961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17962         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17963
17964         local stripe_count
17965         local file
17966
17967         mkdir -p $DIR/$tdir
17968
17969         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
17970                 error "set striped dir error"
17971
17972         touch $DIR/$tdir/striped_dir/a
17973         touch $DIR/$tdir/striped_dir/b
17974         touch $DIR/$tdir/striped_dir/c
17975
17976         mkdir $DIR/$tdir/striped_dir/dir_a
17977         mkdir $DIR/$tdir/striped_dir/dir_b
17978         mkdir $DIR/$tdir/striped_dir/dir_c
17979
17980         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
17981                 error "set striped adir under striped dir error"
17982
17983         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
17984                 error "set striped bdir under striped dir error"
17985
17986         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
17987                 error "set striped cdir under striped dir error"
17988
17989         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
17990                 error "rename dir under striped dir fails"
17991
17992         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
17993                 error "rename dir under different stripes fails"
17994
17995         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
17996                 error "rename file under striped dir should succeed"
17997
17998         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
17999                 error "rename dir under striped dir should succeed"
18000
18001         rm -rf $DIR/$tdir
18002 }
18003 run_test 300e "check rename under striped directory"
18004
18005 test_300f() {
18006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18008         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18009                 skip "Need MDS version at least 2.7.55"
18010
18011         local stripe_count
18012         local file
18013
18014         rm -rf $DIR/$tdir
18015         mkdir -p $DIR/$tdir
18016
18017         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18018                 error "set striped dir error"
18019
18020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18021                 error "set striped dir error"
18022
18023         touch $DIR/$tdir/striped_dir/a
18024         mkdir $DIR/$tdir/striped_dir/dir_a
18025         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18026                 error "create striped dir under striped dir fails"
18027
18028         touch $DIR/$tdir/striped_dir1/b
18029         mkdir $DIR/$tdir/striped_dir1/dir_b
18030         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18031                 error "create striped dir under striped dir fails"
18032
18033         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18034                 error "rename dir under different striped dir should fail"
18035
18036         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18037                 error "rename striped dir under diff striped dir should fail"
18038
18039         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18040                 error "rename file under diff striped dirs fails"
18041
18042         rm -rf $DIR/$tdir
18043 }
18044 run_test 300f "check rename cross striped directory"
18045
18046 test_300_check_default_striped_dir()
18047 {
18048         local dirname=$1
18049         local default_count=$2
18050         local default_index=$3
18051         local stripe_count
18052         local stripe_index
18053         local dir_stripe_index
18054         local dir
18055
18056         echo "checking $dirname $default_count $default_index"
18057         $LFS setdirstripe -D -c $default_count -i $default_index \
18058                                 -t all_char $DIR/$tdir/$dirname ||
18059                 error "set default stripe on striped dir error"
18060         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18061         [ $stripe_count -eq $default_count ] ||
18062                 error "expect $default_count get $stripe_count for $dirname"
18063
18064         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18065         [ $stripe_index -eq $default_index ] ||
18066                 error "expect $default_index get $stripe_index for $dirname"
18067
18068         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18069                                                 error "create dirs failed"
18070
18071         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18072         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18073         for dir in $(find $DIR/$tdir/$dirname/*); do
18074                 stripe_count=$($LFS getdirstripe -c $dir)
18075                 [ $stripe_count -eq $default_count ] ||
18076                 [ $stripe_count -eq 0 -o $default_count -eq 1 ] ||
18077                 error "stripe count $default_count != $stripe_count for $dir"
18078
18079                 stripe_index=$($LFS getdirstripe -i $dir)
18080                 [ $default_index -eq -1 -o $stripe_index -eq $default_index ] ||
18081                         error "$stripe_index != $default_index for $dir"
18082
18083                 #check default stripe
18084                 stripe_count=$($LFS getdirstripe -D -c $dir)
18085                 [ $stripe_count -eq $default_count ] ||
18086                 error "default count $default_count != $stripe_count for $dir"
18087
18088                 stripe_index=$($LFS getdirstripe -D -i $dir)
18089                 [ $stripe_index -eq $default_index ] ||
18090                 error "default index $default_index != $stripe_index for $dir"
18091         done
18092         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18093 }
18094
18095 test_300g() {
18096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18097         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18098                 skip "Need MDS version at least 2.7.55"
18099
18100         local dir
18101         local stripe_count
18102         local stripe_index
18103
18104         mkdir $DIR/$tdir
18105         mkdir $DIR/$tdir/normal_dir
18106
18107         #Checking when client cache stripe index
18108         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18109         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18110                 error "create striped_dir failed"
18111
18112         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18113                 error "create dir0 fails"
18114         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18115         [ $stripe_index -eq 0 ] ||
18116                 error "dir0 expect index 0 got $stripe_index"
18117
18118         mkdir $DIR/$tdir/striped_dir/dir1 ||
18119                 error "create dir1 fails"
18120         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18121         [ $stripe_index -eq 1 ] ||
18122                 error "dir1 expect index 1 got $stripe_index"
18123
18124         #check default stripe count/stripe index
18125         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18126         test_300_check_default_striped_dir normal_dir 1 0
18127         test_300_check_default_striped_dir normal_dir 2 1
18128         test_300_check_default_striped_dir normal_dir 2 -1
18129
18130         #delete default stripe information
18131         echo "delete default stripeEA"
18132         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18133                 error "set default stripe on striped dir error"
18134
18135         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18136         for dir in $(find $DIR/$tdir/normal_dir/*); do
18137                 stripe_count=$($LFS getdirstripe -c $dir)
18138                 [ $stripe_count -eq 0 ] ||
18139                         error "expect 1 get $stripe_count for $dir"
18140                 stripe_index=$($LFS getdirstripe -i $dir)
18141                 [ $stripe_index -eq 0 ] ||
18142                         error "expect 0 get $stripe_index for $dir"
18143         done
18144 }
18145 run_test 300g "check default striped directory for normal directory"
18146
18147 test_300h() {
18148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18149         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18150                 skip "Need MDS version at least 2.7.55"
18151
18152         local dir
18153         local stripe_count
18154
18155         mkdir $DIR/$tdir
18156         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18157                 error "set striped dir error"
18158
18159         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18160         test_300_check_default_striped_dir striped_dir 1 0
18161         test_300_check_default_striped_dir striped_dir 2 1
18162         test_300_check_default_striped_dir striped_dir 2 -1
18163
18164         #delete default stripe information
18165         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18166                 error "set default stripe on striped dir error"
18167
18168         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18169         for dir in $(find $DIR/$tdir/striped_dir/*); do
18170                 stripe_count=$($LFS getdirstripe -c $dir)
18171                 [ $stripe_count -eq 0 ] ||
18172                         error "expect 1 get $stripe_count for $dir"
18173         done
18174 }
18175 run_test 300h "check default striped directory for striped directory"
18176
18177 test_300i() {
18178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18179         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18180         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18181                 skip "Need MDS version at least 2.7.55"
18182
18183         local stripe_count
18184         local file
18185
18186         mkdir $DIR/$tdir
18187
18188         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18189                 error "set striped dir error"
18190
18191         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18192                 error "create files under striped dir failed"
18193
18194         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18195                 error "set striped hashdir error"
18196
18197         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18198                 error "create dir0 under hash dir failed"
18199         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18200                 error "create dir1 under hash dir failed"
18201
18202         # unfortunately, we need to umount to clear dir layout cache for now
18203         # once we fully implement dir layout, we can drop this
18204         umount_client $MOUNT || error "umount failed"
18205         mount_client $MOUNT || error "mount failed"
18206
18207         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18208         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18209         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18210
18211         #set the stripe to be unknown hash type
18212         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18213         $LCTL set_param fail_loc=0x1901
18214         for ((i = 0; i < 10; i++)); do
18215                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18216                         error "stat f-$i failed"
18217                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18218         done
18219
18220         touch $DIR/$tdir/striped_dir/f0 &&
18221                 error "create under striped dir with unknown hash should fail"
18222
18223         $LCTL set_param fail_loc=0
18224
18225         umount_client $MOUNT || error "umount failed"
18226         mount_client $MOUNT || error "mount failed"
18227
18228         return 0
18229 }
18230 run_test 300i "client handle unknown hash type striped directory"
18231
18232 test_300j() {
18233         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18235         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18236                 skip "Need MDS version at least 2.7.55"
18237
18238         local stripe_count
18239         local file
18240
18241         mkdir $DIR/$tdir
18242
18243         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18244         $LCTL set_param fail_loc=0x1702
18245         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18246                 error "set striped dir error"
18247
18248         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18249                 error "create files under striped dir failed"
18250
18251         $LCTL set_param fail_loc=0
18252
18253         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18254
18255         return 0
18256 }
18257 run_test 300j "test large update record"
18258
18259 test_300k() {
18260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18262         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18263                 skip "Need MDS version at least 2.7.55"
18264
18265         # this test needs a huge transaction
18266         local kb
18267         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18268         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18269
18270         local stripe_count
18271         local file
18272
18273         mkdir $DIR/$tdir
18274
18275         #define OBD_FAIL_LARGE_STRIPE   0x1703
18276         $LCTL set_param fail_loc=0x1703
18277         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18278                 error "set striped dir error"
18279         $LCTL set_param fail_loc=0
18280
18281         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18282                 error "getstripeddir fails"
18283         rm -rf $DIR/$tdir/striped_dir ||
18284                 error "unlink striped dir fails"
18285
18286         return 0
18287 }
18288 run_test 300k "test large striped directory"
18289
18290 test_300l() {
18291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18293         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18294                 skip "Need MDS version at least 2.7.55"
18295
18296         local stripe_index
18297
18298         test_mkdir -p $DIR/$tdir/striped_dir
18299         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18300                         error "chown $RUNAS_ID failed"
18301         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18302                 error "set default striped dir failed"
18303
18304         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18305         $LCTL set_param fail_loc=0x80000158
18306         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18307
18308         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18309         [ $stripe_index -eq 1 ] ||
18310                 error "expect 1 get $stripe_index for $dir"
18311 }
18312 run_test 300l "non-root user to create dir under striped dir with stale layout"
18313
18314 test_300m() {
18315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18316         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18318                 skip "Need MDS version at least 2.7.55"
18319
18320         mkdir -p $DIR/$tdir/striped_dir
18321         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18322                 error "set default stripes dir error"
18323
18324         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18325
18326         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18327         [ $stripe_count -eq 0 ] ||
18328                         error "expect 0 get $stripe_count for a"
18329
18330         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18331                 error "set default stripes dir error"
18332
18333         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18334
18335         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18336         [ $stripe_count -eq 0 ] ||
18337                         error "expect 0 get $stripe_count for b"
18338
18339         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18340                 error "set default stripes dir error"
18341
18342         mkdir $DIR/$tdir/striped_dir/c &&
18343                 error "default stripe_index is invalid, mkdir c should fails"
18344
18345         rm -rf $DIR/$tdir || error "rmdir fails"
18346 }
18347 run_test 300m "setstriped directory on single MDT FS"
18348
18349 cleanup_300n() {
18350         local list=$(comma_list $(mdts_nodes))
18351
18352         trap 0
18353         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18354 }
18355
18356 test_300n() {
18357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18359         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18360                 skip "Need MDS version at least 2.7.55"
18361         remote_mds_nodsh && skip "remote MDS with nodsh"
18362
18363         local stripe_index
18364         local list=$(comma_list $(mdts_nodes))
18365
18366         trap cleanup_300n RETURN EXIT
18367         mkdir -p $DIR/$tdir
18368         chmod 777 $DIR/$tdir
18369         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18370                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18371                 error "create striped dir succeeds with gid=0"
18372
18373         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18374         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18375                 error "create striped dir fails with gid=-1"
18376
18377         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18378         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18379                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18380                 error "set default striped dir succeeds with gid=0"
18381
18382
18383         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18384         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18385                 error "set default striped dir fails with gid=-1"
18386
18387
18388         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18389         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18390                                         error "create test_dir fails"
18391         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18392                                         error "create test_dir1 fails"
18393         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18394                                         error "create test_dir2 fails"
18395         cleanup_300n
18396 }
18397 run_test 300n "non-root user to create dir under striped dir with default EA"
18398
18399 test_300o() {
18400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18402         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18403                 skip "Need MDS version at least 2.7.55"
18404
18405         local numfree1
18406         local numfree2
18407
18408         mkdir -p $DIR/$tdir
18409
18410         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18411         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18412         if [ $numfree1 -lt 66000 -o $numfree2 -lt 66000 ]; then
18413                 skip "not enough free inodes $numfree1 $numfree2"
18414         fi
18415
18416         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18417         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18418         if [ $numfree1 -lt 300000 -o $numfree2 -lt 300000 ]; then
18419                 skip "not enough free space $numfree1 $numfree2"
18420         fi
18421
18422         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18423                 error "setdirstripe fails"
18424
18425         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18426                 error "create dirs fails"
18427
18428         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18429         ls $DIR/$tdir/striped_dir > /dev/null ||
18430                 error "ls striped dir fails"
18431         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18432                 error "unlink big striped dir fails"
18433 }
18434 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18435
18436 test_300p() {
18437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18439         remote_mds_nodsh && skip "remote MDS with nodsh"
18440
18441         mkdir -p $DIR/$tdir
18442
18443         #define OBD_FAIL_OUT_ENOSPC     0x1704
18444         do_facet mds2 lctl set_param fail_loc=0x80001704
18445         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18446                  && error "create striped directory should fail"
18447
18448         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18449
18450         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18451         true
18452 }
18453 run_test 300p "create striped directory without space"
18454
18455 test_300q() {
18456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18458
18459         local fd=$(free_fd)
18460         local cmd="exec $fd<$tdir"
18461         cd $DIR
18462         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18463         eval $cmd
18464         cmd="exec $fd<&-"
18465         trap "eval $cmd" EXIT
18466         cd $tdir || error "cd $tdir fails"
18467         rmdir  ../$tdir || error "rmdir $tdir fails"
18468         mkdir local_dir && error "create dir succeeds"
18469         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18470         eval $cmd
18471         return 0
18472 }
18473 run_test 300q "create remote directory under orphan directory"
18474
18475 test_300r() {
18476         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18477                 skip "Need MDS version at least 2.7.55" && return
18478         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18479
18480         mkdir $DIR/$tdir
18481
18482         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18483                 error "set striped dir error"
18484
18485         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18486                 error "getstripeddir fails"
18487
18488         local stripe_count
18489         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18490                       awk '/lmv_stripe_count:/ { print $2 }')
18491
18492         [ $MDSCOUNT -ne $stripe_count ] &&
18493                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18494
18495         rm -rf $DIR/$tdir/striped_dir ||
18496                 error "unlink striped dir fails"
18497 }
18498 run_test 300r "test -1 striped directory"
18499
18500 prepare_remote_file() {
18501         mkdir $DIR/$tdir/src_dir ||
18502                 error "create remote source failed"
18503
18504         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18505                  error "cp to remote source failed"
18506         touch $DIR/$tdir/src_dir/a
18507
18508         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18509                 error "create remote target dir failed"
18510
18511         touch $DIR/$tdir/tgt_dir/b
18512
18513         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18514                 error "rename dir cross MDT failed!"
18515
18516         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18517                 error "src_child still exists after rename"
18518
18519         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18520                 error "missing file(a) after rename"
18521
18522         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18523                 error "diff after rename"
18524 }
18525
18526 test_310a() {
18527         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18529
18530         local remote_file=$DIR/$tdir/tgt_dir/b
18531
18532         mkdir -p $DIR/$tdir
18533
18534         prepare_remote_file || error "prepare remote file failed"
18535
18536         #open-unlink file
18537         $OPENUNLINK $remote_file $remote_file ||
18538                 error "openunlink $remote_file failed"
18539         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18540 }
18541 run_test 310a "open unlink remote file"
18542
18543 test_310b() {
18544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18546
18547         local remote_file=$DIR/$tdir/tgt_dir/b
18548
18549         mkdir -p $DIR/$tdir
18550
18551         prepare_remote_file || error "prepare remote file failed"
18552
18553         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18554         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
18555         $CHECKSTAT -t file $remote_file || error "check file failed"
18556 }
18557 run_test 310b "unlink remote file with multiple links while open"
18558
18559 test_310c() {
18560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18561         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
18562
18563         local remote_file=$DIR/$tdir/tgt_dir/b
18564
18565         mkdir -p $DIR/$tdir
18566
18567         prepare_remote_file || error "prepare remote file failed"
18568
18569         ln $remote_file $DIR/$tfile || error "link failed for remote file"
18570         multiop_bg_pause $remote_file O_uc ||
18571                         error "mulitop failed for remote file"
18572         MULTIPID=$!
18573         $MULTIOP $DIR/$tfile Ouc
18574         kill -USR1 $MULTIPID
18575         wait $MULTIPID
18576 }
18577 run_test 310c "open-unlink remote file with multiple links"
18578
18579 #LU-4825
18580 test_311() {
18581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18582         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18583         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
18584                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
18585         remote_mds_nodsh && skip "remote MDS with nodsh"
18586
18587         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18588         local mdts=$(comma_list $(mdts_nodes))
18589
18590         mkdir -p $DIR/$tdir
18591         $LFS setstripe -i 0 -c 1 $DIR/$tdir
18592         createmany -o $DIR/$tdir/$tfile. 1000
18593
18594         # statfs data is not real time, let's just calculate it
18595         old_iused=$((old_iused + 1000))
18596
18597         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18598                         osp.*OST0000*MDT0000.create_count")
18599         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
18600                                 osp.*OST0000*MDT0000.max_create_count")
18601         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
18602
18603         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
18604         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
18605         [ $index -ne 0 ] || error "$tfile stripe index is 0"
18606
18607         unlinkmany $DIR/$tdir/$tfile. 1000
18608
18609         do_nodes $mdts "$LCTL set_param -n \
18610                         osp.*OST0000*.max_create_count=$max_count"
18611         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
18612                 do_nodes $mdts "$LCTL set_param -n \
18613                                 osp.*OST0000*.create_count=$count"
18614         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
18615                         grep "=0" && error "create_count is zero"
18616
18617         local new_iused
18618         for i in $(seq 120); do
18619                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
18620                 # system may be too busy to destroy all objs in time, use
18621                 # a somewhat small value to not fail autotest
18622                 [ $((old_iused - new_iused)) -gt 400 ] && break
18623                 sleep 1
18624         done
18625
18626         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
18627         [ $((old_iused - new_iused)) -gt 400 ] ||
18628                 error "objs not destroyed after unlink"
18629 }
18630 run_test 311 "disable OSP precreate, and unlink should destroy objs"
18631
18632 zfs_oid_to_objid()
18633 {
18634         local ost=$1
18635         local objid=$2
18636
18637         local vdevdir=$(dirname $(facet_vdevice $ost))
18638         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
18639         local zfs_zapid=$(do_facet $ost $cmd |
18640                           grep -w "/O/0/d$((objid%32))" -C 5 |
18641                           awk '/Object/{getline; print $1}')
18642         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
18643                           awk "/$objid = /"'{printf $3}')
18644
18645         echo $zfs_objid
18646 }
18647
18648 zfs_object_blksz() {
18649         local ost=$1
18650         local objid=$2
18651
18652         local vdevdir=$(dirname $(facet_vdevice $ost))
18653         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
18654         local blksz=$(do_facet $ost $cmd $objid |
18655                       awk '/dblk/{getline; printf $4}')
18656
18657         case "${blksz: -1}" in
18658                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
18659                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
18660                 *) ;;
18661         esac
18662
18663         echo $blksz
18664 }
18665
18666 test_312() { # LU-4856
18667         remote_ost_nodsh && skip "remote OST with nodsh"
18668         [ "$ost1_FSTYPE" = "zfs" ] ||
18669                 skip_env "the test only applies to zfs"
18670
18671         local max_blksz=$(do_facet ost1 \
18672                           $ZFS get -p recordsize $(facet_device ost1) |
18673                           awk '!/VALUE/{print $3}')
18674
18675         # to make life a little bit easier
18676         $LFS mkdir -c 1 -i 0 $DIR/$tdir
18677         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18678
18679         local tf=$DIR/$tdir/$tfile
18680         touch $tf
18681         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18682
18683         # Get ZFS object id
18684         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18685         # block size change by sequential overwrite
18686         local bs
18687
18688         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
18689                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
18690
18691                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
18692                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
18693         done
18694         rm -f $tf
18695
18696         # block size change by sequential append write
18697         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
18698         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18699         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18700         local count
18701
18702         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
18703                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
18704                         oflag=sync conv=notrunc
18705
18706                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
18707                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
18708                         error "blksz error, actual $blksz, " \
18709                                 "expected: 2 * $count * $PAGE_SIZE"
18710         done
18711         rm -f $tf
18712
18713         # random write
18714         touch $tf
18715         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
18716         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
18717
18718         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
18719         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18720         [ $blksz -eq $PAGE_SIZE ] ||
18721                 error "blksz error: $blksz, expected: $PAGE_SIZE"
18722
18723         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
18724         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18725         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
18726
18727         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
18728         blksz=$(zfs_object_blksz ost1 $zfs_objid)
18729         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
18730 }
18731 run_test 312 "make sure ZFS adjusts its block size by write pattern"
18732
18733 test_313() {
18734         remote_ost_nodsh && skip "remote OST with nodsh"
18735
18736         local file=$DIR/$tfile
18737
18738         rm -f $file
18739         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
18740
18741         # define OBD_FAIL_TGT_RCVD_EIO           0x720
18742         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18743         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
18744                 error "write should failed"
18745         do_facet ost1 "$LCTL set_param fail_loc=0"
18746         rm -f $file
18747 }
18748 run_test 313 "io should fail after last_rcvd update fail"
18749
18750 test_314() {
18751         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
18752
18753         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
18754         do_facet ost1 "$LCTL set_param fail_loc=0x720"
18755         rm -f $DIR/$tfile
18756         wait_delete_completed
18757         do_facet ost1 "$LCTL set_param fail_loc=0"
18758 }
18759 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
18760
18761 test_315() { # LU-618
18762         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
18763
18764         local file=$DIR/$tfile
18765         rm -f $file
18766
18767         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
18768                 error "multiop file write failed"
18769         $MULTIOP $file oO_RDONLY:r4063232_c &
18770         PID=$!
18771
18772         sleep 2
18773
18774         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
18775         kill -USR1 $PID
18776
18777         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
18778         rm -f $file
18779 }
18780 run_test 315 "read should be accounted"
18781
18782 test_316() {
18783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18784         large_xattr_enabled || skip_env "ea_inode feature disabled"
18785
18786         rm -rf $DIR/$tdir/d
18787         mkdir -p $DIR/$tdir/d
18788         chown nobody $DIR/$tdir/d
18789         touch $DIR/$tdir/d/file
18790
18791         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
18792 }
18793 run_test 316 "lfs mv"
18794
18795 test_317() {
18796         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
18797                 skip "Need MDS version at least 2.11.53"
18798         local trunc_sz
18799         local grant_blk_size
18800
18801         if [ "$(facet_fstype $facet)" == "zfs" ]; then
18802                 skip "LU-10370: no implementation for ZFS" && return
18803         fi
18804
18805         stack_trap "rm -f $DIR/$tfile" EXIT
18806         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
18807                         awk '/grant_block_size:/ { print $2; exit; }')
18808         #
18809         # Create File of size 5M. Truncate it to below size's and verify
18810         # blocks count.
18811         #
18812         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
18813                 error "Create file : $DIR/$tfile"
18814
18815         for trunc_sz in 2097152 4097 4000 509 0; do
18816                 $TRUNCATE $DIR/$tfile $trunc_sz ||
18817                         error "truncate $tfile to $trunc_sz failed"
18818                 local sz=$(stat --format=%s $DIR/$tfile)
18819                 local blk=$(stat --format=%b $DIR/$tfile)
18820                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
18821                                      grant_blk_size) * 8))
18822
18823                 if [[ $blk -ne $trunc_blk ]]; then
18824                         $(which stat) $DIR/$tfile
18825                         error "Expected Block $trunc_blk got $blk for $tfile"
18826                 fi
18827
18828                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18829                         error "Expected Size $trunc_sz got $sz for $tfile"
18830         done
18831
18832         #
18833         # sparse file test
18834         # Create file with a hole and write actual two blocks. Block count
18835         # must be 16.
18836         #
18837         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
18838                 conv=fsync || error "Create file : $DIR/$tfile"
18839
18840         # Calculate the final truncate size.
18841         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
18842
18843         #
18844         # truncate to size $trunc_sz bytes. Strip the last block
18845         # The block count must drop to 8
18846         #
18847         $TRUNCATE $DIR/$tfile $trunc_sz ||
18848                 error "truncate $tfile to $trunc_sz failed"
18849
18850         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
18851         sz=$(stat --format=%s $DIR/$tfile)
18852         blk=$(stat --format=%b $DIR/$tfile)
18853
18854         if [[ $blk -ne $trunc_bsz ]]; then
18855                 $(which stat) $DIR/$tfile
18856                 error "Expected Block $trunc_bsz got $blk for $tfile"
18857         fi
18858
18859         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
18860                 error "Expected Size $trunc_sz got $sz for $tfile"
18861 }
18862 run_test 317 "Verify blocks get correctly update after truncate"
18863
18864 test_319() {
18865         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
18866
18867         local before=$(date +%s)
18868         local evict
18869         local mdir=$DIR/$tdir
18870         local file=$mdir/xxx
18871
18872         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
18873         touch $file
18874
18875 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
18876         $LCTL set_param fail_val=5 fail_loc=0x8000032c
18877         $LFS mv -m1 $file &
18878
18879         sleep 1
18880         dd if=$file of=/dev/null
18881         wait
18882         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
18883           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
18884
18885         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
18886 }
18887 run_test 319 "lost lease lock on migrate error"
18888
18889 test_fake_rw() {
18890         local read_write=$1
18891         if [ "$read_write" = "write" ]; then
18892                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
18893         elif [ "$read_write" = "read" ]; then
18894                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
18895         else
18896                 error "argument error"
18897         fi
18898
18899         # turn off debug for performance testing
18900         local saved_debug=$($LCTL get_param -n debug)
18901         $LCTL set_param debug=0
18902
18903         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18904
18905         # get ost1 size - lustre-OST0000
18906         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
18907         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
18908         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
18909
18910         if [ "$read_write" = "read" ]; then
18911                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
18912         fi
18913
18914         local start_time=$(date +%s.%N)
18915         $dd_cmd bs=1M count=$blocks oflag=sync ||
18916                 error "real dd $read_write error"
18917         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
18918
18919         if [ "$read_write" = "write" ]; then
18920                 rm -f $DIR/$tfile
18921         fi
18922
18923         # define OBD_FAIL_OST_FAKE_RW           0x238
18924         do_facet ost1 $LCTL set_param fail_loc=0x238
18925
18926         local start_time=$(date +%s.%N)
18927         $dd_cmd bs=1M count=$blocks oflag=sync ||
18928                 error "fake dd $read_write error"
18929         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
18930
18931         if [ "$read_write" = "write" ]; then
18932                 # verify file size
18933                 cancel_lru_locks osc
18934                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
18935                         error "$tfile size not $blocks MB"
18936         fi
18937         do_facet ost1 $LCTL set_param fail_loc=0
18938
18939         echo "fake $read_write $duration_fake vs. normal $read_write" \
18940                 "$duration in seconds"
18941         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
18942                 error_not_in_vm "fake write is slower"
18943
18944         $LCTL set_param -n debug="$saved_debug"
18945         rm -f $DIR/$tfile
18946 }
18947 test_399a() { # LU-7655 for OST fake write
18948         remote_ost_nodsh && skip "remote OST with nodsh"
18949
18950         test_fake_rw write
18951 }
18952 run_test 399a "fake write should not be slower than normal write"
18953
18954 test_399b() { # LU-8726 for OST fake read
18955         remote_ost_nodsh && skip "remote OST with nodsh"
18956         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
18957                 skip_env "ldiskfs only test"
18958         fi
18959
18960         test_fake_rw read
18961 }
18962 run_test 399b "fake read should not be slower than normal read"
18963
18964 test_400a() { # LU-1606, was conf-sanity test_74
18965         if ! which $CC > /dev/null 2>&1; then
18966                 skip_env "$CC is not installed"
18967         fi
18968
18969         local extra_flags=''
18970         local out=$TMP/$tfile
18971         local prefix=/usr/include/lustre
18972         local prog
18973
18974         if ! [[ -d $prefix ]]; then
18975                 # Assume we're running in tree and fixup the include path.
18976                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
18977                 extra_flags+=" -L$LUSTRE/utils/.lib"
18978         fi
18979
18980         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
18981                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
18982                         error "client api broken"
18983         done
18984         rm -f $out
18985 }
18986 run_test 400a "Lustre client api program can compile and link"
18987
18988 test_400b() { # LU-1606, LU-5011
18989         local header
18990         local out=$TMP/$tfile
18991         local prefix=/usr/include/linux/lustre
18992
18993         # We use a hard coded prefix so that this test will not fail
18994         # when run in tree. There are headers in lustre/include/lustre/
18995         # that are not packaged (like lustre_idl.h) and have more
18996         # complicated include dependencies (like config.h and lnet/types.h).
18997         # Since this test about correct packaging we just skip them when
18998         # they don't exist (see below) rather than try to fixup cppflags.
18999
19000         if ! which $CC > /dev/null 2>&1; then
19001                 skip_env "$CC is not installed"
19002         fi
19003
19004         for header in $prefix/*.h; do
19005                 if ! [[ -f "$header" ]]; then
19006                         continue
19007                 fi
19008
19009                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19010                         continue # lustre_ioctl.h is internal header
19011                 fi
19012
19013                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19014                         error "cannot compile '$header'"
19015         done
19016         rm -f $out
19017 }
19018 run_test 400b "packaged headers can be compiled"
19019
19020 test_401a() { #LU-7437
19021         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19022         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19023
19024         #count the number of parameters by "list_param -R"
19025         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19026         #count the number of parameters by listing proc files
19027         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19028         echo "proc_dirs='$proc_dirs'"
19029         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19030         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19031                       sort -u | wc -l)
19032
19033         [ $params -eq $procs ] ||
19034                 error "found $params parameters vs. $procs proc files"
19035
19036         # test the list_param -D option only returns directories
19037         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19038         #count the number of parameters by listing proc directories
19039         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19040                 sort -u | wc -l)
19041
19042         [ $params -eq $procs ] ||
19043                 error "found $params parameters vs. $procs proc files"
19044 }
19045 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19046
19047 test_401b() {
19048         local save=$($LCTL get_param -n jobid_var)
19049         local tmp=testing
19050
19051         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19052                 error "no error returned when setting bad parameters"
19053
19054         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19055         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19056
19057         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19058         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19059         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19060 }
19061 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19062
19063 test_401c() {
19064         local jobid_var_old=$($LCTL get_param -n jobid_var)
19065         local jobid_var_new
19066
19067         $LCTL set_param jobid_var= &&
19068                 error "no error returned for 'set_param a='"
19069
19070         jobid_var_new=$($LCTL get_param -n jobid_var)
19071         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19072                 error "jobid_var was changed by setting without value"
19073
19074         $LCTL set_param jobid_var &&
19075                 error "no error returned for 'set_param a'"
19076
19077         jobid_var_new=$($LCTL get_param -n jobid_var)
19078         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19079                 error "jobid_var was changed by setting without value"
19080 }
19081 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19082
19083 test_401d() {
19084         local jobid_var_old=$($LCTL get_param -n jobid_var)
19085         local jobid_var_new
19086         local new_value="foo=bar"
19087
19088         $LCTL set_param jobid_var=$new_value ||
19089                 error "'set_param a=b' did not accept a value containing '='"
19090
19091         jobid_var_new=$($LCTL get_param -n jobid_var)
19092         [[ "$jobid_var_new" == "$new_value" ]] ||
19093                 error "'set_param a=b' failed on a value containing '='"
19094
19095         # Reset the jobid_var to test the other format
19096         $LCTL set_param jobid_var=$jobid_var_old
19097         jobid_var_new=$($LCTL get_param -n jobid_var)
19098         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19099                 error "failed to reset jobid_var"
19100
19101         $LCTL set_param jobid_var $new_value ||
19102                 error "'set_param a b' did not accept a value containing '='"
19103
19104         jobid_var_new=$($LCTL get_param -n jobid_var)
19105         [[ "$jobid_var_new" == "$new_value" ]] ||
19106                 error "'set_param a b' failed on a value containing '='"
19107
19108         $LCTL set_param jobid_var $jobid_var_old
19109         jobid_var_new=$($LCTL get_param -n jobid_var)
19110         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19111                 error "failed to reset jobid_var"
19112 }
19113 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19114
19115 test_402() {
19116         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19117         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19118                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19119         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19120                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19121                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19122         remote_mds_nodsh && skip "remote MDS with nodsh"
19123
19124         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19125 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19126         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19127         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19128                 echo "Touch failed - OK"
19129 }
19130 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19131
19132 test_403() {
19133         local file1=$DIR/$tfile.1
19134         local file2=$DIR/$tfile.2
19135         local tfile=$TMP/$tfile
19136
19137         rm -f $file1 $file2 $tfile
19138
19139         touch $file1
19140         ln $file1 $file2
19141
19142         # 30 sec OBD_TIMEOUT in ll_getattr()
19143         # right before populating st_nlink
19144         $LCTL set_param fail_loc=0x80001409
19145         stat -c %h $file1 > $tfile &
19146
19147         # create an alias, drop all locks and reclaim the dentry
19148         < $file2
19149         cancel_lru_locks mdc
19150         cancel_lru_locks osc
19151         sysctl -w vm.drop_caches=2
19152
19153         wait
19154
19155         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19156
19157         rm -f $tfile $file1 $file2
19158 }
19159 run_test 403 "i_nlink should not drop to zero due to aliasing"
19160
19161 test_404() { # LU-6601
19162         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19163                 skip "Need server version newer than 2.8.52"
19164         remote_mds_nodsh && skip "remote MDS with nodsh"
19165
19166         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19167                 awk '/osp .*-osc-MDT/ { print $4}')
19168
19169         local osp
19170         for osp in $mosps; do
19171                 echo "Deactivate: " $osp
19172                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19173                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19174                         awk -vp=$osp '$4 == p { print $2 }')
19175                 [ $stat = IN ] || {
19176                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19177                         error "deactivate error"
19178                 }
19179                 echo "Activate: " $osp
19180                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19181                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19182                         awk -vp=$osp '$4 == p { print $2 }')
19183                 [ $stat = UP ] || {
19184                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19185                         error "activate error"
19186                 }
19187         done
19188 }
19189 run_test 404 "validate manual {de}activated works properly for OSPs"
19190
19191 test_405() {
19192         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19193         [ $MDS1_VERSION -lt $(version_code 2.6.92) -o \
19194         [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19195                 skip "Layout swap lock is not supported"
19196         check_swap_layouts_support
19197
19198         test_mkdir $DIR/$tdir
19199         swap_lock_test -d $DIR/$tdir ||
19200                 error "One layout swap locked test failed"
19201 }
19202 run_test 405 "Various layout swap lock tests"
19203
19204 test_406() {
19205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19206         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19207         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19209         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19210                 skip "Need MDS version at least 2.8.50"
19211
19212         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19213         local test_pool=$TESTNAME
19214
19215         if ! combined_mgs_mds ; then
19216                 mount_mgs_client
19217         fi
19218         pool_add $test_pool || error "pool_add failed"
19219         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19220                 error "pool_add_targets failed"
19221
19222         save_layout_restore_at_exit $MOUNT
19223
19224         # parent set default stripe count only, child will stripe from both
19225         # parent and fs default
19226         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19227                 error "setstripe $MOUNT failed"
19228         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19229         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19230         for i in $(seq 10); do
19231                 local f=$DIR/$tdir/$tfile.$i
19232                 touch $f || error "touch failed"
19233                 local count=$($LFS getstripe -c $f)
19234                 [ $count -eq $OSTCOUNT ] ||
19235                         error "$f stripe count $count != $OSTCOUNT"
19236                 local offset=$($LFS getstripe -i $f)
19237                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19238                 local size=$($LFS getstripe -S $f)
19239                 [ $size -eq $((def_stripe_size * 2)) ] ||
19240                         error "$f stripe size $size != $((def_stripe_size * 2))"
19241                 local pool=$($LFS getstripe -p $f)
19242                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19243         done
19244
19245         # change fs default striping, delete parent default striping, now child
19246         # will stripe from new fs default striping only
19247         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19248                 error "change $MOUNT default stripe failed"
19249         $LFS setstripe -c 0 $DIR/$tdir ||
19250                 error "delete $tdir default stripe failed"
19251         for i in $(seq 11 20); do
19252                 local f=$DIR/$tdir/$tfile.$i
19253                 touch $f || error "touch $f failed"
19254                 local count=$($LFS getstripe -c $f)
19255                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19256                 local offset=$($LFS getstripe -i $f)
19257                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19258                 local size=$($LFS getstripe -S $f)
19259                 [ $size -eq $def_stripe_size ] ||
19260                         error "$f stripe size $size != $def_stripe_size"
19261                 local pool=$($LFS getstripe -p $f)
19262                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19263         done
19264
19265         unlinkmany $DIR/$tdir/$tfile. 1 20
19266
19267         local f=$DIR/$tdir/$tfile
19268         pool_remove_all_targets $test_pool $f
19269         pool_remove $test_pool $f
19270
19271         if ! combined_mgs_mds ; then
19272                 umount_mgs_client
19273         fi
19274 }
19275 run_test 406 "DNE support fs default striping"
19276
19277 test_407() {
19278         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19279         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19280                 skip "Need MDS version at least 2.8.55"
19281         remote_mds_nodsh && skip "remote MDS with nodsh"
19282
19283         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19284                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19285         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19286                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19287         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19288
19289         #define OBD_FAIL_DT_TXN_STOP    0x2019
19290         for idx in $(seq $MDSCOUNT); do
19291                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19292         done
19293         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19294         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19295                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19296         true
19297 }
19298 run_test 407 "transaction fail should cause operation fail"
19299
19300 test_408() {
19301         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19302
19303         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19304         lctl set_param fail_loc=0x8000040a
19305         # let ll_prepare_partial_page() fail
19306         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19307
19308         rm -f $DIR/$tfile
19309
19310         # create at least 100 unused inodes so that
19311         # shrink_icache_memory(0) should not return 0
19312         touch $DIR/$tfile-{0..100}
19313         rm -f $DIR/$tfile-{0..100}
19314         sync
19315
19316         echo 2 > /proc/sys/vm/drop_caches
19317 }
19318 run_test 408 "drop_caches should not hang due to page leaks"
19319
19320 test_409()
19321 {
19322         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19323
19324         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19325         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19326         touch $DIR/$tdir/guard || error "(2) Fail to create"
19327
19328         local PREFIX=$(str_repeat 'A' 128)
19329         echo "Create 1K hard links start at $(date)"
19330         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19331                 error "(3) Fail to hard link"
19332
19333         echo "Links count should be right although linkEA overflow"
19334         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19335         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19336         [ $linkcount -eq 1001 ] ||
19337                 error "(5) Unexpected hard links count: $linkcount"
19338
19339         echo "List all links start at $(date)"
19340         ls -l $DIR/$tdir/foo > /dev/null ||
19341                 error "(6) Fail to list $DIR/$tdir/foo"
19342
19343         echo "Unlink hard links start at $(date)"
19344         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19345                 error "(7) Fail to unlink"
19346         echo "Unlink hard links finished at $(date)"
19347 }
19348 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19349
19350 test_410()
19351 {
19352         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19353                 skip "Need client version at least 2.9.59"
19354
19355         # Create a file, and stat it from the kernel
19356         local testfile=$DIR/$tfile
19357         touch $testfile
19358
19359         local run_id=$RANDOM
19360         local my_ino=$(stat --format "%i" $testfile)
19361
19362         # Try to insert the module. This will always fail as the
19363         # module is designed to not be inserted.
19364         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19365             &> /dev/null
19366
19367         # Anything but success is a test failure
19368         dmesg | grep -q \
19369             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19370             error "no inode match"
19371 }
19372 run_test 410 "Test inode number returned from kernel thread"
19373
19374 cleanup_test411_cgroup() {
19375         trap 0
19376         rmdir "$1"
19377 }
19378
19379 test_411() {
19380         local cg_basedir=/sys/fs/cgroup/memory
19381         # LU-9966
19382         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19383                 skip "no setup for cgroup"
19384
19385         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19386                 error "test file creation failed"
19387         cancel_lru_locks osc
19388
19389         # Create a very small memory cgroup to force a slab allocation error
19390         local cgdir=$cg_basedir/osc_slab_alloc
19391         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19392         trap "cleanup_test411_cgroup $cgdir" EXIT
19393         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19394         echo 1M > $cgdir/memory.limit_in_bytes
19395
19396         # Should not LBUG, just be killed by oom-killer
19397         # dd will return 0 even allocation failure in some environment.
19398         # So don't check return value
19399         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19400         cleanup_test411_cgroup $cgdir
19401
19402         return 0
19403 }
19404 run_test 411 "Slab allocation error with cgroup does not LBUG"
19405
19406 test_412() {
19407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19408         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19409                 skip "Need server version at least 2.10.55"
19410         fi
19411
19412         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19413                 error "mkdir failed"
19414         $LFS getdirstripe $DIR/$tdir
19415         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19416         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19417                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19418         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19419         [ $stripe_count -eq 2 ] ||
19420                 error "expect 2 get $stripe_count"
19421 }
19422 run_test 412 "mkdir on specific MDTs"
19423
19424 test_413() {
19425         [ $MDSCOUNT -lt 2 ] &&
19426                 skip "We need at least 2 MDTs for this test"
19427
19428         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19429                 skip "Need server version at least 2.10.55"
19430         fi
19431
19432         mkdir $DIR/$tdir || error "mkdir failed"
19433
19434         # find MDT that is the most full
19435         local max=$($LFS df | grep MDT |
19436                 awk 'BEGIN { a=0 }
19437                         { sub("%", "", $5)
19438                           if (0+$5 >= a)
19439                           {
19440                                 a = $5
19441                                 b = $6
19442                           }
19443                         }
19444                      END { split(b, c, ":")
19445                            sub("]", "", c[2])
19446                            print c[2]
19447                          }')
19448
19449         for i in $(seq $((MDSCOUNT - 1))); do
19450                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19451                         error "mkdir d$i failed"
19452                 $LFS getdirstripe $DIR/$tdir/d$i
19453                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19454                 [ $stripe_index -ne $max ] ||
19455                         error "don't expect $max"
19456         done
19457 }
19458 run_test 413 "mkdir on less full MDTs"
19459
19460 test_414() {
19461 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
19462         $LCTL set_param fail_loc=0x80000521
19463         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
19464         rm -f $DIR/$tfile
19465 }
19466 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
19467
19468 test_415() {
19469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19470         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
19471                 skip "Need server version at least 2.11.52"
19472
19473         # LU-11102
19474         local total
19475         local setattr_pid
19476         local start_time
19477         local end_time
19478         local duration
19479
19480         total=500
19481         # this test may be slow on ZFS
19482         [ "$mds1_FSTYPE" == "zfs" ] && total=100
19483
19484         # though this test is designed for striped directory, let's test normal
19485         # directory too since lock is always saved as CoS lock.
19486         test_mkdir $DIR/$tdir || error "mkdir $tdir"
19487         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
19488
19489         (
19490                 while true; do
19491                         touch $DIR/$tdir
19492                 done
19493         ) &
19494         setattr_pid=$!
19495
19496         start_time=$(date +%s)
19497         for i in $(seq $total); do
19498                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
19499                         > /dev/null
19500         done
19501         end_time=$(date +%s)
19502         duration=$((end_time - start_time))
19503
19504         kill -9 $setattr_pid
19505
19506         echo "rename $total files took $duration sec"
19507         [ $duration -lt 100 ] || error "rename took $duration sec"
19508 }
19509 run_test 415 "lock revoke is not missing"
19510
19511 test_416() {
19512         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
19513                 skip "Need server version at least 2.11.55"
19514
19515         # define OBD_FAIL_OSD_TXN_START    0x19a
19516         do_facet mds1 lctl set_param fail_loc=0x19a
19517
19518         lfs mkdir -c $MDSCOUNT $DIR/$tdir
19519
19520         true
19521 }
19522 run_test 416 "transaction start failure won't cause system hung"
19523
19524 cleanup_417() {
19525         trap 0
19526         do_nodes $(comma_list $(mdts_nodes)) \
19527                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
19528         do_nodes $(comma_list $(mdts_nodes)) \
19529                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
19530         do_nodes $(comma_list $(mdts_nodes)) \
19531                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
19532 }
19533
19534 test_417() {
19535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19536         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
19537                 skip "Need MDS version at least 2.11.56"
19538
19539         trap cleanup_417 RETURN EXIT
19540
19541         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
19542         do_nodes $(comma_list $(mdts_nodes)) \
19543                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
19544         $LFS migrate -m 0 $DIR/$tdir.1 &&
19545                 error "migrate dir $tdir.1 should fail"
19546
19547         do_nodes $(comma_list $(mdts_nodes)) \
19548                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
19549         $LFS mkdir -i 1 $DIR/$tdir.2 &&
19550                 error "create remote dir $tdir.2 should fail"
19551
19552         do_nodes $(comma_list $(mdts_nodes)) \
19553                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
19554         $LFS mkdir -c 2 $DIR/$tdir.3 &&
19555                 error "create striped dir $tdir.3 should fail"
19556         true
19557 }
19558 run_test 417 "disable remote dir, striped dir and dir migration"
19559
19560 # Checks that the outputs of df [-i] and lfs df [-i] match
19561 #
19562 # usage: check_lfs_df <blocks | inodes> <mountpoint>
19563 check_lfs_df() {
19564         local dir=$2
19565         local inodes
19566         local df_out
19567         local lfs_df_out
19568         local count
19569         local passed=false
19570
19571         # blocks or inodes
19572         [ "$1" == "blocks" ] && inodes= || inodes="-i"
19573
19574         for count in {1..100}; do
19575                 cancel_lru_locks
19576                 sync; sleep 0.2
19577
19578                 # read the lines of interest
19579                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
19580                         error "df $inodes $dir | tail -n +2 failed"
19581                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
19582                         error "lfs df $inodes $dir | grep summary: failed"
19583
19584                 # skip first substrings of each output as they are different
19585                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
19586                 # compare the two outputs
19587                 passed=true
19588                 for i in {1..5}; do
19589                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
19590                 done
19591                 $passed && break
19592         done
19593
19594         if ! $passed; then
19595                 df -P $inodes $dir
19596                 echo
19597                 lfs df $inodes $dir
19598                 error "df and lfs df $1 output mismatch: "      \
19599                       "df ${inodes}: ${df_out[*]}, "            \
19600                       "lfs df ${inodes}: ${lfs_df_out[*]}"
19601         fi
19602 }
19603
19604 test_418() {
19605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19606
19607         local dir=$DIR/$tdir
19608         local numfiles=$((RANDOM % 4096 + 2))
19609         local numblocks=$((RANDOM % 256 + 1))
19610
19611         wait_delete_completed
19612         test_mkdir $dir
19613
19614         # check block output
19615         check_lfs_df blocks $dir
19616         # check inode output
19617         check_lfs_df inodes $dir
19618
19619         # create a single file and retest
19620         echo "Creating a single file and testing"
19621         createmany -o $dir/$tfile- 1 &>/dev/null ||
19622                 error "creating 1 file in $dir failed"
19623         check_lfs_df blocks $dir
19624         check_lfs_df inodes $dir
19625
19626         # create a random number of files
19627         echo "Creating $((numfiles - 1)) files and testing"
19628         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
19629                 error "creating $((numfiles - 1)) files in $dir failed"
19630
19631         # write a random number of blocks to the first test file
19632         echo "Writing $numblocks 4K blocks and testing"
19633         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
19634                 count=$numblocks &>/dev/null ||
19635                 error "dd to $dir/${tfile}-0 failed"
19636
19637         # retest
19638         check_lfs_df blocks $dir
19639         check_lfs_df inodes $dir
19640
19641         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
19642                 error "unlinking $numfiles files in $dir failed"
19643 }
19644 run_test 418 "df and lfs df outputs match"
19645
19646 prep_801() {
19647         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19648         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19649                 skip "Need server version at least 2.9.55"
19650
19651         start_full_debug_logging
19652 }
19653
19654 post_801() {
19655         stop_full_debug_logging
19656 }
19657
19658 barrier_stat() {
19659         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19660                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19661                            awk '/The barrier for/ { print $7 }')
19662                 echo $st
19663         else
19664                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
19665                 echo \'$st\'
19666         fi
19667 }
19668
19669 barrier_expired() {
19670         local expired
19671
19672         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
19673                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
19674                           awk '/will be expired/ { print $7 }')
19675         else
19676                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
19677         fi
19678
19679         echo $expired
19680 }
19681
19682 test_801a() {
19683         prep_801
19684
19685         echo "Start barrier_freeze at: $(date)"
19686         #define OBD_FAIL_BARRIER_DELAY          0x2202
19687         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19688         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
19689
19690         sleep 2
19691         local b_status=$(barrier_stat)
19692         echo "Got barrier status at: $(date)"
19693         [ "$b_status" = "'freezing_p1'" ] ||
19694                 error "(1) unexpected barrier status $b_status"
19695
19696         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19697         wait
19698         b_status=$(barrier_stat)
19699         [ "$b_status" = "'frozen'" ] ||
19700                 error "(2) unexpected barrier status $b_status"
19701
19702         local expired=$(barrier_expired)
19703         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
19704         sleep $((expired + 3))
19705
19706         b_status=$(barrier_stat)
19707         [ "$b_status" = "'expired'" ] ||
19708                 error "(3) unexpected barrier status $b_status"
19709
19710         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
19711                 error "(4) fail to freeze barrier"
19712
19713         b_status=$(barrier_stat)
19714         [ "$b_status" = "'frozen'" ] ||
19715                 error "(5) unexpected barrier status $b_status"
19716
19717         echo "Start barrier_thaw at: $(date)"
19718         #define OBD_FAIL_BARRIER_DELAY          0x2202
19719         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
19720         do_facet mgs $LCTL barrier_thaw $FSNAME &
19721
19722         sleep 2
19723         b_status=$(barrier_stat)
19724         echo "Got barrier status at: $(date)"
19725         [ "$b_status" = "'thawing'" ] ||
19726                 error "(6) unexpected barrier status $b_status"
19727
19728         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
19729         wait
19730         b_status=$(barrier_stat)
19731         [ "$b_status" = "'thawed'" ] ||
19732                 error "(7) unexpected barrier status $b_status"
19733
19734         #define OBD_FAIL_BARRIER_FAILURE        0x2203
19735         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
19736         do_facet mgs $LCTL barrier_freeze $FSNAME
19737
19738         b_status=$(barrier_stat)
19739         [ "$b_status" = "'failed'" ] ||
19740                 error "(8) unexpected barrier status $b_status"
19741
19742         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19743         do_facet mgs $LCTL barrier_thaw $FSNAME
19744
19745         post_801
19746 }
19747 run_test 801a "write barrier user interfaces and stat machine"
19748
19749 test_801b() {
19750         prep_801
19751
19752         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19753         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
19754         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
19755         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
19756         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
19757
19758         cancel_lru_locks mdc
19759
19760         # 180 seconds should be long enough
19761         do_facet mgs $LCTL barrier_freeze $FSNAME 180
19762
19763         local b_status=$(barrier_stat)
19764         [ "$b_status" = "'frozen'" ] ||
19765                 error "(6) unexpected barrier status $b_status"
19766
19767         mkdir $DIR/$tdir/d0/d10 &
19768         mkdir_pid=$!
19769
19770         touch $DIR/$tdir/d1/f13 &
19771         touch_pid=$!
19772
19773         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
19774         ln_pid=$!
19775
19776         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
19777         mv_pid=$!
19778
19779         rm -f $DIR/$tdir/d4/f12 &
19780         rm_pid=$!
19781
19782         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
19783
19784         # To guarantee taht the 'stat' is not blocked
19785         b_status=$(barrier_stat)
19786         [ "$b_status" = "'frozen'" ] ||
19787                 error "(8) unexpected barrier status $b_status"
19788
19789         # let above commands to run at background
19790         sleep 5
19791
19792         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
19793         ps -p $touch_pid || error "(10) touch should be blocked"
19794         ps -p $ln_pid || error "(11) link should be blocked"
19795         ps -p $mv_pid || error "(12) rename should be blocked"
19796         ps -p $rm_pid || error "(13) unlink should be blocked"
19797
19798         b_status=$(barrier_stat)
19799         [ "$b_status" = "'frozen'" ] ||
19800                 error "(14) unexpected barrier status $b_status"
19801
19802         do_facet mgs $LCTL barrier_thaw $FSNAME
19803         b_status=$(barrier_stat)
19804         [ "$b_status" = "'thawed'" ] ||
19805                 error "(15) unexpected barrier status $b_status"
19806
19807         wait $mkdir_pid || error "(16) mkdir should succeed"
19808         wait $touch_pid || error "(17) touch should succeed"
19809         wait $ln_pid || error "(18) link should succeed"
19810         wait $mv_pid || error "(19) rename should succeed"
19811         wait $rm_pid || error "(20) unlink should succeed"
19812
19813         post_801
19814 }
19815 run_test 801b "modification will be blocked by write barrier"
19816
19817 test_801c() {
19818         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19819
19820         prep_801
19821
19822         stop mds2 || error "(1) Fail to stop mds2"
19823
19824         do_facet mgs $LCTL barrier_freeze $FSNAME 30
19825
19826         local b_status=$(barrier_stat)
19827         [ "$b_status" = "'expired'" -o "$b_status" = "'failed'" ] || {
19828                 do_facet mgs $LCTL barrier_thaw $FSNAME
19829                 error "(2) unexpected barrier status $b_status"
19830         }
19831
19832         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19833                 error "(3) Fail to rescan barrier bitmap"
19834
19835         do_facet mgs $LCTL barrier_freeze $FSNAME 10
19836
19837         b_status=$(barrier_stat)
19838         [ "$b_status" = "'frozen'" ] ||
19839                 error "(4) unexpected barrier status $b_status"
19840
19841         do_facet mgs $LCTL barrier_thaw $FSNAME
19842         b_status=$(barrier_stat)
19843         [ "$b_status" = "'thawed'" ] ||
19844                 error "(5) unexpected barrier status $b_status"
19845
19846         local devname=$(mdsdevname 2)
19847
19848         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
19849
19850         do_facet mgs $LCTL barrier_rescan $FSNAME ||
19851                 error "(7) Fail to rescan barrier bitmap"
19852
19853         post_801
19854 }
19855 run_test 801c "rescan barrier bitmap"
19856
19857 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
19858 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
19859 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
19860
19861 cleanup_802a() {
19862         trap 0
19863
19864         stopall
19865         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
19866         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
19867         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
19868         setupall
19869 }
19870
19871 test_802a() {
19872
19873         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
19874         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
19875                 skip "Need server version at least 2.9.55"
19876
19877         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
19878
19879         mkdir $DIR/$tdir || error "(1) fail to mkdir"
19880
19881         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19882                 error "(2) Fail to copy"
19883
19884         trap cleanup_802a EXIT
19885
19886         # sync by force before remount as readonly
19887         sync; sync_all_data; sleep 3; sync_all_data
19888
19889         stopall
19890
19891         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
19892         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
19893         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
19894
19895         echo "Mount the server as read only"
19896         setupall server_only || error "(3) Fail to start servers"
19897
19898         echo "Mount client without ro should fail"
19899         mount_client $MOUNT &&
19900                 error "(4) Mount client without 'ro' should fail"
19901
19902         echo "Mount client with ro should succeed"
19903         mount_client $MOUNT ro ||
19904                 error "(5) Mount client with 'ro' should succeed"
19905
19906         echo "Modify should be refused"
19907         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19908
19909         echo "Read should be allowed"
19910         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19911                 error "(7) Read should succeed under ro mode"
19912
19913         cleanup_802a
19914 }
19915 run_test 802a "simulate readonly device"
19916
19917 test_802b() {
19918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19919         remote_mds_nodsh && skip "remote MDS with nodsh"
19920
19921         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
19922                 skip "readonly option not available"
19923
19924         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
19925
19926         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
19927                 error "(2) Fail to copy"
19928
19929         # write back all cached data before setting MDT to readonly
19930         cancel_lru_locks
19931         sync_all_data
19932
19933         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
19934         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
19935
19936         echo "Modify should be refused"
19937         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
19938
19939         echo "Read should be allowed"
19940         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
19941                 error "(7) Read should succeed under ro mode"
19942
19943         # disable readonly
19944         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
19945 }
19946 run_test 802b "be able to set MDTs to readonly"
19947
19948 test_803() {
19949         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19950         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
19951                 skip "MDS needs to be newer than 2.10.54"
19952
19953         mkdir -p $DIR/$tdir
19954         # Create some objects on all MDTs to trigger related logs objects
19955         for idx in $(seq $MDSCOUNT); do
19956                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
19957                         $DIR/$tdir/dir${idx} ||
19958                         error "Fail to create $DIR/$tdir/dir${idx}"
19959         done
19960
19961         sync; sleep 3
19962         wait_delete_completed # ensure old test cleanups are finished
19963         echo "before create:"
19964         $LFS df -i $MOUNT
19965         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19966
19967         for i in {1..10}; do
19968                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
19969                         error "Fail to create $DIR/$tdir/foo$i"
19970         done
19971
19972         sync; sleep 3
19973         echo "after create:"
19974         $LFS df -i $MOUNT
19975         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19976
19977         # allow for an llog to be cleaned up during the test
19978         [ $after_used -ge $((before_used + 10 - 1)) ] ||
19979                 error "before ($before_used) + 10 > after ($after_used)"
19980
19981         for i in {1..10}; do
19982                 rm -rf $DIR/$tdir/foo$i ||
19983                         error "Fail to remove $DIR/$tdir/foo$i"
19984         done
19985
19986         sleep 3 # avoid MDT return cached statfs
19987         wait_delete_completed
19988         echo "after unlink:"
19989         $LFS df -i $MOUNT
19990         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
19991
19992         # allow for an llog to be created during the test
19993         [ $after_used -le $((before_used + 1)) ] ||
19994                 error "after ($after_used) > before ($before_used) + 1"
19995 }
19996 run_test 803 "verify agent object for remote object"
19997
19998 test_804() {
19999         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20000         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20001                 skip "MDS needs to be newer than 2.10.54"
20002         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20003
20004         mkdir -p $DIR/$tdir
20005         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20006                 error "Fail to create $DIR/$tdir/dir0"
20007
20008         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20009         local dev=$(mdsdevname 2)
20010
20011         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20012                 grep ${fid} || error "NOT found agent entry for dir0"
20013
20014         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20015                 error "Fail to create $DIR/$tdir/dir1"
20016
20017         touch $DIR/$tdir/dir1/foo0 ||
20018                 error "Fail to create $DIR/$tdir/dir1/foo0"
20019         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20020         local rc=0
20021
20022         for idx in $(seq $MDSCOUNT); do
20023                 dev=$(mdsdevname $idx)
20024                 do_facet mds${idx} \
20025                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20026                         grep ${fid} && rc=$idx
20027         done
20028
20029         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20030                 error "Fail to rename foo0 to foo1"
20031         if [ $rc -eq 0 ]; then
20032                 for idx in $(seq $MDSCOUNT); do
20033                         dev=$(mdsdevname $idx)
20034                         do_facet mds${idx} \
20035                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20036                         grep ${fid} && rc=$idx
20037                 done
20038         fi
20039
20040         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20041                 error "Fail to rename foo1 to foo2"
20042         if [ $rc -eq 0 ]; then
20043                 for idx in $(seq $MDSCOUNT); do
20044                         dev=$(mdsdevname $idx)
20045                         do_facet mds${idx} \
20046                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20047                         grep ${fid} && rc=$idx
20048                 done
20049         fi
20050
20051         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20052
20053         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20054                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20055         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20056                 error "Fail to rename foo2 to foo0"
20057         unlink $DIR/$tdir/dir1/foo0 ||
20058                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20059         rm -rf $DIR/$tdir/dir0 ||
20060                 error "Fail to rm $DIR/$tdir/dir0"
20061
20062         for idx in $(seq $MDSCOUNT); do
20063                 dev=$(mdsdevname $idx)
20064                 rc=0
20065
20066                 stop mds${idx}
20067                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20068                         rc=$?
20069                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20070                         error "mount mds$idx failed"
20071                 df $MOUNT > /dev/null 2>&1
20072
20073                 # e2fsck should not return error
20074                 [ $rc -eq 0 ] ||
20075                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20076         done
20077 }
20078 run_test 804 "verify agent entry for remote entry"
20079
20080 cleanup_805() {
20081         do_facet $SINGLEMDS zfs set quota=$old $fsset
20082         unlinkmany $DIR/$tdir/f- 1000000
20083         trap 0
20084 }
20085
20086 test_805() {
20087         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20088         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20089         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20090                 skip "netfree not implemented before 0.7"
20091         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20092                 skip "Need MDS version at least 2.10.57"
20093
20094         local fsset
20095         local freekb
20096         local usedkb
20097         local old
20098         local quota
20099         local pref="osd-zfs.lustre-MDT0000."
20100
20101         # limit available space on MDS dataset to meet nospace issue
20102         # quickly. then ZFS 0.7.2 can use reserved space if asked
20103         # properly (using netfree flag in osd_declare_destroy()
20104         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20105         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20106                 gawk '{print $3}')
20107         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20108         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20109         let "usedkb=usedkb-freekb"
20110         let "freekb=freekb/2"
20111         if let "freekb > 5000"; then
20112                 let "freekb=5000"
20113         fi
20114         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20115         trap cleanup_805 EXIT
20116         mkdir $DIR/$tdir
20117         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20118         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20119         rm -rf $DIR/$tdir || error "not able to remove"
20120         do_facet $SINGLEMDS zfs set quota=$old $fsset
20121         trap 0
20122 }
20123 run_test 805 "ZFS can remove from full fs"
20124
20125 # Size-on-MDS test
20126 check_lsom_data()
20127 {
20128         local file=$1
20129         local size=$($LFS getsom -s $file)
20130         local expect=$(stat -c %s $file)
20131
20132         [[ $size == $expect ]] ||
20133                 error "$file expected size: $expect, got: $size"
20134
20135         local blocks=$($LFS getsom -b $file)
20136         expect=$(stat -c %b $file)
20137         [[ $blocks == $expect ]] ||
20138                 error "$file expected blocks: $expect, got: $blocks"
20139 }
20140
20141 check_lsom_size()
20142 {
20143         local size=$($LFS getsom -s $1)
20144         local expect=$2
20145
20146         [[ $size == $expect ]] ||
20147                 error "$file expected size: $expect, got: $size"
20148 }
20149
20150 test_806() {
20151         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20152                 skip "Need MDS version at least 2.11.52"
20153
20154         local bs=1048576
20155
20156         touch $DIR/$tfile || error "touch $tfile failed"
20157
20158         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20159         save_lustre_params client "llite.*.xattr_cache" > $save
20160         lctl set_param llite.*.xattr_cache=0
20161         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20162
20163         # single-threaded write
20164         echo "Test SOM for single-threaded write"
20165         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20166                 error "write $tfile failed"
20167         check_lsom_size $DIR/$tfile $bs
20168
20169         local num=32
20170         local size=$(($num * $bs))
20171         local offset=0
20172         local i
20173
20174         echo "Test SOM for single client multi-threaded($num) write"
20175         $TRUNCATE $DIR/$tfile 0
20176         for ((i = 0; i < $num; i++)); do
20177                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20178                 local pids[$i]=$!
20179                 offset=$((offset + $bs))
20180         done
20181         for (( i=0; i < $num; i++ )); do
20182                 wait ${pids[$i]}
20183         done
20184         check_lsom_size $DIR/$tfile $size
20185
20186         $TRUNCATE $DIR/$tfile 0
20187         for ((i = 0; i < $num; i++)); do
20188                 offset=$((offset - $bs))
20189                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20190                 local pids[$i]=$!
20191         done
20192         for (( i=0; i < $num; i++ )); do
20193                 wait ${pids[$i]}
20194         done
20195         check_lsom_size $DIR/$tfile $size
20196
20197         # multi-client wirtes
20198         num=$(get_node_count ${CLIENTS//,/ })
20199         size=$(($num * $bs))
20200         offset=0
20201         i=0
20202
20203         echo "Test SOM for multi-client ($num) writes"
20204         $TRUNCATE $DIR/$tfile 0
20205         for client in ${CLIENTS//,/ }; do
20206                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20207                 local pids[$i]=$!
20208                 i=$((i + 1))
20209                 offset=$((offset + $bs))
20210         done
20211         for (( i=0; i < $num; i++ )); do
20212                 wait ${pids[$i]}
20213         done
20214         check_lsom_size $DIR/$tfile $offset
20215
20216         i=0
20217         $TRUNCATE $DIR/$tfile 0
20218         for client in ${CLIENTS//,/ }; do
20219                 offset=$((offset - $bs))
20220                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20221                 local pids[$i]=$!
20222                 i=$((i + 1))
20223         done
20224         for (( i=0; i < $num; i++ )); do
20225                 wait ${pids[$i]}
20226         done
20227         check_lsom_size $DIR/$tfile $size
20228
20229         # verify truncate
20230         echo "Test SOM for truncate"
20231         $TRUNCATE $DIR/$tfile 1048576
20232         check_lsom_size $DIR/$tfile 1048576
20233         $TRUNCATE $DIR/$tfile 1234
20234         check_lsom_size $DIR/$tfile 1234
20235
20236         # verify SOM blocks count
20237         echo "Verify SOM block count"
20238         $TRUNCATE $DIR/$tfile 0
20239         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20240                 error "failed to write file $tfile"
20241         check_lsom_data $DIR/$tfile
20242 }
20243 run_test 806 "Verify Lazy Size on MDS"
20244
20245 test_807() {
20246         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20247         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20248                 skip "Need MDS version at least 2.11.52"
20249
20250         # Registration step
20251         changelog_register || error "changelog_register failed"
20252         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20253         changelog_users $SINGLEMDS | grep -q $cl_user ||
20254                 error "User $cl_user not found in changelog_users"
20255
20256         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20257         save_lustre_params client "llite.*.xattr_cache" > $save
20258         lctl set_param llite.*.xattr_cache=0
20259         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20260
20261         rm -rf $DIR/$tdir || error "rm $tdir failed"
20262         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20263         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20264         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20265         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20266                 error "truncate $tdir/trunc failed"
20267
20268         local bs=1048576
20269         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20270                 error "write $tfile failed"
20271
20272         # multi-client wirtes
20273         local num=$(get_node_count ${CLIENTS//,/ })
20274         local offset=0
20275         local i=0
20276
20277         echo "Test SOM for multi-client ($num) writes"
20278         touch $DIR/$tfile || error "touch $tfile failed"
20279         $TRUNCATE $DIR/$tfile 0
20280         for client in ${CLIENTS//,/ }; do
20281                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20282                 local pids[$i]=$!
20283                 i=$((i + 1))
20284                 offset=$((offset + $bs))
20285         done
20286         for (( i=0; i < $num; i++ )); do
20287                 wait ${pids[$i]}
20288         done
20289
20290         sleep 5
20291         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20292         check_lsom_data $DIR/$tdir/trunc
20293         check_lsom_data $DIR/$tdir/single_dd
20294         check_lsom_data $DIR/$tfile
20295
20296         rm -rf $DIR/$tdir
20297         # Deregistration step
20298         changelog_deregister || error "changelog_deregister failed"
20299 }
20300 run_test 807 "verify LSOM syncing tool"
20301
20302 check_som_nologged()
20303 {
20304         local lines=$($LFS changelog $FSNAME-MDT0000 |
20305                 grep 'x=trusted.som' | wc -l)
20306         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20307 }
20308
20309 test_808() {
20310         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20311                 skip "Need MDS version at least 2.11.55"
20312
20313         # Registration step
20314         changelog_register || error "changelog_register failed"
20315
20316         touch $DIR/$tfile || error "touch $tfile failed"
20317         check_som_nologged
20318
20319         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
20320                 error "write $tfile failed"
20321         check_som_nologged
20322
20323         $TRUNCATE $DIR/$tfile 1234
20324         check_som_nologged
20325
20326         $TRUNCATE $DIR/$tfile 1048576
20327         check_som_nologged
20328
20329         # Deregistration step
20330         changelog_deregister || error "changelog_deregister failed"
20331 }
20332 run_test 808 "Check trusted.som xattr not logged in Changelogs"
20333
20334 check_som_nodata()
20335 {
20336         $LFS getsom $1
20337         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
20338 }
20339
20340 test_809() {
20341         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20342                 skip "Need MDS version at least 2.11.56"
20343
20344         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
20345                 error "failed to create DoM-only file $DIR/$tfile"
20346         touch $DIR/$tfile || error "touch $tfile failed"
20347         check_som_nodata $DIR/$tfile
20348
20349         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
20350                 error "write $tfile failed"
20351         check_som_nodata $DIR/$tfile
20352
20353         $TRUNCATE $DIR/$tfile 1234
20354         check_som_nodata $DIR/$tfile
20355
20356         $TRUNCATE $DIR/$tfile 4097
20357         check_som_nodata $DIR/$file
20358 }
20359 run_test 809 "Verify no SOM xattr store for DoM-only files"
20360
20361 test_810() {
20362         local ORIG
20363         local CSUM
20364
20365         # t10 seem to dislike partial pages
20366         lctl set_param osc.*.checksum_type=adler
20367         lctl set_param fail_loc=0x411
20368         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
20369         ORIG=$(md5sum $DIR/$tfile)
20370         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
20371         CSUM=$(md5sum $DIR/$tfile)
20372         set_checksum_type adler
20373         if [ "$ORIG" != "$CSUM" ]; then
20374                 error "$ORIG != $CSUM"
20375         fi
20376 }
20377 run_test 810 "partial page writes on ZFS (LU-11663)"
20378
20379 test_811() {
20380         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
20381                 skip "Need MDS version at least 2.11.56"
20382
20383         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
20384         do_facet mds1 $LCTL set_param fail_loc=0x165
20385         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
20386
20387         stop mds1
20388         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20389
20390         sleep 5
20391         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
20392                 error "MDD orphan cleanup thread not quit"
20393 }
20394 run_test 811 "orphan name stub can be cleaned up in startup"
20395
20396 test_812() {
20397         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
20398                 skip "OST < 2.12.51 doesn't support this fail_loc"
20399
20400         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20401         # ensure ost1 is connected
20402         stat $DIR/$tfile >/dev/null || error "can't stat"
20403         wait_osc_import_state client ost1 FULL
20404         # no locks, no reqs to let the connection idle
20405         cancel_lru_locks osc
20406
20407         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
20408 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
20409         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
20410         wait_osc_import_state client ost1 CONNECTING
20411         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
20412
20413         stat $DIR/$tfile >/dev/null || error "can't stat file"
20414 }
20415 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
20416
20417 test_813() {
20418         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
20419         [ -z "$file_heat_sav" ] && skip "no file heat support"
20420
20421         local readsample
20422         local writesample
20423         local readbyte
20424         local writebyte
20425         local readsample1
20426         local writesample1
20427         local readbyte1
20428         local writebyte1
20429
20430         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
20431         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
20432
20433         $LCTL set_param -n llite.*.file_heat=1
20434         echo "Turn on file heat"
20435         echo "Period second: $period_second, Decay percentage: $decay_pct"
20436
20437         echo "QQQQ" > $DIR/$tfile
20438         echo "QQQQ" > $DIR/$tfile
20439         echo "QQQQ" > $DIR/$tfile
20440         cat $DIR/$tfile > /dev/null
20441         cat $DIR/$tfile > /dev/null
20442         cat $DIR/$tfile > /dev/null
20443         cat $DIR/$tfile > /dev/null
20444
20445         local out=$($LFS heat_get $DIR/$tfile)
20446
20447         $LFS heat_get $DIR/$tfile
20448         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20449         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20450         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20451         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20452
20453         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
20454         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
20455         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
20456         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
20457
20458         sleep $((period_second + 3))
20459         echo "Sleep $((period_second + 3)) seconds..."
20460         # The recursion formula to calculate the heat of the file f is as
20461         # follow:
20462         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
20463         # Where Hi is the heat value in the period between time points i*I and
20464         # (i+1)*I; Ci is the access count in the period; the symbol P refers
20465         # to the weight of Ci.
20466         out=$($LFS heat_get $DIR/$tfile)
20467         $LFS heat_get $DIR/$tfile
20468         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20469         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20470         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20471         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20472
20473         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
20474                 error "read sample ($readsample) is wrong"
20475         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
20476                 error "write sample ($writesample) is wrong"
20477         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
20478                 error "read bytes ($readbyte) is wrong"
20479         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
20480                 error "write bytes ($writebyte) is wrong"
20481
20482         echo "QQQQ" > $DIR/$tfile
20483         echo "QQQQ" > $DIR/$tfile
20484         echo "QQQQ" > $DIR/$tfile
20485         cat $DIR/$tfile > /dev/null
20486         cat $DIR/$tfile > /dev/null
20487         cat $DIR/$tfile > /dev/null
20488         cat $DIR/$tfile > /dev/null
20489
20490         sleep $((period_second + 3))
20491         echo "Sleep $((period_second + 3)) seconds..."
20492
20493         out=$($LFS heat_get $DIR/$tfile)
20494         $LFS heat_get $DIR/$tfile
20495         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20496         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20497         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20498         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20499
20500         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
20501                 4 * $decay_pct) / 100") -eq 1 ] ||
20502                 error "read sample ($readsample1) is wrong"
20503         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
20504                 3 * $decay_pct) / 100") -eq 1 ] ||
20505                 error "write sample ($writesample1) is wrong"
20506         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
20507                 20 * $decay_pct) / 100") -eq 1 ] ||
20508                 error "read bytes ($readbyte1) is wrong"
20509         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
20510                 15 * $decay_pct) / 100") -eq 1 ] ||
20511                 error "write bytes ($writebyte1) is wrong"
20512
20513         echo "Turn off file heat for the file $DIR/$tfile"
20514         $LFS heat_set -o $DIR/$tfile
20515
20516         echo "QQQQ" > $DIR/$tfile
20517         echo "QQQQ" > $DIR/$tfile
20518         echo "QQQQ" > $DIR/$tfile
20519         cat $DIR/$tfile > /dev/null
20520         cat $DIR/$tfile > /dev/null
20521         cat $DIR/$tfile > /dev/null
20522         cat $DIR/$tfile > /dev/null
20523
20524         out=$($LFS heat_get $DIR/$tfile)
20525         $LFS heat_get $DIR/$tfile
20526         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20527         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20528         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20529         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20530
20531         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20532         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20533         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20534         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20535
20536         echo "Trun on file heat for the file $DIR/$tfile"
20537         $LFS heat_set -O $DIR/$tfile
20538
20539         echo "QQQQ" > $DIR/$tfile
20540         echo "QQQQ" > $DIR/$tfile
20541         echo "QQQQ" > $DIR/$tfile
20542         cat $DIR/$tfile > /dev/null
20543         cat $DIR/$tfile > /dev/null
20544         cat $DIR/$tfile > /dev/null
20545         cat $DIR/$tfile > /dev/null
20546
20547         out=$($LFS heat_get $DIR/$tfile)
20548         $LFS heat_get $DIR/$tfile
20549         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20550         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20551         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20552         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20553
20554         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
20555         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
20556         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
20557         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
20558
20559         $LFS heat_set -c $DIR/$tfile
20560         $LCTL set_param -n llite.*.file_heat=0
20561         echo "Turn off file heat support for the Lustre filesystem"
20562
20563         echo "QQQQ" > $DIR/$tfile
20564         echo "QQQQ" > $DIR/$tfile
20565         echo "QQQQ" > $DIR/$tfile
20566         cat $DIR/$tfile > /dev/null
20567         cat $DIR/$tfile > /dev/null
20568         cat $DIR/$tfile > /dev/null
20569         cat $DIR/$tfile > /dev/null
20570
20571         out=$($LFS heat_get $DIR/$tfile)
20572         $LFS heat_get $DIR/$tfile
20573         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
20574         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
20575         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
20576         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
20577
20578         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
20579         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
20580         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
20581         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
20582
20583         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
20584         rm -f $DIR/$tfile
20585 }
20586 run_test 813 "File heat verfication"
20587
20588 #
20589 # tests that do cleanup/setup should be run at the end
20590 #
20591
20592 test_900() {
20593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20594         local ls
20595
20596         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
20597         $LCTL set_param fail_loc=0x903
20598
20599         cancel_lru_locks MGC
20600
20601         FAIL_ON_ERROR=true cleanup
20602         FAIL_ON_ERROR=true setup
20603 }
20604 run_test 900 "umount should not race with any mgc requeue thread"
20605
20606 complete $SECONDS
20607 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
20608 check_and_cleanup_lustre
20609 if [ "$I_MOUNTED" != "yes" ]; then
20610         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
20611 fi
20612 exit_status